react-native-move-sdk 2.10.1 → 2.10.3

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.
@@ -144,7 +144,7 @@ dependencies {
144
144
  // noinspection GradleDynamicVersion
145
145
 
146
146
  implementation "com.facebook.react:react-native:+"
147
- api "io.dolphin.move:move-sdk:2.10.0.87"
147
+ api "io.dolphin.move:move-sdk:2.10.1.88"
148
148
 
149
149
  testImplementation 'junit:junit:4.13.2'
150
150
  testImplementation "androidx.test:core:1.4.0"
@@ -12,6 +12,7 @@ import android.os.Build
12
12
  import androidx.core.content.ContextCompat
13
13
  import androidx.core.content.edit
14
14
  import com.google.gson.Gson
15
+ import `in`.dolph.move.sdk.extentions.PermissionUtils
15
16
  import io.dolphin.move.MoveDevice
16
17
  import io.dolphin.move.MoveSdk
17
18
  import java.nio.ByteBuffer
@@ -55,9 +56,12 @@ class DeviceScanner(
55
56
  onNewDevices: (List<MoveDevice>) -> Unit,
56
57
  onNewEvent: (String, String?) -> Unit,
57
58
  ) {
58
- if (filters.contains(MoveDeviceFilter.PAIRED.filter)) {
59
+ if (filters.contains(MoveDeviceFilter.CONNECTED.filter)) {
59
60
  proceedWithConnectedDevices(onNewDevices, onNewEvent)
60
61
  }
62
+ if (filters.contains(MoveDeviceFilter.PAIRED.filter)) {
63
+ proceedWithPairedDevices(onNewDevices, onNewEvent)
64
+ }
61
65
  if (filters.contains(MoveDeviceFilter.BEACON.filter)) {
62
66
  this.onNewDevices = onNewDevices
63
67
  this.proximityId = uuid
@@ -93,6 +97,22 @@ class DeviceScanner(
93
97
  }
94
98
  }
95
99
 
100
+ @SuppressLint("MissingPermission")
101
+ private fun proceedWithPairedDevices(
102
+ onNewDevices: (List<MoveDevice>) -> Unit,
103
+ onNewEvent: (String, String?) -> Unit,
104
+ ) {
105
+ if (PermissionUtils.hasBluetoothConnectPermission(context)) {
106
+ val bondedDevices = btManager?.adapter?.bondedDevices
107
+ ?.mapNotNull { MoveSdk.get()?.convertToMoveDevice(it) }
108
+ onNewEvent(TAG, "Bonded devices: ${bondedDevices?.map { it.name }}")
109
+ bondedDevices ?: return
110
+ onNewDevices(bondedDevices)
111
+ } else {
112
+ onNewEvent(TAG, "Missing BLUETOOTH_CONNECT permission")
113
+ }
114
+ }
115
+
96
116
  private fun proceedWithConnectedDevices(
97
117
  onNewDevices: (List<MoveDevice>) -> Unit,
98
118
  onNewEvent: (String, String?) -> Unit,
@@ -182,5 +202,6 @@ class DeviceScanner(
182
202
 
183
203
  enum class MoveDeviceFilter(val filter: String) {
184
204
  BEACON("beacon"),
185
- PAIRED("paired");
205
+ PAIRED("paired"),
206
+ CONNECTED("connected");
186
207
  }
@@ -2,6 +2,7 @@ package `in`.dolph.move.sdk
2
2
 
3
3
  import android.annotation.SuppressLint
4
4
  import android.app.Activity
5
+ import android.bluetooth.BluetoothManager
5
6
  import android.content.Context
6
7
  import android.content.Intent
7
8
  import android.net.Uri
@@ -105,14 +106,8 @@ class MoveSdkModule(context: ReactApplicationContext) : ReactContextBaseJavaModu
105
106
  // Platform config
106
107
  recognitionNotificationTitle: String,
107
108
  recognitionNotificationText: String,
108
- recognitionNotificationChannelId: String,
109
- recognitionNotificationChannelName: String,
110
- recognitionNotificationChannelDescription: String,
111
109
  tripNotificationTitle: String,
112
110
  tripNotificationText: String,
113
- tripNotificationChannelId: String,
114
- tripNotificationChannelName: String,
115
- tripNotificationChannelDescription: String,
116
111
  promise: Promise?
117
112
  ) {
118
113
  nativeSdkWrapper.setup(
@@ -128,14 +123,8 @@ class MoveSdkModule(context: ReactApplicationContext) : ReactContextBaseJavaModu
128
123
  // Platform config
129
124
  recognitionNotificationTitle,
130
125
  recognitionNotificationText,
131
- recognitionNotificationChannelId,
132
- recognitionNotificationChannelName,
133
- recognitionNotificationChannelDescription,
134
126
  tripNotificationTitle,
135
127
  tripNotificationText,
136
- tripNotificationChannelId,
137
- tripNotificationChannelName,
138
- tripNotificationChannelDescription,
139
128
  promise = promise
140
129
  )
141
130
  }
@@ -151,14 +140,8 @@ class MoveSdkModule(context: ReactApplicationContext) : ReactContextBaseJavaModu
151
140
  // Platform config
152
141
  recognitionNotificationTitle: String,
153
142
  recognitionNotificationText: String,
154
- recognitionNotificationChannelId: String,
155
- recognitionNotificationChannelName: String,
156
- recognitionNotificationChannelDescription: String,
157
143
  tripNotificationTitle: String,
158
144
  tripNotificationText: String,
159
- tripNotificationChannelId: String,
160
- tripNotificationChannelName: String,
161
- tripNotificationChannelDescription: String,
162
145
  promise: Promise?
163
146
  ) {
164
147
  nativeSdkWrapper.setup(
@@ -171,14 +154,8 @@ class MoveSdkModule(context: ReactApplicationContext) : ReactContextBaseJavaModu
171
154
  // Platform config
172
155
  recognitionNotificationTitle,
173
156
  recognitionNotificationText,
174
- recognitionNotificationChannelId,
175
- recognitionNotificationChannelName,
176
- recognitionNotificationChannelDescription,
177
157
  tripNotificationTitle,
178
158
  tripNotificationText,
179
- tripNotificationChannelId,
180
- tripNotificationChannelName,
181
- tripNotificationChannelDescription,
182
159
  promise = promise
183
160
  )
184
161
  }
@@ -471,6 +448,16 @@ class MoveSdkModule(context: ReactApplicationContext) : ReactContextBaseJavaModu
471
448
  }
472
449
  }
473
450
 
451
+ @ReactMethod
452
+ fun getBluetoothState(promise: Promise) {
453
+ promise.resolve(nativeSdkWrapper.isBluetoothEnabled())
454
+ }
455
+
456
+ @ReactMethod
457
+ fun getBluetoothPermission(promise: Promise) {
458
+ promise.resolve(nativeSdkWrapper.hasDiscoveryPermissions())
459
+ }
460
+
474
461
  // region PERMISSIONS MODULE
475
462
  @SuppressLint("NewApi")
476
463
  override fun onActivityResult(
@@ -492,14 +479,9 @@ class MoveSdkModule(context: ReactApplicationContext) : ReactContextBaseJavaModu
492
479
 
493
480
  @ReactMethod
494
481
  fun canDrawOverlays(promise: Promise) {
495
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
496
- promise.resolve(Settings.canDrawOverlays(reactContext))
497
- } else {
498
- promise.resolve(true)
499
- }
482
+ promise.resolve(Settings.canDrawOverlays(reactContext))
500
483
  }
501
484
 
502
- @RequiresApi(Build.VERSION_CODES.M)
503
485
  @ReactMethod
504
486
  fun requestDrawOverlaysPermission() {
505
487
  val intent = Intent(
@@ -512,12 +494,7 @@ class MoveSdkModule(context: ReactApplicationContext) : ReactContextBaseJavaModu
512
494
  private fun isAppIgnoringBatteryOptimization(): Boolean {
513
495
  val packageName = reactContext.packageName
514
496
  val pm: PowerManager = reactContext.getSystemService(Context.POWER_SERVICE) as PowerManager
515
-
516
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
517
- return pm.isIgnoringBatteryOptimizations(packageName)
518
- } else {
519
- return true
520
- }
497
+ return pm.isIgnoringBatteryOptimizations(packageName)
521
498
  }
522
499
 
523
500
  @ReactMethod
@@ -526,7 +503,6 @@ class MoveSdkModule(context: ReactApplicationContext) : ReactContextBaseJavaModu
526
503
  }
527
504
 
528
505
  @SuppressLint("BatteryLife")
529
- @RequiresApi(Build.VERSION_CODES.M)
530
506
  @ReactMethod
531
507
  fun requestAppIgnoringBatteryOptimization() {
532
508
  val intent = Intent(
@@ -3,34 +3,16 @@ package `in`.dolph.move.sdk
3
3
  import android.content.Context
4
4
  import android.content.SharedPreferences
5
5
  import io.dolphin.move.DrivingService
6
- import io.dolphin.move.MoveAuth
7
6
  import io.dolphin.move.MoveDetectionService
8
7
  import io.dolphin.move.WalkingService
9
8
 
10
9
  private const val SHARED_PREF_NAME = "move-react"
11
10
 
12
- private const val PROPERTY_TIMELINE_SERVICES = "timelineDetectionServices"
13
- private const val PROPERTY_DRIVING_SERVICES = "drivingServices"
14
- private const val PROPERTY_WALKING_SERVICES = "walkingServices"
15
-
16
11
  private const val PROPERTY_PRODUCT_ID = "productId"
17
12
  private const val PROPERTY_USER_ID = "contractId"
18
13
  private const val PROPERTY_ACCESS_TOKEN = "accessToken"
19
14
  private const val PROPERTY_REFRESH_TOKEN = "refreshToken"
20
15
 
21
- private const val PROPERTY_STARTED = "isInRunningState"
22
-
23
- private const val PROPERTY_NOTIFICATION_TITLE = "NotificationTitle"
24
- private const val PROPERTY_NOTIFICATION_TEXT = "NotificationText"
25
- private const val PROPERTY_NOTIFICATION_CHANNELID = "NotificationChannelId"
26
- private const val PROPERTY_NOTIFICATION_CHANNELNAME = "NotificationChannelName"
27
- private const val PROPERTY_NOTIFICATION_CHANNELDESCRIPTION = "NotificationChannelName"
28
- private const val PROPERTY_NOTIFICATION_ICON = "NotificationIcon"
29
-
30
- private const val NOTIFICATION_RECOGNITION = "recognition"
31
- private const val NOTIFICATION_TRIP = "trip"
32
- private const val NOTIFICATION_WALKING = "walking"
33
-
34
16
  class MoveSdkConfigRepository(context: Context) {
35
17
 
36
18
  private val sharedPreferences: SharedPreferences =
@@ -39,139 +21,20 @@ class MoveSdkConfigRepository(context: Context) {
39
21
  Context.MODE_PRIVATE
40
22
  )
41
23
 
42
- fun storeConfig(config: MoveSdkConfig) {
43
-
44
- // Persist data for native init next app start
45
- val editor = sharedPreferences.edit()
46
- editor.putStringSet(
47
- PROPERTY_TIMELINE_SERVICES,
48
- config.timelineDetectionServices.map { service -> service.name() }.toSet()
49
- )
50
- editor.apply()
51
-
52
- storeAuth(config.auth)
53
-
54
- // Platform config
55
- val recognitionNotification = config.recognitionNotification
56
- storeNotificationConfig(NOTIFICATION_RECOGNITION, recognitionNotification)
57
-
58
- val tripNotification = config.tripNotification
59
- storeNotificationConfig(NOTIFICATION_TRIP, tripNotification)
60
-
61
- val walkingNotification = config.walkingNotification
62
- storeNotificationConfig(NOTIFICATION_WALKING, walkingNotification)
63
- }
64
-
65
- private fun storeNotificationConfig(
66
- prefix: String,
67
- recognitionNotification: MoveNotificationConfig
68
- ) {
69
- val editor = sharedPreferences.edit()
70
- editor.putString(prefix + PROPERTY_NOTIFICATION_TITLE, recognitionNotification.title)
71
- editor.putString(prefix + PROPERTY_NOTIFICATION_TEXT, recognitionNotification.text)
72
- editor.putString(
73
- prefix + PROPERTY_NOTIFICATION_CHANNELID,
74
- recognitionNotification.channelId
75
- )
76
- editor.putString(
77
- prefix + PROPERTY_NOTIFICATION_CHANNELNAME,
78
- recognitionNotification.channelName
79
- )
80
- editor.putString(
81
- prefix + PROPERTY_NOTIFICATION_CHANNELDESCRIPTION,
82
- recognitionNotification.channelDescription
83
- )
84
- editor.putInt(
85
- prefix + PROPERTY_NOTIFICATION_ICON,
86
- recognitionNotification.icon ?: 0,
87
- )
88
- editor.apply()
89
- }
90
-
91
- fun storeAuth(auth: MoveAuth) {
92
- // Persist data for native init next app start
93
- val editor = sharedPreferences.edit()
94
- editor.putInt(PROPERTY_PRODUCT_ID, auth.projectId.toInt())
95
- editor.putString(PROPERTY_USER_ID, auth.userId)
96
- editor.putString(PROPERTY_ACCESS_TOKEN, auth.accessToken)
97
- editor.putString(PROPERTY_REFRESH_TOKEN, auth.refreshToken)
98
- editor.apply()
99
- }
100
-
101
- fun loadConfig(): MoveSdkConfig {
102
-
103
- val projectId = sharedPreferences.getInt(PROPERTY_PRODUCT_ID, 0)
104
- val userId = sharedPreferences.getString(PROPERTY_USER_ID, "") ?: ""
105
- val accessToken: String = sharedPreferences.getString(PROPERTY_ACCESS_TOKEN, "") ?: ""
106
- val refreshToken = sharedPreferences.getString(PROPERTY_REFRESH_TOKEN, "") ?: ""
107
-
108
- // Config
109
-
110
- /*
111
- val drivingServices: List<DrivingService> =
112
- sharedPreferences.getStringSet(PROPERTY_DRIVING_SERVICES, emptySet())?.map { service ->
113
- DrivingService.valueOf(service)
114
- } ?: emptyList()
115
-
116
- val walkingServices: List<WalkingService> =
117
- sharedPreferences.getStringSet(PROPERTY_WALKING_SERVICES, emptySet())?.map { service ->
118
- WalkingService.valueOf(service)
119
- } ?: emptyList()
120
-
121
- val timelineDetectionServices: List<MoveDetectionService> = emptyList()
122
- sharedPreferences.getStringSet(PROPERTY_TIMELINE_SERVICES, emptySet())?.map { service ->
123
- valueOfMoveDetectionService(service, drivingServices, walkingServices)
124
- } ?: emptyList()
125
- */
126
-
127
- val recognitionNotification = loadNotificationConfig(NOTIFICATION_RECOGNITION)
128
- val tripNotification = loadNotificationConfig(NOTIFICATION_TRIP)
129
- val walkingNotification = loadNotificationConfig(NOTIFICATION_WALKING)
130
-
131
- return MoveSdkConfig(
132
- auth = MoveAuth(
133
- userId = userId,
134
- accessToken = accessToken,
135
- refreshToken = refreshToken,
136
- projectId = projectId.toLong(),
137
- ),
138
- timelineDetectionServices = emptyList(),
139
- tripNotification = tripNotification,
140
- recognitionNotification = recognitionNotification,
141
- walkingNotification = walkingNotification
142
- )
143
- }
144
-
145
- private fun loadNotificationConfig(prefix: String): MoveNotificationConfig {
146
- val notificationTitle: String =
147
- sharedPreferences.getString(prefix + PROPERTY_NOTIFICATION_TITLE, "") ?: ""
148
- val notificationText: String =
149
- sharedPreferences.getString(prefix + PROPERTY_NOTIFICATION_TEXT, "") ?: ""
150
- val notificationChannelId: String =
151
- sharedPreferences.getString(prefix + PROPERTY_NOTIFICATION_CHANNELID, "") ?: ""
152
- val notificationChannelName: String =
153
- sharedPreferences.getString(prefix + PROPERTY_NOTIFICATION_CHANNELNAME, "") ?: ""
154
- val notificationChannelDescription: String =
155
- sharedPreferences.getString(prefix + PROPERTY_NOTIFICATION_CHANNELDESCRIPTION, "") ?: ""
156
- val notificationIcon: Int =
157
- sharedPreferences.getInt(prefix + PROPERTY_NOTIFICATION_ICON, 0)
158
-
159
- return MoveNotificationConfig(
160
- title = notificationTitle,
161
- text = notificationText,
162
- icon = notificationIcon.takeIf { it != 0 },
163
- channelId = notificationChannelId,
164
- channelName = notificationChannelName,
165
- channelDescription = notificationChannelDescription
166
- )
167
- }
168
-
169
- fun storeRunningState(running: Boolean) {
170
- sharedPreferences.edit().putBoolean(PROPERTY_STARTED, running).apply()
171
- }
172
-
173
- fun loadRunningState(): Boolean {
174
- return sharedPreferences.getBoolean(PROPERTY_STARTED, false)
24
+ // Migration part. We must remove token stored in shared prefs.
25
+ init {
26
+ if (sharedPreferences.contains(PROPERTY_PRODUCT_ID)) {
27
+ sharedPreferences.edit().remove(PROPERTY_PRODUCT_ID).apply()
28
+ }
29
+ if (sharedPreferences.contains(PROPERTY_USER_ID)) {
30
+ sharedPreferences.edit().remove(PROPERTY_USER_ID).apply()
31
+ }
32
+ if (sharedPreferences.contains(PROPERTY_ACCESS_TOKEN)) {
33
+ sharedPreferences.edit().remove(PROPERTY_ACCESS_TOKEN).apply()
34
+ }
35
+ if (sharedPreferences.contains(PROPERTY_REFRESH_TOKEN)) {
36
+ sharedPreferences.edit().remove(PROPERTY_REFRESH_TOKEN).apply()
37
+ }
175
38
  }
176
39
 
177
40
  fun clear() {
@@ -1,12 +1,15 @@
1
1
  package `in`.dolph.move.sdk
2
2
 
3
3
  import android.annotation.SuppressLint
4
+ import android.bluetooth.BluetoothManager
4
5
  import android.content.Context
6
+ import android.os.Build
5
7
  import android.util.Log
6
8
  import com.facebook.react.bridge.Promise
7
9
  import com.facebook.react.bridge.ReadableArray
8
10
  import com.facebook.react.bridge.ReadableMap
9
11
  import com.google.gson.Gson
12
+ import `in`.dolph.move.sdk.extentions.PermissionUtils
10
13
  import `in`.dolph.move.sdk.metadata.METADATA_PREF
11
14
  import `in`.dolph.move.sdk.metadata.MetadataStorage
12
15
  import `in`.dolph.move.sdk.metadata.MetadataStorageImpl
@@ -21,6 +24,7 @@ import io.dolphin.move.MoveConfig
21
24
  import io.dolphin.move.MoveConfigurationError
22
25
  import io.dolphin.move.MoveDetectionService
23
26
  import io.dolphin.move.MoveDevice
27
+ import io.dolphin.move.MoveNotification
24
28
  import io.dolphin.move.MoveOptions
25
29
  import io.dolphin.move.MoveScanResult
26
30
  import io.dolphin.move.MoveSdk
@@ -128,14 +132,8 @@ class NativeMoveSdkWrapper(private val context: Context) : MoveSdk.StateListener
128
132
  // Platform config
129
133
  recognitionNotificationTitle: String,
130
134
  recognitionNotificationText: String,
131
- recognitionNotificationChannelId: String,
132
- recognitionNotificationChannelName: String,
133
- recognitionNotificationChannelDescription: String,
134
135
  tripNotificationTitle: String,
135
136
  tripNotificationText: String,
136
- tripNotificationChannelId: String,
137
- tripNotificationChannelName: String,
138
- tripNotificationChannelDescription: String,
139
137
  promise: Promise?
140
138
  ) {
141
139
 
@@ -169,28 +167,6 @@ class NativeMoveSdkWrapper(private val context: Context) : MoveSdk.StateListener
169
167
  )
170
168
  )
171
169
  }
172
- // TODO there was a bug on building local npm, fix it and uncomment
173
- // val recognitionNotificationIcon = getIconIdByName(recognitionIconName)
174
- // val tripNotificationIcon = getIconIdByName(tripIconName)
175
-
176
- val recognitionNotification = MoveNotificationConfig(
177
- recognitionNotificationTitle,
178
- recognitionNotificationText,
179
- null,
180
- recognitionNotificationChannelId,
181
- recognitionNotificationChannelName,
182
- recognitionNotificationChannelDescription,
183
- )
184
- val tripNotification = MoveNotificationConfig(
185
- tripNotificationTitle,
186
- tripNotificationText,
187
- null,
188
- tripNotificationChannelId,
189
- tripNotificationChannelName,
190
- tripNotificationChannelDescription,
191
- )
192
- // TODO - just use recognition notification for now
193
- val walkingNotification = recognitionNotification
194
170
 
195
171
  val featureOptions = options?.toHashMap()
196
172
  val moveOptions = try {
@@ -229,11 +205,16 @@ class NativeMoveSdkWrapper(private val context: Context) : MoveSdk.StateListener
229
205
  refreshToken = refreshToken,
230
206
  projectId = projectId.toLong(),
231
207
  )
232
- MoveSdk.get()?.let {
233
- it.tripNotification(tripNotification.toMoveNotification(context))
234
- it.recognitionNotification(recognitionNotification.toMoveNotification(context))
235
- it.walkingLocationNotification(walkingNotification.toMoveNotification(context))
236
- }
208
+ MoveSdk.get()?.setNotificationText(
209
+ notification = MoveNotification(
210
+ recognitionTitle = recognitionNotificationTitle,
211
+ recognitionText = recognitionNotificationText,
212
+ drivingTitle = tripNotificationTitle,
213
+ drivingText = tripNotificationText,
214
+ walkingTitle = recognitionNotificationTitle,
215
+ walkingText = recognitionNotificationText
216
+ )
217
+ )
237
218
  val moveConfig = MoveConfig(timelineDetectionServicesToUse)
238
219
  MoveSdk.setup(
239
220
  auth = moveAuth,
@@ -241,15 +222,6 @@ class NativeMoveSdkWrapper(private val context: Context) : MoveSdk.StateListener
241
222
  options = moveOptions,
242
223
  )
243
224
 
244
- val moveSdkConfig = MoveSdkConfig(
245
- timelineDetectionServices = timelineDetectionServicesToUse,
246
- auth = moveAuth,
247
- recognitionNotification = recognitionNotification,
248
- tripNotification = tripNotification,
249
- walkingNotification = walkingNotification
250
- )
251
- configRepository.storeConfig(moveSdkConfig)
252
-
253
225
  promise?.resolve(PROMISE_OK)
254
226
  } catch (t: Throwable) {
255
227
  val message = "SETUP_ERROR: ${t.message}"
@@ -270,14 +242,8 @@ class NativeMoveSdkWrapper(private val context: Context) : MoveSdk.StateListener
270
242
  // Platform config
271
243
  recognitionNotificationTitle: String,
272
244
  recognitionNotificationText: String,
273
- recognitionNotificationChannelId: String,
274
- recognitionNotificationChannelName: String,
275
- recognitionNotificationChannelDescription: String,
276
245
  tripNotificationTitle: String,
277
246
  tripNotificationText: String,
278
- tripNotificationChannelId: String,
279
- tripNotificationChannelName: String,
280
- tripNotificationChannelDescription: String,
281
247
  promise: Promise?
282
248
  ) {
283
249
 
@@ -311,28 +277,6 @@ class NativeMoveSdkWrapper(private val context: Context) : MoveSdk.StateListener
311
277
  )
312
278
  )
313
279
  }
