Asset Tracking Extended

SDK, users can do asset creation and binding, switch between different tracking modes, and receive callbacks for the data tracking.

This detailed example walks you through the following steps:

  • Creating a New Asset Based on User Input: Learn how to generate a new asset within your application, leveraging user input to create assets dynamically.

  • Binding User-Created Asset IDs to the Current Device: Discover the process of associating user-generated asset IDs with the device you're currently using, facilitating tracking and management of these assets.

  • Starting and Stopping Tracking Based on User Operations: Gain insights into initiating and halting tracking operations, giving users control over the tracking process.

  • Switching Between Tracking Modes Based on User Operations: Learn how to transition between different tracking modes, providing flexibility and adaptability to user preferences.

  • Receiving AssetTrackingCallbacks and Displaying Results in the User Interface: Explore how to handle AssetTrackingCallbacks and effectively communicate tracking results to the user interface, ensuring a seamless and informative user experience.

For all code examples, refer to Asset Tracking Android Code Examples

activity_set_profile.xml view source

1
<?xml version="1.0" encoding="utf-8"?>
2
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
xmlns:tools="http://schemas.android.com/tools"
4
android:layout_width="match_parent"
5
android:layout_height="match_parent"
6
tools:context=".SetProfileActivity">
7
8
<ScrollView
9
android:layout_width="match_parent"
10
android:layout_height="wrap_content">
11
12
<LinearLayout
13
android:layout_width="match_parent"
14
android:layout_height="wrap_content"
15
android:orientation="vertical"
16
android:paddingStart="20dp"
17
android:paddingEnd="20dp"
18
android:paddingBottom="20dp">
19
20
<TextView
21
android:layout_width="wrap_content"
22
android:layout_height="wrap_content"
23
android:layout_marginTop="50dp"
24
android:text="@string/custom_id"
25
android:textColor="@color/text_color_primary"
26
android:textSize="15sp"
27
android:textStyle="bold" />
28
29
<EditText
30
android:id="@+id/edit_custom_id"
31
android:layout_width="match_parent"
32
android:layout_height="40dp"
33
android:layout_marginTop="6dp"
34
android:height="40dp"
35
android:background="@drawable/selector_edit_text_bg"
36
android:hint="@string/enter_custom_id"
37
android:inputType="text"
38
android:lines="1"
39
android:paddingStart="10dp"
40
android:paddingEnd="10dp"
41
android:textAlignment="viewStart"
42
android:textColor="@color/text_color_primary"
43
android:textColorHint="@color/md_grey_400"
44
android:textCursorDrawable="@drawable/shape_cursor_color"
45
android:textSize="15sp"
46
tools:ignore="Autofill" />
47
48
49
<TextView
50
android:layout_width="wrap_content"
51
android:layout_height="wrap_content"
52
android:layout_marginTop="40dp"
53
android:text="@string/asset_name"
54
android:textColor="@color/text_color_primary"
55
android:textSize="15sp"
56
android:textStyle="bold" />
57
58
<EditText
59
android:id="@+id/edit_asset_name"
60
android:layout_width="match_parent"
61
android:layout_height="40dp"
62
android:layout_marginTop="6dp"
63
android:background="@drawable/selector_edit_text_bg"
64
android:hint="@string/enter_asset_name"
65
android:inputType="text"
66
android:lines="1"
67
android:paddingStart="10dp"
68
android:paddingEnd="10dp"
69
android:textAlignment="viewStart"
70
android:textColor="@color/text_color_primary"
71
android:textColorHint="@color/md_grey_400"
72
android:textCursorDrawable="@drawable/shape_cursor_color"
73
android:textSize="15sp"
74
tools:ignore="Autofill,TextFields" />
75
76
<TextView
77
android:layout_width="wrap_content"
78
android:layout_height="wrap_content"
79
android:layout_marginTop="40dp"
80
android:text="@string/asset_description"
81
android:textColor="@color/text_color_primary"
82
android:textSize="15sp"
83
android:textStyle="bold" />
84
85
<EditText
86
android:id="@+id/edit_asset_description"
87
android:layout_width="match_parent"
88
android:layout_height="40dp"
89
android:layout_marginTop="6dp"
90
android:background="@drawable/selector_edit_text_bg"
91
android:hint="@string/enter_asset_description"
92
android:inputType="text"
93
android:lines="1"
94
android:paddingStart="10dp"
95
android:paddingEnd="10dp"
96
android:textAlignment="viewStart"
97
android:textColor="@color/text_color_primary"
98
android:textColorHint="@color/md_grey_400"
99
android:textCursorDrawable="@drawable/shape_cursor_color"
100
android:textSize="15sp"
101
tools:ignore="Autofill,TextFields" />
102
103
<TextView
104
android:layout_width="wrap_content"
105
android:layout_height="wrap_content"
106
android:layout_marginTop="40dp"
107
android:text="@string/asset_attributes"
108
android:textColor="@color/text_color_primary"
109
android:textSize="15sp"
110
android:textStyle="bold" />
111
112
<EditText
113
android:id="@+id/edit_asset_attributes"
114
android:layout_width="match_parent"
115
android:layout_height="40dp"
116
android:layout_marginTop="6dp"
117
android:background="@drawable/selector_edit_text_bg"
118
android:hint="@string/enter_asset_attributes"
119
android:inputType="text"
120
android:lines="1"
121
android:paddingStart="10dp"
122
android:paddingEnd="10dp"
123
android:textAlignment="viewStart"
124
android:textColor="@color/text_color_primary"
125
android:textColorHint="@color/md_grey_400"
126
android:textCursorDrawable="@drawable/shape_cursor_color"
127
android:textSize="15sp"
128
tools:ignore="Autofill,TextFields" />
129
130
<TextView
131
android:id="@+id/create_new_asset"
132
android:layout_width="match_parent"
133
android:layout_height="wrap_content"
134
android:layout_gravity="bottom|center_horizontal"
135
android:layout_marginTop="50dp"
136
android:background="@drawable/route_nav_bg"
137
android:gravity="center"
138
android:paddingTop="15dp"
139
android:paddingBottom="15dp"
140
android:text="@string/create_asset"
141
android:textColor="@color/white"
142
android:textSize="15sp"
143
android:textStyle="bold" />
144
145
<TextView
146
android:layout_width="wrap_content"
147
android:layout_height="wrap_content"
148
android:layout_marginTop="40dp"
149
android:text="@string/asset_id"
150
android:textColor="@color/text_color_primary"
151
android:textSize="15sp"
152
android:textStyle="bold" />
153
154
<EditText
155
android:id="@+id/edit_asset_id"
156
android:layout_width="match_parent"
157
android:layout_height="40dp"
158
android:layout_marginTop="6dp"
159
android:background="@drawable/selector_edit_text_bg"
160
android:hint="@string/enter_asset_id"
161
android:inputType="text"
162
android:lines="1"
163
android:paddingStart="10dp"
164
android:paddingEnd="10dp"
165
android:textAlignment="viewStart"
166
android:textColor="@color/text_color_primary"
167
android:textColorHint="@color/md_grey_400"
168
android:textCursorDrawable="@drawable/shape_cursor_color"
169
android:textSize="15sp"
170
tools:ignore="Autofill,TextFields" />
171
172
<TextView
173
android:id="@+id/bind_asset"
174
android:layout_width="match_parent"
175
android:layout_height="wrap_content"
176
android:layout_gravity="bottom|center_horizontal"
177
android:layout_marginTop="20dp"
178
android:background="@drawable/dialog_radius_5_415e_bg"
179
android:gravity="center"
180
android:paddingTop="15dp"
181
android:paddingBottom="15dp"
182
android:text="@string/bind_asset"
183
android:textColor="@color/colorPrimary"
184
android:textSize="15sp"
185
android:textStyle="bold" />
186
187
<TextView
188
android:layout_width="wrap_content"
189
android:layout_height="wrap_content"
190
android:layout_marginTop="40dp"
191
android:text="@string/your_asset_id"
192
android:textColor="@color/text_color_primary"
193
android:textSize="15sp"
194
android:textStyle="bold" />
195
196
<EditText
197
android:id="@+id/last_used_asset_id"
198
android:layout_width="match_parent"
199
android:layout_height="40dp"
200
android:layout_marginTop="6dp"
201
android:layout_marginBottom="50dp"
202
android:height="40dp"
203
android:background="@drawable/selector_edit_text_bg"
204
android:hint="@string/display_asset_id"
205
android:inputType="none"
206
android:lines="1"
207
android:paddingStart="10dp"
208
android:paddingEnd="10dp"
209
android:textAlignment="viewStart"
210
android:textColor="@color/text_color_primary"
211
android:textColorHint="@color/md_grey_400"
212
android:textCursorDrawable="@drawable/shape_cursor_color"
213
android:textIsSelectable="true"
214
android:textSize="15sp"
215
tools:ignore="Autofill" />
216
217
</LinearLayout>
218
</ScrollView>
219
220
<ProgressBar
221
android:id="@+id/saving_progress"
222
android:layout_width="80dp"
223
android:layout_height="80dp"
224
android:layout_gravity="center"
225
android:visibility="gone" />
226
227
</FrameLayout>

