react-native-move-sdk 2.10.0 → 2.10.2

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.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2022 Dolphin Technologies
3
+ Copyright (c) 2024 Dolphin Technologies
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -14,7 +14,7 @@ copies or substantial portions of the Software.
14
14
 
15
15
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
16
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
18
18
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # react-native-move-sdk
2
2
 
3
- React Native library for MOVE SDK - please see https://docs.movesdk.com/move/ for features and details about the MOVE SDK.
3
+ React Native library for MOVE SDK - please see https://docs.movesdk.com/move-platform for features and details about the MOVE SDK.
4
4
 
5
5
  ## Installation
6
6
 
@@ -61,7 +61,7 @@ public class MainApplication extends Application implements ReactApplication {
61
61
 
62
62
  ## Usage
63
63
 
64
- See https://docs.movesdk.com/move/sdk-1/api-interface/react-native/intialization
64
+ See https://docs.movesdk.com/move-platform/sdk/api-interface/react-native/intialization
65
65
 
66
66
  ```js
67
67
  import MoveSdk from 'react-native-move-sdk';
@@ -107,7 +107,7 @@ MoveSdk.setup(CONFIG, auth, ANDROID_CONFIG)
107
107
 
108
108
  # Methods
109
109
 
110
- See: https://docs.movesdk.com/move/sdk-1/api-interface/react-native/services
110
+ See: https://docs.movesdk.com/move-platform/sdk/api-interface/react-native/services
111
111
 
112
112
  Required permissions description ios and android...
113
113
 
@@ -151,6 +151,9 @@ MoveSdk.addErrorsListener((errors: ErrorListType) => {
151
151
  ...
152
152
  });
153
153
 
154
+ MoveSdk.addLogListener((log: MoveSdkLog) => {
155
+ ...
156
+ });
154
157
  ```
155
158
 
156
159
  ## License
@@ -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
@@ -42,6 +43,7 @@ internal const val EVENT_MOVE_SDK_APP = "MOVE_SDK_APP_EVENT"
42
43
  internal const val EVENT_MOVE_CONFIG_UPDATE = "MOVE_SDK_CONFIG_UPDATE"
43
44
  internal const val EVENT_MOVE_SDK_TRIP_START = "MOVE_SDK_TRIP_START"
44
45
  internal const val EVENT_MOVE_SDK_DEVICE_STATE = "MOVE_SDK_DEVICE_STATE"
46
+ internal const val EVENT_MOVE_SDK_LOG = "MOVE_SDK_LOG"
45
47
 
46
48
  internal const val ARGUMENT_ACCESS_TOKEN = "accessToken"
47
49
  internal const val ARGUMENT_REFRESH_TOKEN = "refreshToken"
@@ -104,14 +106,8 @@ class MoveSdkModule(context: ReactApplicationContext) : ReactContextBaseJavaModu
104
106
  // Platform config
105
107
  recognitionNotificationTitle: String,
106
108
  recognitionNotificationText: String,
107
- recognitionNotificationChannelId: String,
108
- recognitionNotificationChannelName: String,
109
- recognitionNotificationChannelDescription: String,
110
109
  tripNotificationTitle: String,
111
110
  tripNotificationText: String,
112
- tripNotificationChannelId: String,
113
- tripNotificationChannelName: String,
114
- tripNotificationChannelDescription: String,
115
111
  promise: Promise?
116
112
  ) {
117
113
  nativeSdkWrapper.setup(
@@ -127,14 +123,8 @@ class MoveSdkModule(context: ReactApplicationContext) : ReactContextBaseJavaModu
127
123
  // Platform config
128
124
  recognitionNotificationTitle,
129
125
  recognitionNotificationText,
130
- recognitionNotificationChannelId,
131
- recognitionNotificationChannelName,
132
- recognitionNotificationChannelDescription,
133
126
  tripNotificationTitle,
134
127
  tripNotificationText,
135
- tripNotificationChannelId,
136
- tripNotificationChannelName,
137
- tripNotificationChannelDescription,
138
128
  promise = promise
139
129
  )
140
130
  }
@@ -150,14 +140,8 @@ class MoveSdkModule(context: ReactApplicationContext) : ReactContextBaseJavaModu
150
140
  // Platform config
151
141
  recognitionNotificationTitle: String,
152
142
  recognitionNotificationText: String,
153
- recognitionNotificationChannelId: String,
154
- recognitionNotificationChannelName: String,
155
- recognitionNotificationChannelDescription: String,
156
143
  tripNotificationTitle: String,
157
144
  tripNotificationText: String,