314
- // TODO there was a bug on building local npm, fix it and uncomment
315
- // val recognitionNotificationIcon = getIconIdByName(recognitionIconName)
316
- // val tripNotificationIcon = getIconIdByName(tripIconName)
317
-
318
- val recognitionNotification = MoveNotificationConfig(
319
- recognitionNotificationTitle,
320
- recognitionNotificationText,
321
- null,
322
- recognitionNotificationChannelId,
323
- recognitionNotificationChannelName,
324
- recognitionNotificationChannelDescription,
325
- )
326
- val tripNotification = MoveNotificationConfig(
327
- tripNotificationTitle,
328
- tripNotificationText,
329
- null,
330
- tripNotificationChannelId,
331
- tripNotificationChannelName,
332
- tripNotificationChannelDescription,
333
- )
334
- // TODO - just use recognition notification for now
335
- val walkingNotification = recognitionNotification
336
280
 
337
281
  val featureOptions = options?.toHashMap()
338
282
  val moveOptions = try {
@@ -365,11 +309,16 @@ class NativeMoveSdkWrapper(private val context: Context) : MoveSdk.StateListener
365
309
  try {
366
310
  Log.d(MoveSdkModule.LOG_TAG, "MOVE SDK Version " + MoveSdk.version)
367
311
 
368
- MoveSdk.get()?.let {
369
- it.tripNotification(tripNotification.toMoveNotification(context))
370
- it.recognitionNotification(recognitionNotification.toMoveNotification(context))
371
- it.walkingLocationNotification(walkingNotification.toMoveNotification(context))
372
- }
312
+ MoveSdk.get()?.setNotificationText(
313
+ notification = MoveNotification(
314
+ recognitionTitle = recognitionNotificationTitle,
315
+ recognitionText = recognitionNotificationText,
316
+ drivingTitle = tripNotificationTitle,
317
+ drivingText = tripNotificationText,
318
+ walkingTitle = recognitionNotificationTitle,
319
+ walkingText = recognitionNotificationText
320
+ )
321
+ )
373
322
  val moveConfig = MoveConfig(timelineDetectionServicesToUse)
374
323
  MoveSdk.setup(
375
324
  authCode = code,
@@ -400,12 +349,10 @@ class NativeMoveSdkWrapper(private val context: Context) : MoveSdk.StateListener
400
349
  }
401
350
 
402
351
  fun startAutomaticDetection(): Boolean {
403
- configRepository.storeRunningState(true)
404
352
  return MoveSdk.get()?.startAutomaticDetection() == true
405
353
  }
406
354
 
407
355
  fun stopAutomaticDetection(): Boolean {
408
- configRepository.storeRunningState(false)
409
356
  return MoveSdk.get()?.stopAutomaticDetection() == true
410
357
  }
411
358
 
@@ -521,17 +468,7 @@ class NativeMoveSdkWrapper(private val context: Context) : MoveSdk.StateListener
521
468
  data.putString(ARGUMENT_ERROR_REASON, state.reason.toString())
522
469
  }**/
523
470
  emitDeviceEvent(EVENT_MOVE_STATE, data)
524
-
525
- if (state is MoveSdkState.Ready) {
526
- val isInRunningState = configRepository.loadRunningState()
527
- if (isInRunningState) {
528
- startAutomaticDetection()
529
- }
530
- } else if (state is MoveSdkState.Running) {
531
- Log.d(MoveSdkModule.LOG_TAG, "Move SDK Running")
532
- // Nothing to do here, all good.
533
- // You may call additional features like #keepInForeground(bool)
534
- }
471
+ Log.d(MoveSdkModule.LOG_TAG, "Move SDK $state")
535
472
  }