activity_extended_tracking.xml view source

1
<?xml version="1.0" encoding="utf-8"?>
2
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
xmlns:app="http://schemas.android.com/apk/res-auto"
4
xmlns:tools="http://schemas.android.com/tools"
5
android:layout_width="match_parent"
6
android:layout_height="match_parent"
7
android:orientation="vertical"
8
android:padding="10dp"
9
tools:context=".MainActivity">
10
11
<LinearLayout
12
android:layout_width="wrap_content"
13
android:layout_height="wrap_content">
14
<Button
15
android:id="@+id/start_tracking"
16
android:layout_width="wrap_content"
17
android:layout_height="wrap_content"
18
android:text="@string/start_tracking"
19
/>
20
21
<Button
22
android:id="@+id/stop_tracking"
23
android:layout_width="wrap_content"
24
android:layout_height="wrap_content"
25
android:layout_marginLeft="10dp"
26
android:text="@string/stop_tracking"
27
/>
28
29
</LinearLayout>
30
31
<RadioGroup
32
android:id="@+id/radioGroup"
33
android:layout_width="wrap_content"
34
android:layout_height="wrap_content"
35
>
36
37
<RadioButton
38
android:id="@+id/radioButtonActive"
39
android:layout_width="wrap_content"
40
android:layout_height="wrap_content"
41
android:text="TRACKING_MODE_ACTIVE" />
42
43
<RadioButton
44
android:id="@+id/radioButtonBalanced"
45
android:layout_width="wrap_content"
46
android:layout_height="wrap_content"
47
android:text="TRACKING_MODE_BALANCED" />
48
49
<RadioButton
50
android:id="@+id/radioButtonPassive"
51
android:layout_width="wrap_content"
52
android:layout_height="wrap_content"
53
android:text="TRACKING_MODE_PASSIVE" />
54
55
</RadioGroup>
56
57
<TextView
58
android:id="@+id/isStopTracking"
59
android:layout_marginTop="10dp"
60
android:layout_width="wrap_content"
61
android:layout_height="wrap_content"/>
62
63
64
<TextView
65
android:id="@+id/locationEngineInfo"
66
android:layout_marginTop="20dp"
67
android:layout_width="wrap_content"
68
android:layout_height="wrap_content"/>
69
70
<TextView
71
android:id="@+id/locationInfo"
72
android:layout_marginTop="20dp"
73
android:layout_width="wrap_content"
74
android:layout_height="wrap_content"/>
75
76
77
<TextView
78
android:id="@+id/edit_asset_profile"
79
android:layout_width="match_parent"
80
android:layout_height="wrap_content"
81
android:layout_gravity="bottom|center_horizontal"
82
android:layout_marginTop="50dp"
83
android:background="@drawable/route_nav_bg"
84
android:gravity="center"
85
android:paddingTop="15dp"
86
android:paddingBottom="15dp"
87
android:text="@string/create_asset"
88
android:textColor="@color/white"
89
android:textSize="15sp"
90
android:textStyle="bold" />
91
92
</LinearLayout>