158
- tripNotificationChannelId: String,
159
- tripNotificationChannelName: String,
160
- tripNotificationChannelDescription: String,
161
145
  promise: Promise?
162
146
  ) {
163
147
  nativeSdkWrapper.setup(
@@ -170,14 +154,8 @@ class MoveSdkModule(context: ReactApplicationContext) : ReactContextBaseJavaModu
170
154
  // Platform config
171
155
  recognitionNotificationTitle,
172
156
  recognitionNotificationText,
173
- recognitionNotificationChannelId,
174
- recognitionNotificationChannelName,
175
- recognitionNotificationChannelDescription,
176
157
  tripNotificationTitle,
177
158
  tripNotificationText,
178
- tripNotificationChannelId,
179
- tripNotificationChannelName,
180
- tripNotificationChannelDescription,
181
159
  promise = promise
182
160
  )
183
161
  }
@@ -199,20 +177,12 @@ class MoveSdkModule(context: ReactApplicationContext) : ReactContextBaseJavaModu
199
177
 
200
178
  @ReactMethod
201
179
  fun startAutomaticDetection(promise: Promise?) {
202
- if (nativeSdkWrapper.startAutomaticDetection()) {
203
- promise?.resolve(true)
204
- } else {
205
- promise?.reject(Throwable())
206
- }
180
+ promise?.resolve(nativeSdkWrapper.startAutomaticDetection())
207
181
  }
208
182
 
209
183
  @ReactMethod
210
184
  fun stopAutomaticDetection(promise: Promise?) {
211
- if (nativeSdkWrapper.stopAutomaticDetection()) {
212
- promise?.resolve(true)
213
- } else {
214
- promise?.reject(Throwable())
215
- }
185
+ promise?.resolve(nativeSdkWrapper.stopAutomaticDetection())
216
186
  }
217
187
 
218
188
  @ReactMethod
@@ -447,11 +417,7 @@ class MoveSdkModule(context: ReactApplicationContext) : ReactContextBaseJavaModu
447
417
  @ReactMethod
448
418
  fun startTrip(metadata: ReadableMap?, promise: Promise?) {
449
419
  val metadataMap = metadata?.toHashMap()?.mapValues { it.value.toString() }
450
- if (MoveSdk.get()?.startTrip(metadataMap) == true) {
451
- promise?.resolve(true)
452
- } else {
453
- promise?.reject(Throwable("Can't start manual trip"))
454
- }
420
+ promise?.resolve(MoveSdk.get()?.startTrip(metadataMap) == true)
455
421
  }
456
422
 
457
423
  @ReactMethod
@@ -482,6 +448,16 @@ class MoveSdkModule(context: ReactApplicationContext) : ReactContextBaseJavaModu
482
448
  }
483
449
  }
484
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
+
485
461
  // region PERMISSIONS MODULE
486
462
  @SuppressLint("NewApi")
487
463
  override fun onActivityResult(
@@ -503,14 +479,9 @@ class MoveSdkModule(context: ReactApplicationContext) : ReactContextBaseJavaModu
503
479
 
504
480
  @ReactMethod
505
481
  fun canDrawOverlays(promise: Promise) {
506
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
507
- promise.resolve(Settings.canDrawOverlays(reactContext))
508
- } else {
509
- promise.resolve(true)
510
- }
482
+ promise.resolve(Settings.canDrawOverlays(reactContext))
511
483
  }
512
484
 
513
- @RequiresApi(Build.VERSION_CODES.M)
514
485
  @ReactMethod
515
486
  fun requestDrawOverlaysPermission() {
516
487
  val intent = Intent(
@@ -523,12 +494,7 @@ class MoveSdkModule(context: ReactApplicationContext) : ReactContextBaseJavaModu
523
494
  private fun isAppIgnoringBatteryOptimization(): Boolean {
524
495
  val packageName = reactContext.packageName
525
496
  val pm: PowerManager = reactContext.getSystemService(Context.POWER_SERVICE) as PowerManager
526
-
527
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
528
- return pm.isIgnoringBatteryOptimizations(packageName)
529
- } else {
530
- return true
531
- }
497
+ return pm.isIgnoringBatteryOptimizations(packageName)
532
498
  }
533
499
 
534
500
  @ReactMethod
@@ -537,7 +503,6 @@ class MoveSdkModule(context: ReactApplicationContext) : ReactContextBaseJavaModu
537
503
  }
538
504
 
539
505
  @SuppressLint("BatteryLife")
540
- @RequiresApi(Build.VERSION_CODES.M)
541
506
  @ReactMethod
542
507
  fun requestAppIgnoringBatteryOptimization() {
543
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() {