536
473
 
537
474
  override fun onTripStateChanged(tripState: MoveTripState) {
@@ -557,8 +494,6 @@ class NativeMoveSdkWrapper(private val context: Context) : MoveSdk.StateListener
557
494
  refreshToken = refreshToken,
558
495
  )
559
496
 
560
- configRepository.storeAuth(auth)
561
-
562
497
  MoveSdk.get()?.updateAuth(auth) { configurationError ->
563
498
  val data = mutableMapOf<Any, Any>()
564
499
  data[ARGUMENT_ERROR] = configurationError.toString()
@@ -794,6 +729,31 @@ class NativeMoveSdkWrapper(private val context: Context) : MoveSdk.StateListener
794
729
  map["isConnected"] = device.isConnected
795
730
  emitDeviceEvent(EVENT_MOVE_SDK_DEVICE_STATE, map)
796
731
  }
732
+
733
+ fun isBluetoothEnabled(): Boolean {
734
+ val adapter = context.getSystemService(BluetoothManager::class.java)?.adapter
735
+ if (adapter == null) {
736
+ Log.i(MoveSdkModule.LOG_TAG, "BluetoothManager is missing or BT adapter is null")
737
+ }
738
+ return adapter?.isEnabled == true
739
+ }
740
+ fun hasDiscoveryPermissions(): Boolean {
741
+ var hasPermissions = true
742
+ val hasBluetoothScanPermission = PermissionUtils.hasBluetoothScanPermission(context)
743
+ Log.i(MoveSdkModule.LOG_TAG, "Discovery permission check: BluetoothScanPermission = $hasBluetoothScanPermission")
744
+ hasPermissions = hasPermissions && hasBluetoothScanPermission
745
+ if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
746
+ val hasFineLocationPermission = PermissionUtils.hasFineLocationPermission(context)
747
+ Log.i(MoveSdkModule.LOG_TAG, "Discovery permission check: FineLocationPermission = $hasFineLocationPermission")
748
+ hasPermissions = hasPermissions && hasFineLocationPermission
749
+ }
750
+ if (Build.VERSION.SDK_INT == Build.VERSION_CODES.R || Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
751
+ val hasBackgroundLocationPermission = PermissionUtils.hasBackgroundLocationPermission(context)
752
+ Log.i(MoveSdkModule.LOG_TAG, "Discovery permission check: BackgroundLocationPermission = $hasBackgroundLocationPermission")
753
+ hasPermissions = hasPermissions && hasBackgroundLocationPermission
754
+ }
755
+ return hasPermissions
756
+ }
797
757
  }