SetProfileActivity view source

1
class SetProfileActivity : AppCompatActivity() {
2
private lateinit var sharedPreferences: SharedPreferences
3
private lateinit var editIdView: EditText
4
private lateinit var editAssetNameView: EditText
5
private lateinit var editDescriptionView: EditText
6
private lateinit var editAttributesView: EditText
7
private lateinit var editAssetIdView: EditText
8
private lateinit var lastAssetIdView: EditText
9
10
private lateinit var createNewAssetView: TextView
11
private lateinit var bindAssetView: TextView
12
private lateinit var progressBar: View
13
14
private lateinit var customId: String
15
private lateinit var assetName: String
16
private lateinit var assetDescription: String
17
private lateinit var assetAttributes: String
18
private lateinit var assetId: String
19
20
private var isSplash = true
21
22
override fun onCreate(savedInstanceState: Bundle?) {
23
super.onCreate(savedInstanceState)
24
setContentView(R.layout.activity_set_profile)
25
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
26
isSplash = intent.getBooleanExtra(Constants.IS_SPLASH_PAGE_KEY, true)
27
setActivityView()
28
initViewText()
29
setListeners()
30
checkAssetId()
31
}
32
33
private fun setActivityView() {
34
editIdView = findViewById(R.id.edit_custom_id)
35
editAssetNameView = findViewById(R.id.edit_asset_name)
36
editDescriptionView = findViewById(R.id.edit_asset_description)
37
editAttributesView = findViewById(R.id.edit_asset_attributes)
38
editAssetIdView = findViewById(R.id.edit_asset_id)
39
lastAssetIdView = findViewById(R.id.last_used_asset_id)
40
41
createNewAssetView = findViewById(R.id.create_new_asset)
42
bindAssetView = findViewById(R.id.bind_asset)
43
44
progressBar = findViewById(R.id.saving_progress)
45
}
46
47
private fun initViewText() {
48
customId =
49
sharedPreferences.getString(Constants.CUSTOM_ID_KEY, UUID.randomUUID().toString())
50
.toString()
51
52
assetName = sharedPreferences.getString(
53
Constants.ASSET_NAME_KEY,
54
getString(R.string.asset_name_example_value)
55
) as String
56
57
assetDescription = sharedPreferences.getString(
58
Constants.ASSET_DESCRIPTION_KEY,
59
getString(R.string.asset_description_example_value)
60
) as String
61
62
assetAttributes = sharedPreferences.getString(
63
Constants.ASSET_ATTRIBUTES_KEY,
64
getString(R.string.asset_attribute_example_value)
65
) as String
66
67
assetId = sharedPreferences.getString(Constants.ASSET_ID_KEY, "") as String
68
69
val lastAssetId = sharedPreferences.getString(Constants.LAST_ASSET_ID_KEY, "") as String
70
71
editIdView.setText(customId)
72
editAssetNameView.setText(assetName)
73
editDescriptionView.setText(assetDescription)
74
editAttributesView.setText(assetAttributes)
75
lastAssetIdView.setText(lastAssetId)
76
lastAssetIdView.inputType = InputType.TYPE_NULL
77
78
if (!assetId.isNullOrEmpty()) {
79
editAssetIdView.setText(assetId)
80
}
81
}
82
83
private fun hideKeyboard() {
84
this.currentFocus?.let { view ->
85
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
86
imm?.hideSoftInputFromWindow(view.windowToken, 0)
87
}
88
}
89
90
private fun setListeners() {
91
createNewAssetView.setOnClickListener {
92
readAssetInfoFromView()
93
if (!checkUserInput()) {
94
return@setOnClickListener
95
}
96
97
if (assetTrackingIsRunning) {
98
Toast.makeText(
99
this@SetProfileActivity,
100
"Asset tracking is ON, please turn off tracking before creating new asset!",
101
Toast.LENGTH_LONG
102
).show()
103
return@setOnClickListener
104
}
105
106
hideKeyboard()
107
progressBar.visibility = View.VISIBLE
108
109
AssetTracking.instance.createNewAsset(
110
AssetProfile.Builder().setCustomId(customId).setName(assetName)
111
.setDescription(assetDescription).setAttributes(
112
mapOf("test attribute" to assetAttributes)
113
).build(), object : AssetApiCallback<AssetCreationResponse> {
114
override fun onSuccess(result: AssetCreationResponse) {
115
progressBar.visibility = View.GONE
116
assetId = result.data.id
117
editAssetIdView.setText(assetId)
118
saveToSharedPreference()
119
}
120
121
override fun onFailure(exception: Exception) {
122
progressBar.visibility = View.GONE
123
Toast.makeText(
124
this@SetProfileActivity,
125
"create asset failed: " + exception.message,
126
Toast.LENGTH_LONG
127
).show()
128
}
129
}
130
)
131
132
}
133
134
bindAssetView.setOnClickListener {
135
assetId = editAssetIdView.text.toString().trim()
136
137
if (assetId.isEmpty()) {
138
return@setOnClickListener
139
}
140
hideKeyboard()
141
progressBar.visibility = View.VISIBLE
142
143
AssetTracking.instance.bindAsset(
144
this@SetProfileActivity,
145
assetId,
146
object : AssetApiCallback<Unit> {
147
override fun onSuccess(result: Unit) {
148
progressBar.visibility = View.GONE
149
150
Toast.makeText(
151
this@SetProfileActivity,
152
String.format(
153
"bind asset successfully with assetId: %s",
154
assetId
155
),
156
Toast.LENGTH_LONG
157
).show()
158
159
sharedPreferences.edit().putString(Constants.LAST_ASSET_ID_KEY, assetId).apply()
160
161
if (isSplash) {
162
launchMainActivity()
163
} else {
164
finish()
165
}
166
}
167
168
override fun onFailure(exception: Exception) {
169
progressBar.visibility = View.GONE
170
171
val exceptionMessage = exception.message ?: ""
172
173
if (exceptionMessage.contains(AssetTrackingApiExceptionType.UN_UPLOADED_LOCATION_DATA.exceptionString)) {
174
showForceBindDialog(assetId, exceptionMessage)
175
} else {
176
Toast.makeText(
177
this@SetProfileActivity,
178
"bind asset failed: $exceptionMessage",
179
Toast.LENGTH_LONG
180
).show()
181
}
182
}
183
})
184
}
185
}
186
187
private fun showForceBindDialog(assetId: String, warningMessage: String) {
188
val alertDialogBuilder = AlertDialog.Builder(this)
189
190
alertDialogBuilder.setMessage("$warningMessage, do you want to clear local data and force bind to new asset id?")
191
192
alertDialogBuilder.setPositiveButton("Proceed") { dialogInterface: DialogInterface, _: Int ->
193
dialogInterface.dismiss() // Close the dialog
194
progressBar.visibility = View.VISIBLE
195
196
AssetTracking.instance.forceBindAsset(this, assetId, object : AssetApiCallback<Unit> {
197
override fun onSuccess(result: Unit) {
198
progressBar.visibility = View.GONE
199
200
Toast.makeText(
201
this@SetProfileActivity,
202
String.format(
203
"Force bind new asset successfully with assetId: %s",
204
assetId
205
),
206
Toast.LENGTH_LONG
207
).show()
208
209
sharedPreferences.edit().putString(Constants.LAST_ASSET_ID_KEY, assetId).apply()
210
211
if (isSplash) {
212
launchMainActivity()
213
} else {
214
finish()
215
}
216
}
217
218
override fun onFailure(exception: Exception) {
219
progressBar.visibility = View.GONE
220
221
Toast.makeText(
222
this@SetProfileActivity,
223
"bind asset failed: " + exception.message,
224
Toast.LENGTH_LONG
225
).show()
226
}
227
})
228
}
229
230
alertDialogBuilder.setNegativeButton("Cancel") { dialogInterface: DialogInterface, _: Int ->
231
dialogInterface.dismiss() // Close the dialog
232
}
233
234
val alertDialog = alertDialogBuilder.create()
235
alertDialog.show()
236
}
237
238
private fun readAssetInfoFromView() {
239
customId = editIdView.text.toString().trim()
240
assetName = editAssetNameView.text.toString().trim()
241
assetDescription = editDescriptionView.text.toString().trim()
242
assetAttributes = editAttributesView.text.toString().trim()
243
}
244
245
private fun saveToSharedPreference() {
246
sharedPreferences.edit().putString(Constants.CUSTOM_ID_KEY, customId).apply()
247
sharedPreferences.edit().putString(Constants.ASSET_NAME_KEY, assetName).apply()
248
sharedPreferences.edit().putString(Constants.ASSET_DESCRIPTION_KEY, assetDescription)
249
.apply()
250
sharedPreferences.edit().putString(Constants.ASSET_ATTRIBUTES_KEY, assetAttributes).apply()
251
sharedPreferences.edit()
252
.putString(Constants.ASSET_ID_KEY, assetId)
253
.apply()
254
}
255
256
private fun checkAssetId() {
257
if (isSplash && !TextUtils.isEmpty(assetId)) {
258
launchMainActivity()
259
}
260
}
261
262
private fun launchMainActivity() {
263
startActivity(Intent(this, ExtendedTrackingActivity::class.java))
264
finish()
265
}
266
267
private fun checkUserInput(): Boolean {
268
if (assetName.isEmpty()) {
269
Toast.makeText(this, R.string.please_enter_name, Toast.LENGTH_SHORT).show()
270
return false
271
}
272
return true
273
}
274
}

