In this page

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:

  1. 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.

  2. 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.

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

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

  5. 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

1class 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

1class 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:

Asset Profile Page Asset 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.

没找到你要找的内容?