react-native-move-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +159 -0
  3. package/android/.project +17 -0
  4. package/android/build.gradle +145 -0
  5. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  6. package/android/gradle/wrapper/gradle-wrapper.properties +5 -0
  7. package/android/gradle.properties +4 -0
  8. package/android/gradlew +183 -0
  9. package/android/gradlew.bat +100 -0
  10. package/android/src/main/AndroidManifest.xml +3 -0
  11. package/android/src/main/java/in/dolph/move/sdk/MoveNotificationConfig.kt +41 -0
  12. package/android/src/main/java/in/dolph/move/sdk/MoveSdkConfig.kt +18 -0
  13. package/android/src/main/java/in/dolph/move/sdk/MoveSdkModule.kt +293 -0
  14. package/android/src/main/java/in/dolph/move/sdk/MoveSdkPackage.kt +19 -0
  15. package/android/src/main/java/in/dolph/move/sdk/MoveSdkRepository.kt +194 -0
  16. package/android/src/main/java/in/dolph/move/sdk/NativeMoveSdkWrapper.kt +305 -0
  17. package/android/src/main/res/drawable-anydpi-v24/ic_notification.xml +13 -0
  18. package/android/src/main/res/drawable-hdpi/ic_notification.png +0 -0
  19. package/android/src/main/res/drawable-mdpi/ic_notification.png +0 -0
  20. package/android/src/main/res/drawable-xhdpi/ic_notification.png +0 -0
  21. package/android/src/main/res/drawable-xxhdpi/ic_notification.png +0 -0
  22. package/android/src/main/res/values/strings.xml +9 -0
  23. package/android/src/main/strings.xml +0 -0
  24. package/ios/MoveSdk-Bridging-Header.h +2 -0
  25. package/ios/MoveSdk.xcodeproj/project.pbxproj +289 -0
  26. package/ios/MoveSdk.xcodeproj/project.xcworkspace/contents.xcworkspacedata +4 -0
  27. package/ios/MoveSdk.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  28. package/ios/NativeModule/DolphinSdk.h +58 -0
  29. package/ios/NativeModule/DolphinSdk.swift +353 -0
  30. package/ios/NativeModule/DolphinSdkDemoReactNative-Bridging-Header.h +8 -0
  31. package/lib/commonjs/index.js +280 -0
  32. package/lib/commonjs/index.js.map +1 -0
  33. package/lib/module/index.js +269 -0
  34. package/lib/module/index.js.map +1 -0
  35. package/lib/typescript/index.d.ts +98 -0
  36. package/package.json +135 -0
  37. package/react-native-move-sdk.podspec +20 -0
  38. package/src/index.ts +407 -0
