Skip to content

Commit a6ae06a

Browse files
committed
Activity Recognition: fix broadcastReceiver (SKD +28) & check for location
1 parent 59cd4a4 commit a6ae06a

6 files changed

Lines changed: 78 additions & 15 deletions

File tree

activity_recognition/src/main/AndroidManifest.xml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
<activity
2121
android:name=".ui.MainActivity"
2222
android:exported="true"
23-
android:label="@string/app_name">
23+
android:label="@string/app_name"
24+
android:screenOrientation="portrait">
2425
<intent-filter>
2526
<action android:name="android.intent.action.MAIN" />
2627

@@ -32,7 +33,11 @@
3233
android:name=".services.TransitionsReceiver"
3334
android:enabled="true"
3435
android:exported="false"
35-
android:permission="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
36+
android:permission="com.google.android.gms.permission.ACTIVITY_RECOGNITION">
37+
<intent-filter>
38+
<action android:name="TRANSITIONS_RECEIVER_ACTION" />
39+
</intent-filter>
40+
</receiver>
3641
</application>
3742

3843
</manifest>

activity_recognition/src/main/java/com/asemlab/samples/activity_recognition/services/TransitionsReceiver.kt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package com.asemlab.samples.activity_recognition.services
33
import android.content.BroadcastReceiver
44
import android.content.Context
55
import android.content.Intent
6+
import android.util.Log
7+
import android.widget.Toast
68
import com.asemlab.samples.activity_recognition.ActivityRecognitionApp
79
import com.asemlab.samples.activity_recognition.utilties.ActivityType
810
import com.asemlab.samples.activity_recognition.utilties.DetectingMode
@@ -18,6 +20,9 @@ class TransitionsReceiver : BroadcastReceiver() {
1820

1921
override fun onReceive(context: Context, intent: Intent) {
2022

23+
Log.d("TransitionsReceiver", "Start detecting")
24+
Toast.makeText(context, "Start detecting", Toast.LENGTH_SHORT).show()
25+
2126
if (ActivityTransitionResult.hasResult(intent)) {
2227
val result = ActivityTransitionResult.extractResult(intent)
2328

@@ -27,17 +32,21 @@ class TransitionsReceiver : BroadcastReceiver() {
2732
val info =
2833
"${toTransitionType(event.transitionType)} ${toActivityString(event.activityType)} at $time"
2934

35+
Toast.makeText(context, info, Toast.LENGTH_SHORT).show()
36+
3037
when (event.transitionType) {
3138
ActivityTransition.ACTIVITY_TRANSITION_ENTER -> {
3239
with(context.applicationContext as ActivityRecognitionApp) {
33-
activityType.value = ActivityType.getType(toActivityString(event.activityType))
40+
activityType.value =
41+
ActivityType.getType(toActivityString(event.activityType))
3442
detectingMode.value = DetectingMode.ENTER
3543
}
3644
}
3745

3846
ActivityTransition.ACTIVITY_TRANSITION_EXIT -> {
3947
with(context.applicationContext as ActivityRecognitionApp) {
40-
activityType.value = ActivityType.getType(toActivityString(event.activityType))
48+
activityType.value =
49+
ActivityType.getType(toActivityString(event.activityType))
4150
detectingMode.value = DetectingMode.EXIT
4251
}
4352
}

activity_recognition/src/main/java/com/asemlab/samples/activity_recognition/ui/dashboard/DashboardFragment.kt

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,17 @@ package com.asemlab.samples.activity_recognition.ui.dashboard
33
// Developed by: Asem Abu alrub // AsemLab © 2025
44

55
import android.Manifest
6+
import android.content.Intent
67
import android.content.pm.PackageManager
78
import android.os.Build
89
import android.os.Bundle
10+
import android.provider.Settings
911
import android.view.LayoutInflater
1012
import android.view.View
1113
import android.view.ViewGroup
1214
import android.widget.Toast
1315
import androidx.activity.result.contract.ActivityResultContracts
16+
import androidx.appcompat.app.AlertDialog
1417
import androidx.core.app.ActivityCompat
1518
import androidx.fragment.app.Fragment
1619
import androidx.lifecycle.ViewModelProvider
@@ -23,6 +26,7 @@ import com.asemlab.samples.activity_recognition.utilties.ActivityType
2326
import com.asemlab.samples.activity_recognition.utilties.Constants
2427
import com.asemlab.samples.activity_recognition.utilties.DetectingMode
2528
import com.asemlab.samples.activity_recognition.utilties.TimerUtility
29+
import com.asemlab.samples.activity_recognition.utilties.isLocationEnabled
2630
import dagger.hilt.android.AndroidEntryPoint
2731

2832

@@ -80,7 +84,7 @@ class DashboardFragment : Fragment() {
8084
.detectingMode.postValue(if (!isRunning) DetectingMode.ON else DetectingMode.OFF)
8185

8286
// TODO Start detecting
83-
ActivityDetectionUtility.switchDetecting(requireContext())
87+
ActivityDetectionUtility.switchDetecting(requireActivity())
8488
}
8589

8690
// For Testing purposes
@@ -173,4 +177,18 @@ class DashboardFragment : Fragment() {
173177
true
174178
}
175179

180+
181+
override fun onResume() {
182+
super.onResume()
183+
if (!isLocationEnabled(requireContext())) {
184+
AlertDialog.Builder(requireContext())
185+
.setTitle(getString(R.string.location_required))
186+
.setMessage(getString(R.string.location_message))
187+
.setPositiveButton(getString(R.string.enable_title)) { d, s ->
188+
startActivity(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
189+
}.setCancelable(false)
190+
.show()
191+
}
192+
}
193+
176194
}

activity_recognition/src/main/java/com/asemlab/samples/activity_recognition/utilties/ActivityDetectionUtility.kt

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import android.content.Context
66
import android.content.Intent
77
import android.os.SystemClock
88
import android.widget.Toast
9+
import com.asemlab.samples.activity_recognition.services.TransitionsReceiver
910
import com.google.android.gms.common.internal.safeparcel.SafeParcelableSerializer
1011
import com.google.android.gms.location.ActivityRecognition
1112
import com.google.android.gms.location.ActivityTransition
@@ -21,12 +22,16 @@ object ActivityDetectionUtility {
2122
private var activityTrackingEnabled: Boolean = false
2223
private var activityTransitionList = mutableListOf<ActivityTransition>()
2324

25+
private val resultKey = "com.google.android.location.internal.EXTRA_ACTIVITY_TRANSITION_RESULT"
2426

2527
private fun getPendingIntent(context: Context): PendingIntent {
2628
if (::pendingIntent.isInitialized)
2729
return pendingIntent
2830

29-
val intent = Intent(Constants.TRANSITIONS_RECEIVER_ACTION)
31+
val intent = Intent(
32+
context,
33+
TransitionsReceiver::class.java
34+
).setAction(Constants.TRANSITIONS_RECEIVER_ACTION)
3035

3136
pendingIntent =
3237
PendingIntent.getBroadcast(
@@ -67,9 +72,7 @@ object ActivityDetectionUtility {
6772
"Transitions Api was successfully registered.",
6873
Toast.LENGTH_SHORT
6974
).show()
70-
}
71-
72-
task.addOnFailureListener { e ->
75+
}.addOnFailureListener { e ->
7376
Toast.makeText(
7477
context,
7578
"Transitions Api could NOT be registered: $e",
@@ -131,8 +134,11 @@ object ActivityDetectionUtility {
131134

132135
// The next two functions are for testing purposes only
133136
fun testSendAction(context: Context) {
134-
val intent2 = Intent()
135-
intent2.setAction(Constants.TRANSITIONS_RECEIVER_ACTION)
137+
val intent2 = Intent(
138+
context,
139+
TransitionsReceiver::class.java
140+
).setAction(Constants.TRANSITIONS_RECEIVER_ACTION)
141+
136142
val events: MutableList<ActivityTransitionEvent> = ArrayList()
137143
var transitionEvent = ActivityTransitionEvent(
138144
DetectedActivity.STILL,
@@ -147,13 +153,17 @@ object ActivityDetectionUtility {
147153
val result = ActivityTransitionResult(events)
148154
SafeParcelableSerializer.serializeToIntentExtra(
149155
result, intent2,
150-
"com.google.android.location.internal.EXTRA_ACTIVITY_TRANSITION_RESULT"
156+
resultKey
151157
)
152158
context.sendBroadcast(intent2)
153159
}
160+
154161
fun testSendActionDriving(context: Context) {
155-
val intent2 = Intent()
156-
intent2.setAction(Constants.TRANSITIONS_RECEIVER_ACTION)
162+
val intent2 = Intent(
163+
context,
164+
TransitionsReceiver::class.java
165+
).setAction(Constants.TRANSITIONS_RECEIVER_ACTION)
166+
157167
val events: MutableList<ActivityTransitionEvent> = ArrayList()
158168
var transitionEvent = ActivityTransitionEvent(
159169
DetectedActivity.IN_VEHICLE,
@@ -168,7 +178,7 @@ object ActivityDetectionUtility {
168178
val result = ActivityTransitionResult(events)
169179
SafeParcelableSerializer.serializeToIntentExtra(
170180
result, intent2,
171-
"com.google.android.location.internal.EXTRA_ACTIVITY_TRANSITION_RESULT"
181+
resultKey
172182
)
173183
context.sendBroadcast(intent2)
174184
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.asemlab.samples.activity_recognition.utilties
2+
3+
import android.content.Context
4+
import android.location.LocationManager
5+
6+
7+
fun isLocationEnabled(context: Context): Boolean {
8+
9+
val locationManager =
10+
context.getSystemService(Context.LOCATION_SERVICE) as LocationManager?
11+
12+
val isGpsEnabled = locationManager!!.isProviderEnabled(LocationManager.GPS_PROVIDER)
13+
val isNetworkEnabled =
14+
locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
15+
16+
return isNetworkEnabled || isGpsEnabled
17+
18+
}

activity_recognition/src/main/res/values/strings.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,7 @@
88
<string name="entry_message">You earned <b>%1$d</b> at <b>%2$s</b> for <b>%3$s</b></string>
99
<string name="start_title">Start</string>
1010
<string name="stop_title">Stop</string>
11+
<string name="location_required">Location required</string>
12+
<string name="location_message">The app needs the location to work propably</string>
13+
<string name="enable_title">Enable</string>
1114
</resources>

0 commit comments

Comments
 (0)