ExtendedTrackingActivity view source

1
class ExtendedTrackingActivity : AppCompatActivity(), View.OnClickListener,
2
AssetTrackingCallBack {
3
private lateinit var startTrackingButton: Button
4
private lateinit var stopTrackingButton: Button
5
private lateinit var radioGroup: RadioGroup
6
private lateinit var activeRadioButton: RadioButton
7
private lateinit var trackingStatusView: TextView
8
private lateinit var locationEngineInfoView: TextView
9
private lateinit var locationInfoView: TextView
10
private lateinit var editAssetProfileView: TextView
11
12
13
var permissionsManager: LocationPermissionsManager? = null
14
var currentSelectedTrackingMode = TrackingMode.ACTIVE
15
16
private val mainHandler by lazy {
17
Handler(Looper.getMainLooper())
18
}
19
20
override fun onCreate(savedInstanceState: Bundle?) {
21
super.onCreate(savedInstanceState)
22
setContentView(R.layout.activity_extended_tracking)
23
// custom location engine
24
// TrackingSDK.setLocationEngine(CustomLocationEngine());
25
initialize("PUT YOUR API KEY HERE")
26
27
initView()
28
29
assetTrackingAddCallback(this)
30
bindExistingAsset()
31
}
32
33
private fun bindExistingAsset() {
34
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
35
val assetId = sharedPreferences.getString(Constants.LAST_ASSET_ID_KEY, "") as String
36
if (assetId.isNotEmpty()) {
37
AssetTracking.instance.bindAsset(
38
this@ExtendedTrackingActivity,
39
assetId,
40
object : AssetApiCallback<Unit> {
41
override fun onSuccess(result: Unit) {
42
Toast.makeText(
43
this@ExtendedTrackingActivity,
44
String.format(
45
"bind asset successfully with assetId: %s",
46
assetId
47
),
48
Toast.LENGTH_LONG
49
).show()
50
}
51
52
override fun onFailure(exception: Exception) {
53
Toast.makeText(
54
this@ExtendedTrackingActivity,
55
"bind asset failed: " + exception.message,
56
Toast.LENGTH_LONG
57
).show()
58
}
59
60
}
61
)
62
}
63
}
64
65
override fun onDestroy() {
66
super.onDestroy()
67
68
assetTrackingRemoveCallback(this)
69
}
70
71
private fun initView() {
72
startTrackingButton = findViewById(R.id.start_tracking)
73
stopTrackingButton = findViewById(R.id.stop_tracking)
74
startTrackingButton.setOnClickListener(this)
75
stopTrackingButton.setOnClickListener(this)
76
77
activeRadioButton = findViewById(R.id.radioButtonActive)
78
activeRadioButton.isChecked = true
79
80
radioGroup = findViewById(R.id.radioGroup)
81
radioGroup.setOnCheckedChangeListener { group, checkedId ->
82
currentSelectedTrackingMode = enumValues<TrackingMode>().find {
83
it.value == group.indexOfChild(group.findViewById(checkedId))
84
}!!
85
AssetTracking.instance.updateLocationConfig(this, LocationConfig(currentSelectedTrackingMode))
86
}
87
88
editAssetProfileView = findViewById(R.id.edit_asset_profile)
89
editAssetProfileView.setOnClickListener {
90
if (AssetTracking.instance.isRunning(this)) {
91
Toast.makeText(this, "please stop tracking before editing asset profile", Toast.LENGTH_LONG).show()
92
return@setOnClickListener
93
}
94
95
val intent = Intent(this@ExtendedTrackingActivity, SetProfileActivity::class.java)
96
intent.putExtra(Constants.IS_SPLASH_PAGE_KEY, false)
97
startActivity(intent)
98
}
99
100
trackingStatusView = findViewById(R.id.isStopTracking)
101
locationEngineInfoView = findViewById(R.id.locationEngineInfo)
102
locationInfoView = findViewById(R.id.locationInfo)
103
}
104
105
@SuppressLint("SetTextI18n")
106
override fun onClick(view: View) {
107
if (view.id == R.id.start_tracking) {
108
checkPermissionsAndStartTracking()
109
} else if (view.id == R.id.stop_tracking) {
110
// TrackingSDK.stopTracking()
111
assetTrackingStop()
112
updateTrackingStatus()
113
}
114
}
115
116
@SuppressLint("SetTextI18n")
117
private fun updateTrackingStatus() {
118
Log.d("asset", "updateTrackingStatus")
119
mainHandler.postDelayed({
120
val isTrackingOn = AssetTracking.instance.isRunning(this)
121
trackingStatusView.text = "Tracking Status: " + if (isTrackingOn) "ON" else "OFF"
122
if (!isTrackingOn) {
123
locationInfoView.text = ""
124
locationEngineInfoView.text = ""
125
}
126
}, 1000)
127
128
}
129
130
@SuppressLint(*["SetTextI18n", "MissingPermission"])
131
fun startTracking() {
132
assetTrackingStart()
133
updateTrackingStatus()
134
}
135
136
137
private fun showLocationServiceOffDialog() {
138
val alertDialogBuilder = AlertDialog.Builder(this)
139
140
alertDialogBuilder.setTitle("Location Services Disabled")
141
alertDialogBuilder.setMessage("To enable location services, please go to Settings > Privacy > Location Services.")
142
143
alertDialogBuilder.setPositiveButton("OK") { dialogInterface: DialogInterface, _: Int ->
144
dialogInterface.dismiss() // Close the dialog
145
}
146
147
val alertDialog = alertDialogBuilder.create()
148
alertDialog.show()
149
}
150
151
private fun checkPermissionsAndStartTracking() {
152
if (areAllLocationPermissionGranted(this@ExtendedTrackingActivity)) {
153
startTracking()
154
} else if (!isLocationServiceEnabled(this@ExtendedTrackingActivity)) {
155
showLocationServiceOffDialog()
156
} else {
157
permissionsManager = LocationPermissionsManager(object : LocationPermissionsListener {
158
override fun onExplanationNeeded(permissionsToExplain: List<String>?) {
159
Toast.makeText(
160
this@ExtendedTrackingActivity, "You need to accept location permissions.",
161
Toast.LENGTH_SHORT
162
).show()
163
}
164
165
override fun onPermissionResult(granted: Boolean) {
166
if (granted) {
167
if (isBackgroundLocationPermissionGranted(this@ExtendedTrackingActivity)) {
168
startTracking()
169
} else {
170
permissionsManager?.requestBackgroundLocationPermissions(this@ExtendedTrackingActivity)
171
}
172
} else {
173
Toast.makeText(
174
this@ExtendedTrackingActivity, "You need to accept location permissions.$granted",
175
Toast.LENGTH_SHORT
176
).show()
177
}
178
}
179
})
180
permissionsManager?.requestLocationPermissions(this)
181
}
182
}
183
184
override fun onRequestPermissionsResult(
185
requestCode: Int,
186
permissions: Array<String>,
187
grantResults: IntArray
188
) {
189
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
190
permissionsManager?.onRequestPermissionsResult(requestCode, permissions, grantResults)
191
}
192
193
private fun getTrackingModeString(trackingMode: TrackingMode): String {
194
return when (trackingMode.value) {
195
0 -> "TRACKING_MODE_ACTIVE"
196
1 -> "TRACKING_MODE_BALANCED"
197
2 -> "TRACKING_MODE_PASSIVE"
198
else -> "Unknown tracking mode"
199
}
200
}
201
202
@SuppressLint("SetTextI18n")
203
override fun onLocationSuccess(result: Location) {
204
locationInfoView.text = """
205
--------- Location Info ---------
206
Provider: ${result.provider}
207
Latitude: ${result.latitude}
208
Longitude: ${result.longitude}
209
Altitude: ${result.altitude}
210
Accuracy: ${result.accuracy}
211
speed:${result.speed}
212
Bearing: ${result.bearing}
213
Time: ${result.time}
214
""".trimIndent()
215
}
216
217
override fun onLocationFailure(exception: Exception) {
218
locationInfoView.text = exception.message
219
}
220
221
override fun onTrackingStart(assetId: String) {
222
updateTrackingStatus()
223
}
224
225
override fun onTrackingStop(assetId: String, trackingDisableType: TrackingDisableType) {
226
Log.d("asset", "onTrackingStop")
227
updateTrackingStatus()
228
}
229
}