798
758
 
799
759
  fun List<MoveServiceFailure>.failuresToArray(): Array<Any> {
@@ -0,0 +1,58 @@
1
+ package `in`.dolph.move.sdk.extentions
2
+
3
+ import android.Manifest
4
+ import android.content.Context
5
+ import android.content.pm.PackageManager
6
+ import android.os.Build
7
+ import androidx.core.content.ContextCompat
8
+
9
+ object PermissionUtils {
10
+
11
+ fun hasFineLocationPermission(context: Context?): Boolean {
12
+ return if (context != null) {
13
+ ContextCompat.checkSelfPermission(
14
+ context,
15
+ Manifest.permission.ACCESS_FINE_LOCATION
16
+ ) == PackageManager.PERMISSION_GRANTED
17
+ } else {
18
+ false
19
+ }
20
+ }
21
+
22
+ fun hasBluetoothScanPermission(context: Context): Boolean {
23
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
24
+ ContextCompat.checkSelfPermission(
25
+ context,
26
+ Manifest.permission.BLUETOOTH_SCAN
27
+ ) == PackageManager.PERMISSION_GRANTED
28
+ } else {
29
+ true
30
+ }
31
+ }
32
+
33
+ fun hasBackgroundLocationPermission(context: Context?): Boolean {
34
+ return if (context != null) {
35
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
36
+ ContextCompat.checkSelfPermission(
37
+ context,
38
+ Manifest.permission.ACCESS_BACKGROUND_LOCATION
39
+ ) == PackageManager.PERMISSION_GRANTED
40
+ } else {
41
+ true
42
+ }
43
+ } else {
44
+ false
45
+ }
46
+ }
47
+
48
+ fun hasBluetoothConnectPermission(context: Context): Boolean {
49
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
50
+ ContextCompat.checkSelfPermission(
51
+ context,
52
+ Manifest.permission.BLUETOOTH_CONNECT
53
+ ) == PackageManager.PERMISSION_GRANTED
54
+ } else {
55
+ true
56
+ }
57
+ }
58
+ }
@@ -134,4 +134,10 @@ RCT_EXTERN_METHOD(requestMotionPermission)
134
134
 
135
135
  RCT_EXTERN_METHOD(requestBluetoothAlwaysUsagePermission)
136
136
 
137
+ RCT_EXTERN_METHOD(getBluetoothPermission: (RCTPromiseResolveBlock)resolve
138
+ rejecter: (RCTPromiseRejectBlock)reject)
139
+
140
+ RCT_EXTERN_METHOD(getBluetoothState: (RCTPromiseResolveBlock)resolve
141
+ rejecter: (RCTPromiseRejectBlock)reject)
142
+
137
143
  @end