@@ -0,0 +1,18 @@
1
+ package `in`.dolph.move.sdk
2
+
3
+ import io.dolphin.move.DrivingService
4
+ import io.dolphin.move.MoveAuth
5
+ import io.dolphin.move.OtherService
6
+ import io.dolphin.move.TimelineDetectionService
7
+ import io.dolphin.move.WalkingService
8
+
9
+ data class MoveSdkConfig(
10
+ val auth: MoveAuth,
11
+ val timelineDetectionServices: List<TimelineDetectionService>,
12
+ val drivingServices: List<DrivingService>,
13
+ val walkingServices: List<WalkingService>,
14
+ val otherServices: List<OtherService>,
15
+ val tripNotification: MoveNotificationConfig,
16
+ val recognitionNotification: MoveNotificationConfig,
17
+ val allowMockLocations: Boolean
18
+ )
@@ -0,0 +1,293 @@
1
+ package `in`.dolph.move.sdk
2
+
3
+ import android.annotation.SuppressLint
4
+ import android.app.Activity
5
+ import android.content.Context
6
+ import android.content.Intent
7
+ import android.net.Uri
8
+ import android.os.Build
9
+ import android.os.PowerManager
10
+ import android.provider.Settings
11
+ import android.util.Log
12
+ import androidx.annotation.RequiresApi
13
+ import com.facebook.react.bridge.ActivityEventListener
14
+ import com.facebook.react.bridge.Arguments
15
+ import com.facebook.react.bridge.Promise
16
+ import com.facebook.react.bridge.ReactApplicationContext
17
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
18
+ import com.facebook.react.bridge.ReactMethod
19
+ import com.facebook.react.bridge.ReadableArray
20
+ import com.facebook.react.bridge.WritableMap
21
+ import com.facebook.react.modules.core.DeviceEventManagerModule
22
+ import io.dolphin.move.MoveSdk
23
+
24
+ internal const val EVENT_INIT_ERROR = "DolphinSdk-InitError"
25
+ internal const val EVENT_MOVE_STATE = "DolphinSdk-State"
26
+ internal const val EVENT_TRIP_STATE = "DolphinSdk-TripState"
27
+ internal const val EVENT_AUTH_STATE = "DolphinSdk-AuthState"
28
+ internal const val EVENT_AUTH_BATTERY_PERMISSION = "DolphinSdk-Permission-BatteryOptimization"
29
+ internal const val EVENT_AUTH_OVERLAY_PERMISSION = "DolphinSdk-Permission-Overlay"
30
+
31
+ internal const val ARGUMENT_ACCESS_TOKEN = "accessToken"
32
+ internal const val ARGUMENT_REFRESH_TOKEN = "refreshToken"
33
+ internal const val ARGUMENT_STATE = "state"
34
+ internal const val ARGUMENT_ERROR = "error"
35
+ internal const val ARGUMENT_ERROR_REASON = "errorReason"
36
+
37
+ internal const val PROMISE_OK = "OK"
38
+
39
+ class MoveSdkModule(context: ReactApplicationContext) : ReactContextBaseJavaModule(context),
40
+ ActivityEventListener {
41
+
42
+ companion object {
43
+ const val LOG_TAG = "DOLPHIN_SDK"
44
+ const val ERROR_CODE = "DOLPHIN_SDK_ERROR"
45
+
46
+ // **** PERMISSIONS MODULE START *****
47
+ const val OVERLAY_REQUEST_CODE = 1
48
+ const val BATTERY_OPTIMIZATION_REQUEST_CODE = 2
49
+ // **** PERMISSIONS MODULE END *****
50
+ }
51
+
52
+ private val reactContext: ReactApplicationContext = context
53
+
54
+ private val nativeSdkWrapper = NativeMoveSdkWrapper.getInstance(reactContext)
55
+
56
+ init {
57
+ nativeSdkWrapper.applyDelegate(this)
58
+
59
+ // **** PERMISSIONS MODULE START *****
60
+ reactContext.addActivityEventListener(this)
61
+ // **** PERMISSIONS MODULE START *****
62
+ }
63
+
64
+ // **** PERMISSIONS MODULE START *****
65
+ override fun onNewIntent(intent: Intent) {
66
+ // Skip, currently obsolete ActivityEventListener callback
67
+ }
68
+ // **** PERMISSIONS MODULE START *****
69
+
70
+ @ReactMethod
71
+ fun initialize(
72
+ contractId: String,
73
+ accessToken: String,
74
+ refreshToken: String,
75
+ productId: Int,
76
+ // Config
77
+ timelineDetectionServices: ReadableArray,
78
+ drivingServices: ReadableArray,
79
+ walkingServices: ReadableArray,
80
+ otherServices: ReadableArray,
81
+ // Platform config
82
+ recognitionNotificationTitle: String,
83
+ recognitionNotificationText: String,
84
+ recognitionNotificationChannelId: String,
85
+ recognitionNotificationChannelName: String,
86
+ recognitionNotificationChannelDescription: String,
87
+ tripNotificationTitle: String,
88
+ tripNotificationText: String,
89
+ tripNotificationChannelId: String,
90
+ tripNotificationChannelName: String,
91
+ tripNotificationChannelDescription: String,
92
+ allowMockLocations: Boolean,
93
+ promise: Promise?
94
+ ) {
95
+
96
+ nativeSdkWrapper.initialize(
97
+ contractId,
98
+ accessToken,
99
+ refreshToken,
100
+ productId,
101
+ // Config
102
+ timelineDetectionServices,
103
+ drivingServices,
104
+ walkingServices,
105
+ otherServices,
106
+ // Platform config
107
+ recognitionNotificationTitle,
108
+ recognitionNotificationText,
109
+ recognitionNotificationChannelId,
110
+ recognitionNotificationChannelName,
111
+ recognitionNotificationChannelDescription,
112
+ tripNotificationTitle,
113
+ tripNotificationText,
114
+ tripNotificationChannelId,
115
+ tripNotificationChannelName,
116
+ tripNotificationChannelDescription,
117
+ allowMockLocations,
118
+ promise = promise
119
+ )
120
+ }
121
+
122
+ @ReactMethod
123
+ fun resolveError() {
124
+ nativeSdkWrapper.resolveError()
125
+ }
126
+
127
+ @ReactMethod
128
+ fun startAutomaticDetection() {
129
+ nativeSdkWrapper.startAutomaticDetection()
130
+ }
131
+
132
+ @ReactMethod
133
+ fun stopAutomaticDetection() {
134
+ nativeSdkWrapper.stopAutomaticDetection()
135
+ }
136
+
137
+ @ReactMethod
138
+ fun shutdown() {
139
+ nativeSdkWrapper.shutdown()
140
+ }
141
+
142
+ @ReactMethod
143
+ fun forceTripRecognition() {
144
+ nativeSdkWrapper.forceTripRecognition()
145
+ }
146
+
147
+ @ReactMethod
148
+ fun keepInForeground(enabled: Boolean) {
149
+ nativeSdkWrapper.keepInForeground(enabled)
150
+ }
151
+
152
+ @ReactMethod
153
+ fun keepActive(enabled: Boolean) {
154
+ nativeSdkWrapper.keepActive(enabled)
155
+ }
156
+
157
+ @ReactMethod
158
+ fun synchronizeUserData() {
159
+ nativeSdkWrapper.synchronizeUserData()
160
+ }
161
+
162
+ @ReactMethod
163
+ fun ignoreCurrentTrip() {
164
+ nativeSdkWrapper.ignoreCurrentTrip()
165
+ }
166
+
167
+ @ReactMethod
168
+ fun finishCurrentTrip() {
169
+ nativeSdkWrapper.finishCurrentTrip()
170
+ }
171
+
172
+ @ReactMethod
173
+ fun getState(promise: Promise) {
174
+ nativeSdkWrapper.getState(promise)
175
+ }
176
+
177
+ @ReactMethod
178
+ fun getTripState(promise: Promise) {
179
+ nativeSdkWrapper.getTripState(promise)
180
+ }
181
+
182
+ @ReactMethod
183
+ fun updateAuth(
184
+ contractId: String,
185
+ accessToken: String,
186
+ refreshToken: String,
187
+ productId: Int
188
+ ) {
189
+ nativeSdkWrapper.updateAuth(contractId, accessToken, refreshToken, productId)
190
+ }
191
+
192
+ @ReactMethod
193
+ fun getAuthState(promise: Promise) {
194
+ nativeSdkWrapper.getAuthState(promise)
195
+ }
196
+
197
+ override fun getName(): String {
198
+ return "DolphinSdk"
199
+ }
200
+
201
+ override fun getConstants(): MutableMap<String, Any> {
202
+ val constants: HashMap<String, Any> = HashMap()
203
+ constants["version"] = MoveSdk.version
204
+ return constants
205
+ }
206
+
207
+ internal fun emitDeviceEvent(eventName: String, eventData: WritableMap?) {
208
+ try {
209
+ reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
210
+ .emit(eventName, eventData)
211
+ } catch (t: Throwable) {
212
+ Log.e("SDK Module", t.message, t)
213
+ // java.lang.IllegalStateException: Tried to access a JS module before the React instance was fully set up.
214
+ // Calls to ReactContext#getJSModule should only happen once initialize() has been called on your native module.
215
+ }
216
+ }
217
+
218
+ @ReactMethod
219
+ fun addListener(eventName: String) {
220
+ // Set up any upstream listeners or background tasks as necessary
221
+ }
222
+
223
+ @ReactMethod
224
+ fun removeListeners(count: Int) {
225
+ // Remove upstream listeners, stop unnecessary background tasks
226
+ }
227
+
228
+ // **** PERMISSIONS MODULE START *****
229
+ @SuppressLint("NewApi")
230
+ override fun onActivityResult(
231
+ activity: Activity,
232
+ requestCode: Int,
233
+ resultCode: Int,
234
+ data: Intent?
235
+ ) {
236
+ if (requestCode == OVERLAY_REQUEST_CODE) {
237
+ val eventData = Arguments.createMap()
238
+ eventData.putBoolean(ARGUMENT_STATE, Settings.canDrawOverlays(reactContext))
239
+ emitDeviceEvent(EVENT_AUTH_OVERLAY_PERMISSION, eventData)
240
+ } else if (requestCode == BATTERY_OPTIMIZATION_REQUEST_CODE) {
241
+ val eventData = Arguments.createMap()
242
+ eventData.putBoolean(ARGUMENT_STATE, isAppIgnoringBatteryOptimization())
243
+ emitDeviceEvent(EVENT_AUTH_BATTERY_PERMISSION, eventData)
244
+ }
245
+ }
246
+
247
+ @ReactMethod
248
+ fun canDrawOverlays(promise: Promise) {
249
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
250
+ promise.resolve(Settings.canDrawOverlays(reactContext))
251
+ } else {
252
+ promise.resolve(true)
253
+ }
254
+ }
255
+
256
+ @RequiresApi(Build.VERSION_CODES.M)
257
+ @ReactMethod
258
+ fun requestDrawOverlaysPermission() {
259
+ val intent = Intent(
260
+ Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
261
+ Uri.parse("package:${reactContext.packageName}")
262
+ )
263
+ reactContext.currentActivity!!.startActivityForResult(intent, OVERLAY_REQUEST_CODE)
264
+ }
265
+
266
+ private fun isAppIgnoringBatteryOptimization(): Boolean {
267
+ val packageName = reactContext.packageName
268
+ val pm: PowerManager = reactContext.getSystemService(Context.POWER_SERVICE) as PowerManager
269
+
270
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
271
+ return pm.isIgnoringBatteryOptimizations(packageName)
272
+ } else {
273
+ return true
274
+ }
275
+ }
276
+
277
+ @ReactMethod
278
+ fun isAppIgnoringBatteryOptimization(promise: Promise) {
279
+ promise.resolve(isAppIgnoringBatteryOptimization())
280
+ }
281
+
282
+ @SuppressLint("BatteryLife")
283
+ @RequiresApi(Build.VERSION_CODES.M)
284
+ @ReactMethod
285
+ fun requestAppIgnoringBatteryOptimization() {
286
+ val intent = Intent(
287
+ Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
288
+ Uri.parse("package:" + reactContext.packageName)
289
+ )
290
+ reactContext.currentActivity?.startActivityForResult(intent, BATTERY_OPTIMIZATION_REQUEST_CODE)
291
+ }
292
+ // **** PERMISSIONS MODULE END *****
293
+ }
@@ -0,0 +1,19 @@
1
+ package `in`.dolph.move.sdk
2
+
3
+ import android.view.View
4
+ import com.facebook.react.ReactPackage
5
+ import com.facebook.react.bridge.NativeModule
6
+ import com.facebook.react.bridge.ReactApplicationContext
7
+ import com.facebook.react.uimanager.ReactShadowNode
8
+ import com.facebook.react.uimanager.ViewManager
9
+
10
+ class MoveSdkPackage : ReactPackage {
11
+
12
+ override fun createViewManagers(reactContext: ReactApplicationContext): MutableList<ViewManager<out View, out ReactShadowNode<*>>> {
13
+ return mutableListOf()
14
+ }
15
+
16
+ override fun createNativeModules(reactContext: ReactApplicationContext): MutableList<NativeModule> {
17
+ return mutableListOf(MoveSdkModule(reactContext))
18
+ }
19
+ }
@@ -0,0 +1,194 @@
1
+ package `in`.dolph.move.sdk
2
+
3
+ import android.content.Context
4
+ import android.content.SharedPreferences
5
+ import io.dolphin.move.DrivingService
6
+ import io.dolphin.move.MoveAuth
7
+ import io.dolphin.move.OtherService
8
+ import io.dolphin.move.TimelineDetectionService
9
+ import io.dolphin.move.WalkingService
10
+
11
+ private const val SHARED_PREF_NAME = "move-react"
12
+
13
+ private const val PROPERTY_TIMELINE_SERVICES = "timelineDetectionServices"
14
+ private const val PROPERTY_DRIVING_SERVICES = "drivingServices"
15
+ private const val PROPERTY_WALKING_SERVICES = "walkingServices"
16
+ private const val PROPERTY_OTHER_SERVICES = "otherServices"
17
+
18
+ private const val PROPERTY_PRODUCT_ID = "productId"
19
+ private const val PROPERTY_CONTRACT_ID = "contractId"
20
+ private const val PROPERTY_ACCESS_TOKEN = "accessToken"
21
+ private const val PROPERTY_REFRESH_TOKEN = "refreshToken"
22
+
23
+ private const val PROPERTY_ALLOW_MOCK = "allowMockLocations"
24
+ private const val PROPERTY_STARTED = "isInRunningState"
25
+
26
+ private const val PROPERTY_NOTIFICATION_TITLE = "NotificationTitle"
27
+ private const val PROPERTY_NOTIFICATION_TEXT = "NotificationText"
28
+ private const val PROPERTY_NOTIFICATION_CHANNELID = "NotificationChannelId"
29
+ private const val PROPERTY_NOTIFICATION_CHANNELNAME = "NotificationChannelName"
30
+ private const val PROPERTY_NOTIFICATION_CHANNELDESCRIPTION = "NotificationChannelName"
31
+
32
+ private const val NOTIFICATION_RECOGNITION = "recognition"
33
+ private const val NOTIFICATION_TRIP = "trip"
34
+
35
+ class MoveSdkConfigRepository(context: Context) {
36
+
37
+ private val sharedPreferences: SharedPreferences =
38
+ context.applicationContext.getSharedPreferences(
39
+ SHARED_PREF_NAME,
40
+ Context.MODE_PRIVATE
41
+ )
42
+
43
+ fun storeConfig(config: MoveSdkConfig) {
44
+
45
+ // Persist data for native init next app start
46
+ val editor = sharedPreferences.edit()
47
+
48
+ storeAuth(config.auth)
49
+
50
+ editor.putStringSet(
51
+ PROPERTY_TIMELINE_SERVICES,
52
+ config.timelineDetectionServices.map { it.toString() }.toSet()
53
+ )
54
+ editor.putStringSet(
55
+ PROPERTY_DRIVING_SERVICES,
56
+ config.drivingServices.map { it.toString() }.toSet()
57
+ )
58
+ editor.putStringSet(
59
+ PROPERTY_WALKING_SERVICES,
60
+ config.walkingServices.map { it.toString() }.toSet()
61
+ )
62
+ editor.putStringSet(
63
+ PROPERTY_OTHER_SERVICES,
64
+ config.otherServices.map { it.toString() }.toSet()
65
+ )
66
+
67
+ editor.putBoolean(PROPERTY_ALLOW_MOCK, config.allowMockLocations)
68
+ editor.apply()
69
+
70
+ // Platform config
71
+ val recognitionNotification = config.recognitionNotification
72
+ storeNotificationConfig(NOTIFICATION_RECOGNITION, recognitionNotification)
73
+
74
+ val tripNotification = config.tripNotification
75
+ storeNotificationConfig(NOTIFICATION_TRIP, tripNotification)
76
+ }
77
+
78
+ private fun storeNotificationConfig(
79
+ prefix: String,
80
+ recognitionNotification: MoveNotificationConfig
81
+ ) {
82
+ val editor = sharedPreferences.edit()
83
+ editor.putString(prefix + PROPERTY_NOTIFICATION_TITLE, recognitionNotification.title)
84
+ editor.putString(prefix + PROPERTY_NOTIFICATION_TEXT, recognitionNotification.text)
85
+ editor.putString(
86
+ prefix + PROPERTY_NOTIFICATION_CHANNELID,
87
+ recognitionNotification.channelId
88
+ )
89
+ editor.putString(
90
+ prefix + PROPERTY_NOTIFICATION_CHANNELNAME,
91
+ recognitionNotification.channelName
92
+ )
93
+ editor.putString(
94
+ prefix + PROPERTY_NOTIFICATION_CHANNELDESCRIPTION,
95
+ recognitionNotification.channelDescription
96
+ )
97
+ editor.apply()
98
+ }
99
+
100
+ fun storeAuth(auth: MoveAuth) {
101
+ // Persist data for native init next app start
102
+ val editor = sharedPreferences.edit()
103
+ editor.putInt(PROPERTY_PRODUCT_ID, auth.productId.toInt())
104
+ editor.putString(PROPERTY_CONTRACT_ID, auth.contractId)
105
+ editor.putString(PROPERTY_ACCESS_TOKEN, auth.accessToken)
106
+ editor.putString(PROPERTY_REFRESH_TOKEN, auth.refreshToken)
107
+ editor.apply()
108
+ }
109
+
110
+ fun loadConfig(): MoveSdkConfig {
111
+
112
+ val productId = sharedPreferences.getInt(PROPERTY_PRODUCT_ID, 0)
113
+ val contractId = sharedPreferences.getString(PROPERTY_CONTRACT_ID, "") ?: ""
114
+ val accessToken: String = sharedPreferences.getString(PROPERTY_ACCESS_TOKEN, "") ?: ""
115
+ val refreshToken = sharedPreferences.getString(PROPERTY_REFRESH_TOKEN, "") ?: ""
116
+
117
+ // Config
118
+
119
+ val timelineDetectionServices: List<TimelineDetectionService> =
120
+ sharedPreferences.getStringSet(PROPERTY_TIMELINE_SERVICES, emptySet())?.map {
121
+ TimelineDetectionService.valueOf(it)
122
+ } ?: emptyList()
123
+
124
+ val drivingServices: List<DrivingService> =
125
+ sharedPreferences.getStringSet(PROPERTY_DRIVING_SERVICES, emptySet())?.map {
126
+ DrivingService.valueOf(it)
127
+ } ?: emptyList()
128
+
129
+ val walkingServices: List<WalkingService> =
130
+ sharedPreferences.getStringSet(PROPERTY_WALKING_SERVICES, emptySet())?.map {
131
+ WalkingService.valueOf(it)
132
+ } ?: emptyList()
133
+
134
+ val otherServices: List<OtherService> =
135
+ sharedPreferences.getStringSet(PROPERTY_OTHER_SERVICES, emptySet())?.map {
136
+ OtherService.valueOf(it)
137
+ } ?: emptyList()
138
+
139
+ // Platform config
140
+ val allowMockLocations: Boolean = sharedPreferences.getBoolean(PROPERTY_ALLOW_MOCK, false)
141
+
142
+ val recognitionNotification = loadNotificationConfig(NOTIFICATION_RECOGNITION)
143
+ val tripNotification = loadNotificationConfig(NOTIFICATION_TRIP)
144
+
145
+ return MoveSdkConfig(
146
+ auth = MoveAuth(
147
+ contractId = contractId,
148
+ accessToken = accessToken,
149
+ refreshToken = refreshToken,
150
+ productId = productId.toLong(),
151
+ ),
152
+ timelineDetectionServices = timelineDetectionServices,
153
+ drivingServices = drivingServices,
154
+ walkingServices = walkingServices,
155
+ otherServices = otherServices,
156
+ tripNotification = tripNotification,
157
+ recognitionNotification = recognitionNotification,
158
+ allowMockLocations = allowMockLocations
159
+ )
160
+ }
161
+
162
+ private fun loadNotificationConfig(prefix: String): MoveNotificationConfig {
163
+ val notificationTitle: String =
164
+ sharedPreferences.getString(prefix + PROPERTY_NOTIFICATION_TITLE, "") ?: ""
165
+ val notificationText: String =
166
+ sharedPreferences.getString(prefix + PROPERTY_NOTIFICATION_TEXT, "") ?: ""
167
+ val notificationChannelId: String =
168
+ sharedPreferences.getString(prefix + PROPERTY_NOTIFICATION_CHANNELID, "") ?: ""
169
+ val notificationChannelName: String =
170
+ sharedPreferences.getString(prefix + PROPERTY_NOTIFICATION_CHANNELNAME, "") ?: ""
171
+ val notificationChannelDescription: String =
172
+ sharedPreferences.getString(prefix + PROPERTY_NOTIFICATION_CHANNELDESCRIPTION, "") ?: ""
173
+
174
+ return MoveNotificationConfig(
175
+ title = notificationTitle,
176
+ text = notificationText,
177
+ channelId = notificationChannelId,
178
+ channelName = notificationChannelName,
179
+ channelDescription = notificationChannelDescription
180
+ )
181
+ }
182
+
183
+ fun storeRunningState(running: Boolean) {
184
+ sharedPreferences.edit().putBoolean(PROPERTY_STARTED, running).apply()
185
+ }
186
+
187
+ fun loadRunningState(): Boolean {
188
+ return sharedPreferences.getBoolean(PROPERTY_STARTED, false)
189
+ }
190
+
191
+ fun clear() {
192
+ sharedPreferences.edit().clear().apply()
193
+ }
194
+ }