Upon executing the code example provided above, your app's appearance will resemble the following snippet:

docs-imagedocs-image
Asset Profile PageAsset Tracking Page

Code Highlights

The SetProfileActivity is for an Android activity that allows users to create and bind assets. The activity has the following main steps:

  1. Initialize the shared preferences.

  2. Initialize the view objects.

  3. Read the asset information from the view.

  4. Validate the user input.

  5. Check whether the asset ID is already set in shared preferences.

  6. Create a new asset or bind an existing asset.

  7. Save the asset information to shared preferences.

  8. Launch the MainActivity if the asset ID is already set in shared preferences and the activity was launched from the splash screen.

The following is a description of each step:

  1. To initialize the shared preferences, the activity calls the PreferenceManager.getDefaultSharedPreferences() method. This method returns a SharedPreferences object that contains the default shared preferences for the application.

  2. To initialize the view objects, the activity finds the view objects by their ID. The view objects include the following:

    1. editIdView: An EditText object that allows users to enter the asset's custom ID.

    2. editAssetNameView: An EditText object that allows users to enter the asset's name.

    3. editDescriptionView: An EditText object that allows users to enter the asset's description.

    4. editAttributesView: An EditText object that allows users to enter the asset's attributes.

    5. editAssetIdView: An EditText object that allows users to enter the asset's ID.

    6. lastAssetIdView: An EditText object that displays the last used asset ID.

  3. To read the asset information from the view, the activity gets the text from each of the EditText objects.

  4. To validate the user input, the activity checks the following:

    1. The asset's custom ID must be a valid UUID.

    2. The asset's name must not be empty.

    3. The asset's description must not be empty.

    4. The asset's attributes must be a valid JSON string.

  5. To check whether the asset ID is already set in shared preferences, the activity calls the checkAssetId() function.

  6. To create a new asset, the activity calls the AssetTracking.instance.createNewAsset() method. This method creates a new asset with the information that was entered by the user.

  7. To bind an existing asset, the activity calls the AssetTracking.instance.bindAsset() method. This method binds the asset that is specified by the assetId parameter to the device.

  8. To save the asset information to shared preferences, the activity calls the SharedPreferences.Editor.putString() method for each of the asset information keys.

  9. To launch the MainActivity, if the asset ID is already set in shared preferences and the activity was launched from the splash screen, the activity calls the launchMainActivity() function.

