Created
May 31, 2021 09:50
-
-
Save oligazar/b84003ef9ce7cb7d8237a20433d74aa1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class IsolateHolderService : MethodChannel.MethodCallHandler, LocationUpdateListener, Service() { | |
// ... other code ... | |
companion object { | |
private var notificationChannelName = "Flutter Locator Plugin" | |
private var notificationTitle = "Start Location Tracking" | |
private var notificationMsg = "Track location in background" | |
private var notificationBigMsg = "Background location is on to keep the app up-tp-date with your location. This is required for main features to work properly when the app is not running." | |
private var icon = 0 | |
private var notificationIconColor = 0 | |
fun getNotification(context: Context): Notification { | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | |
// Notification channel is available in Android O and up | |
val channel = NotificationChannel(Keys.CHANNEL_ID, | |
notificationChannelName, | |
NotificationManager.IMPORTANCE_LOW) | |
(context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager) | |
.createNotificationChannel(channel) | |
} | |
val intent = Intent(context, getMainActivityClass(context)) | |
intent.action = Keys.NOTIFICATION_ACTION | |
val pendingIntent: PendingIntent = PendingIntent.getActivity(context, | |
1, intent, | |
PendingIntent.FLAG_UPDATE_CURRENT) | |
return NotificationCompat.Builder(context, Keys.CHANNEL_ID) | |
.setContentTitle(notificationTitle) | |
.setContentText(notificationMsg) | |
.setStyle(NotificationCompat.BigTextStyle() | |
.bigText(notificationBigMsg)) | |
.setSmallIcon(icon) | |
.setColor(notificationIconColor) | |
.setPriority(NotificationCompat.PRIORITY_HIGH) | |
.setContentIntent(pendingIntent) | |
.setOnlyAlertOnce(true) // so when data is updated don't make sound and alert in android 8.0+ | |
.setOngoing(true) | |
.build() | |
} | |
private fun getMainActivityClass(context: Context): Class<*>? { | |
val packageName = context.packageName | |
val launchIntent = context.packageManager.getLaunchIntentForPackage(packageName) | |
val className = launchIntent?.component?.className ?: return null | |
return try { | |
Class.forName(className) | |
} catch (e: ClassNotFoundException) { | |
e.printStackTrace() | |
null | |
} | |
} | |
} | |
class LocalBinder : Binder() { | |
val service: IsolateHolderService | |
get() = this@IsolateHolderService | |
} | |
// Create the instance on the service. | |
private val binder = LocalBinder() | |
override fun onBind(intent: Intent?): IBinder? { | |
context?.d("onBind") | |
return binder | |
} | |
} | |
class BackgroundLocatorPlugin | |
: MethodCallHandler, FlutterPlugin, PluginRegistry.NewIntentListener, ActivityAware { | |
// ... other code ... | |
companion object { | |
private var context: Context? = null | |
private fun bindService(context: Context, intent: Intent) { | |
try { | |
context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE) | |
} catch (ignored: RuntimeException) { | |
// This is probably a broadcast receiver context even though we are calling getApplicationContext(). | |
// Just call startForegroundService instead since we cannot bind a service to a | |
// broadcast receiver context. The service also have to call startForeground in | |
// this case. | |
// context.startForegroundService(getServiceIntent(context)) | |
ContextCompat.startForegroundService(context, intent) | |
} | |
context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE) | |
} | |
private var serviceConnection: ServiceConnection = object : ServiceConnection { | |
override fun onServiceConnected(name: ComponentName, service: IBinder) { | |
// The binder of the service that returns the instance that is created. | |
val binder: IsolateHolderService.LocalBinder = service as IsolateHolderService.LocalBinder | |
// The getter method to acquire the service. | |
val myService: IsolateHolderService = binder.service | |
// getServiceIntent(context) returns the relative service intent | |
// context!!.startForegroundService(getServiceIntent(context)) | |
context?.let { | |
ContextCompat.startForegroundService(it, getServiceIntent(context)) // getServiceIntent has to be implemented | |
// This is the key: Without waiting Android Framework to call this method | |
// inside Service.onCreate(), immediately call here to post the notification. | |
myService.startForeground(IsolateHolderService.notificationId, IsolateHolderService.getNotification(it)) | |
} | |
// Release the connection to prevent leaks. | |
context!!.unbindService(this) | |
} | |
override fun onServiceDisconnected(name: ComponentName?) { | |
TODO("Not yet implemented") | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment