Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#34 #41 Restart locator service after reboot; #47

Merged
merged 3 commits into from
Apr 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.1.3+1
Add possibility to restart locator service after reboot;
Fix triggering android notification callback with wrong notification;

## 1.1.2+2
Fix optional android notification callback.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import rekab.app.background_locator.Keys.Companion.METHOD_PLUGIN_INITIALIZE_SERV
import rekab.app.background_locator.Keys.Companion.METHOD_PLUGIN_IS_REGISTER_LOCATION_UPDATE
import rekab.app.background_locator.Keys.Companion.METHOD_PLUGIN_REGISTER_LOCATION_UPDATE
import rekab.app.background_locator.Keys.Companion.METHOD_PLUGIN_UN_REGISTER_LOCATION_UPDATE
import rekab.app.background_locator.Keys.Companion.NOTIFICATION_ACTION
import rekab.app.background_locator.Keys.Companion.NOTIFICATION_CALLBACK_HANDLE_KEY
import rekab.app.background_locator.Keys.Companion.SHARED_PREFERENCES_KEY

Expand Down Expand Up @@ -200,17 +201,39 @@ class BackgroundLocatorPlugin()
return context.getSharedPreferences(SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE)
.getLong(key, 0)
}

@JvmStatic
fun registerAfterBoot(context: Context) {
val settings = PreferencesManager.getSettings(context)

val plugin = BackgroundLocatorPlugin()
plugin.context = context
plugin.locatorClient = LocationServices.getFusedLocationProviderClient(context)

initializeService(context, settings)
registerLocator(context,
plugin.locatorClient,
settings, null)
}
}