The ExtendedTrackingActivity is for an Android activity that allows users to start and stop tracking an asset. The activity has the following main steps:

  1. Initialize the location permissions manager.

  2. Bind an existing asset, if there is one.

  3. Initialize the view.

  4. Set up the click listeners for the buttons.

  5. Implement the onRequestPermissionsResult() method to handle the results of the location permission requests.

  6. Implement the onLocationSuccess() and onLocationFailure() methods to handle location updates.

  7. Implement the onTrackingStart() and onTrackingStop() methods to handle tracking events.

The following is a description of each step:

  1. To initialize the location permissions manager, the activity creates a new LocationPermissionsManager object and sets a listener for the onPermissionResult() event.

  2. To bind an existing asset, the activity gets the asset ID from shared preferences and calls the AssetTracking.instance.bindAsset() method.

  3. To initialize the view, the activity finds the view objects by their ID. The view objects include the following:

    1. start_tracking: A button that starts tracking the asset.

    2. stop_tracking: A button that stops tracking the asset.

    3. dit_asset_profile: A button that opens the asset profile activity.

    4. isStopTracking: A text view that displays the tracking status.

    5. locationInfo: A text view that displays location information.

    6. locationEngineInfo: A text view that displays the location engine information.

  4. To set up the click listeners for the buttons, the activity sets a click listener for the start_tracking button that calls the checkPermissionsAndStartTracking() method. The activity also sets a click listener for the stop_tracking button that calls the assetTrackingStop() method.

  5. To implement the onRequestPermissionsResult() method, the activity checks the results of the location permission requests and calls the startTracking() method if the permissions are granted.

  6. To implement the onLocationSuccess() and onLocationFailure() methods, the activity updates the locationInfo text view with the location information or the error message, respectively.

  7. To implement the onTrackingStart() and onTrackingStop() methods, the activity updates the isStopTracking text view to reflect the tracking status.

ยฉ 2024 NextBillion.ai all rights reserved.