override fun onMethodCall(call: MethodCall, result: Result) {
when (call.method) {
METHOD_PLUGIN_INITIALIZE_SERVICE -> {
val args: Map<Any, Any> = call.arguments()

// save callback dispatcher to use it when device reboots
PreferencesManager.saveCallbackDispatcher(context!!, args)

initializeService(context!!, args)
result.success(true)
}
METHOD_PLUGIN_REGISTER_LOCATION_UPDATE -> {
val args: Map<Any, Any> = call.arguments()

// save setting to use it when device reboots
PreferencesManager.saveSettings(context!!, args)

registerLocator(context!!,
locatorClient,
args,
Expand Down Expand Up @@ -241,6 +264,11 @@ class BackgroundLocatorPlugin()
}

override fun onNewIntent(intent: Intent?): Boolean {
if(intent?.action != NOTIFICATION_ACTION) {
// this is not our notification
return false
}

val notificationCallback = getCallbackHandle(activity!!, NOTIFICATION_CALLBACK_HANDLE_KEY)
if (notificationCallback > 0 && IsolateHolderService._backgroundFlutterView != null) {
val backgroundChannel = MethodChannel(IsolateHolderService._backgroundFlutterView,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package rekab.app.background_locator

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent

class BootBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == "android.intent.action.BOOT_COMPLETED") {
BackgroundLocatorPlugin.registerAfterBoot(context)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import rekab.app.background_locator.Keys.Companion.ARG_NOTIFICATION_MSG
import rekab.app.background_locator.Keys.Companion.ARG_NOTIFICATION_TITLE
import rekab.app.background_locator.Keys.Companion.ARG_WAKE_LOCK_TIME
import rekab.app.background_locator.Keys.Companion.CHANNEL_ID
import rekab.app.background_locator.Keys.Companion.NOTIFICATION_ACTION

class IsolateHolderService : Service() {
companion object {
Expand Down Expand Up @@ -64,6 +65,8 @@ class IsolateHolderService : Service() {
}

val intent = Intent(this, getMainActivityClass(this))
intent.action = NOTIFICATION_ACTION

val pendingIntent: PendingIntent = PendingIntent.getActivity(this, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT)

val notification = NotificationCompat.Builder(this, CHANNEL_ID)
Expand Down
3 changes: 3 additions & 0 deletions android/src/main/kotlin/rekab/app/background_locator/Keys.kt
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,8 @@ class Keys {
val BCM_SEND_LOCATION = "BCM_SEND_LOCATION"
@JvmStatic
val BCM_NOTIFICATION_CLICK = "BCM_NOTIFICATION_CLICK"

@JvmStatic
val NOTIFICATION_ACTION = "com.rekab.background_locator.notification"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package rekab.app.background_locator

import android.content.Context
import rekab.app.background_locator.Keys.Companion.ARG_WAKE_LOCK_TIME

class PreferencesManager() {
companion object {
private const val PREF_NAME = "background_locator"

@JvmStatic
fun saveCallbackDispatcher(context: Context, map: Map<Any, Any>) {
val sharedPreferences =
context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)

sharedPreferences.edit()
.putLong(Keys.ARG_CALLBACK_DISPATCHER,
map[Keys.ARG_CALLBACK_DISPATCHER] as Long)
.apply()
}

@JvmStatic
fun saveSettings(context: Context, map: Map<Any, Any>) {
val sharedPreferences =
context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)

sharedPreferences.edit()
.putLong(Keys.ARG_CALLBACK,
map[Keys.ARG_CALLBACK] as Long)
.apply()

if (map[Keys.ARG_NOTIFICATION_CALLBACK] as? Long != null) {
sharedPreferences.edit()
.putLong(Keys.ARG_NOTIFICATION_CALLBACK,
map[Keys.ARG_NOTIFICATION_CALLBACK] as Long)
.apply()
}

val settings = map[Keys.ARG_SETTINGS] as Map<*, *>

sharedPreferences.edit()
.putString(Keys.ARG_NOTIFICATION_TITLE,
settings[Keys.ARG_NOTIFICATION_TITLE] as String)
.apply()

sharedPreferences.edit()
.putString(Keys.ARG_NOTIFICATION_MSG,
settings[Keys.ARG_NOTIFICATION_MSG] as String)
.apply()

sharedPreferences.edit()
.putString(Keys.ARG_NOTIFICATION_ICON,
settings[Keys.ARG_NOTIFICATION_ICON] as String)
.apply()

sharedPreferences.edit()
.putInt(Keys.ARG_INTERVAL,
settings[Keys.ARG_INTERVAL] as Int)
.apply()

sharedPreferences.edit()
.putInt(Keys.ARG_ACCURACY,
settings[Keys.ARG_ACCURACY] as Int)
.apply()

sharedPreferences.edit()
.putFloat(Keys.ARG_DISTANCE_FILTER,
(settings[Keys.ARG_DISTANCE_FILTER] as Double).toFloat())
.apply()

if (settings.containsKey(ARG_WAKE_LOCK_TIME)) {
sharedPreferences.edit()
.putInt(Keys.ARG_WAKE_LOCK_TIME,
settings[ARG_WAKE_LOCK_TIME] as Int)
.apply()
}
}

@JvmStatic
fun getSettings(context: Context): Map<Any, Any> {
val sharedPreferences =
context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)

val result = HashMap<Any, Any>()

result[Keys.ARG_CALLBACK_DISPATCHER] = sharedPreferences.getLong(Keys.ARG_CALLBACK_DISPATCHER, 0)
result[Keys.ARG_CALLBACK] = sharedPreferences.getLong(Keys.ARG_CALLBACK, 0)

if (sharedPreferences.contains(Keys.ARG_NOTIFICATION_CALLBACK)) {
result[Keys.ARG_NOTIFICATION_CALLBACK] =
sharedPreferences.getLong(Keys.ARG_NOTIFICATION_CALLBACK, 0)
}

val settings = HashMap<String, Any?>()

settings[Keys.ARG_NOTIFICATION_TITLE] =
sharedPreferences.getString(Keys.ARG_NOTIFICATION_TITLE, "")

settings[Keys.ARG_NOTIFICATION_MSG] =
sharedPreferences.getString(Keys.ARG_NOTIFICATION_MSG, "")

settings[Keys.ARG_NOTIFICATION_ICON] =
sharedPreferences.getString(Keys.ARG_NOTIFICATION_ICON, "")

settings[Keys.ARG_INTERVAL] =
sharedPreferences.getInt(Keys.ARG_INTERVAL, 0)

settings[Keys.ARG_ACCURACY] =
sharedPreferences.getInt(Keys.ARG_ACCURACY, 0)

settings[Keys.ARG_DISTANCE_FILTER] =
sharedPreferences.getFloat(Keys.ARG_DISTANCE_FILTER, 0f).toDouble()

if (sharedPreferences.contains(ARG_WAKE_LOCK_TIME)) {
settings[ARG_WAKE_LOCK_TIME] = sharedPreferences.getInt(ARG_WAKE_LOCK_TIME, 0)
}

result[Keys.ARG_SETTINGS] = settings
return result
}

}
}
10 changes: 10 additions & 0 deletions example/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>


<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
Expand Down Expand Up @@ -44,6 +47,13 @@
android:exported="true"
/>

<receiver android:name="rekab.app.background_locator.BootBroadcastReceiver"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>

<service
android:name="rekab.app.background_locator.LocatorService"
android:permission="android.permission.BIND_JOB_SERVICE"
Expand Down
2 changes: 1 addition & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ class _MyAppState extends State<MyApp> {
notificationMsg: "Track location in background exapmle",
wakeLockTime: 20,
autoStop: false,
interval: 1
interval: 5
),
);
setState(() {
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: background_locator
description: A Flutter plugin to request the location even if the app is killed. Sending the location to a dart function in background, also provide a meter filter
version: 1.1.2+2
version: 1.1.3+1
homepage: https://github.com/rekab-app/background_locator

environment:
Expand Down