admin管理员组文章数量:1287840
I am facing a problem with the android google activity recognisation service to detect user activity , When I install appplication it work just fine and I get udpate like still ,tilt , on foot , in vehicle , but after some time like 15 /16 hours it just stop to receive any update,
I have add Activity client in foreground service , I have created Broadcast receiver for Activity Recognisation and Transition , And created A work manager to Recreate Actiivty client at Monring 6 AM and after every 30 minutes I am recreating this ,
I am sharing what I have done
(Service, BroadcastReceiver, Manifest included)
class ActivityRecognitionService : Service() {
private val examplePreferenceUseCase: ExamplePreferenceUseCase by inject()
companion object {
const val DETECTED_ACTIVITY = "DETECTED_ACTIVITY"
const val PREF_NAME = "example_preferences"
}
lateinit var client: ActivityRecognitionClient
private val channelId = "activity_recognition_channel"
private val notificationId = 101
override fun onCreate() {
super.onCreate()
AppLogger.log(applicationContext, "ActivityRecognitionService", "Service created, initializing components.")
client = ActivityRecognition.getClient(this)
requestForUpdates()
createNotificationChannel()
startForeground(notificationId, buildNotification("Detecting activity..."))
scheduleUploadWorker(applicationContext)
scheduleActivityRecognitionWorker(applicationContext)
JobSchedulerHelper.scheduleJob(applicationContext)
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
return START_STICKY
}
private fun requestForUpdates() {
client.requestActivityTransitionUpdates(ActivityTransitionsUtil.getActivityTransitionRequest(), getPendingIntent())
.addOnSuccessListener {
AppLogger.log(applicationContext, "ActivityRecognitionService", "Activity transition updates registered successfully.")
}
.addOnFailureListener { e ->
AppLogger.log(applicationContext, "ActivityRecognitionService", "Failed to register activity transition updates: ${e.localizedMessage}")
}
client.requestActivityUpdates(0L, getPendingIntent())
.addOnSuccessListener {
AppLogger.log(applicationContext, "ActivityRecognitionService", "Activity updates registered successfully.")
}
.addOnFailureListener { e ->
AppLogger.log(applicationContext, "ActivityRecognitionService", "Failed to register activity updates: ${e.localizedMessage}")
}
}
private fun getPendingIntent(): PendingIntent {
val intent = Intent(this, ActivityTransitionReceiver::class.java)
return PendingIntent.getBroadcast(this, 123, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE)
}
private fun createNotificationChannel() {
val channel = NotificationChannel(channelId, "Activity Recognition", NotificationManager.IMPORTANCE_HIGH)
val manager = getSystemService(NotificationManager::class.java)
manager.createNotificationChannel(channel)
}
private fun buildNotification(content: String): Notification {
return NotificationCompat.Builder(this, channelId)
.setContentTitle("Activity Recognition Service")
.setContentText(content)
.setSmallIcon(android.R.drawable.ic_dialog_info)
.build()
}
private fun updateNotification(content: String) {
val notification = buildNotification(content)
val manager = getSystemService(NotificationManager::class.java)
manager.notify(notificationId, notification)
}
override fun onBind(intent: Intent?): IBinder? {
return null
}
fun scheduleUploadWorker(context: Context) {
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val time = examplePreferenceUseCase.getSyncAllTripDataInterval().toLong()
val uploadRequest = PeriodicWorkRequestBuilder<UploadWorker>(time, TimeUnit.MINUTES)
.setConstraints(constraints)
.build()
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
"UploadWorker",
ExistingPeriodicWorkPolicy.KEEP,
uploadRequest
)
AppLogger.log(context, "ActivityRecognitionService", "UploadWorker scheduled every $time minutes.")
}
fun scheduleActivityRecognitionWorker(context: Context) {
val workManager = WorkManager.getInstance(context)
val now = Calendar.getInstance()
val scheduledTime = Calendar.getInstance().apply {
set(Calendar.HOUR_OF_DAY, 6)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
if (before(now)) {
add(Calendar.DAY_OF_MONTH, 1)
}
}
val initialDelay = scheduledTime.timeInMillis - now.timeInMillis
val oneTimeWorkRequest = OneTimeWorkRequestBuilder<ActivityRecognitionWorker>()
.setInitialDelay(initialDelay, TimeUnit.MILLISECONDS)
.build()
workManager.enqueueUniqueWork(
"TripCheckWorker_6AM",
ExistingWorkPolicy.REPLACE,
oneTimeWorkRequest
)
AppLogger.log(context, "WorkManagerScheduler", "First worker scheduled at 6 AM.")
val periodicWorkRequest = PeriodicWorkRequestBuilder<ActivityRecognitionWorker>(30, TimeUnit.MINUTES)
.setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.NOT_REQUIRED)
.build()
)
.build()
workManager.enqueueUniquePeriodicWork(
"TripCheckWorker_8HourCycle",
ExistingPeriodicWorkPolicy.KEEP,
periodicWorkRequest
)
AppLogger.log(context, "WorkManagerScheduler", "Repeating worker scheduled every 8 hours.")
}
override fun onDestroy() {
AppLogger.log(applicationContext, "ActivityRecognitionService", "Service destroyed.")
super.onDestroy()
}
}
class ActivityTransitionReceiver : BroadcastReceiver() {
companion object {
private const val ACTIVITY_TRANSITION_NOTIFICATION_ID = 111
private const val CHANNEL_ID = "activity_transition_channel"
}
override fun onReceive(context: Context, intent: Intent) {
AppLogger.log(context, "ActivityTransitionReceiver", "onReceive triggered")
if (ActivityRecognitionResult.hasResult(intent)) {
val result = ActivityRecognitionResult.extractResult(intent) ?: return
val detectedActivity = result.mostProbableActivity
AppLogger.log(
context, "ActivityRecognition",
"Detected activity: ${ActivityTransitionsUtil.toActivityString(detectedActivity.type)}"
)
ExamplePreferenceManager.setLastUpdateTime()
handleDetectedActivity(context, detectedActivity.type, "ActivityRecognition")
} else if (ActivityTransitionResult.hasResult(intent)) {
val transitionResult = ActivityTransitionResult.extractResult(intent) ?: return
for (event in transitionResult.transitionEvents) {
AppLogger.log(
context, "ActivityTransition",
"Transition detected: ${ActivityTransitionsUtil.toActivityString(event.activityType)}"
)
ExamplePreferenceManager.setLastUpdateTime()
handleDetectedActivity(context, event.activityType, "ActivityTransition")
}
}
}
private fun handleDetectedActivity(context: Context, activityType: Int, tripSource: String) {
AppLogger.log(
context, "ActivityHandling",
"Handling activity type: ${ActivityTransitionsUtil.toActivityString(activityType)} from: $tripSource"
)
when (activityType) {
DetectedActivity.IN_VEHICLE -> {
if (!ExamplePreferenceManager.isTripOngoing()) {
startLocationTracking(context, tripSource)
showNotification(context, activityType, tripSource)
}
}
else -> {
stopLocationTracking(context)
showNotification(context, activityType, tripSource)
}
}
}
private fun startLocationTracking(context: Context, tripSource: String) {
val serviceIntent = Intent(context, LocationUpdateService::class.java).apply {
action = LocationUpdateService.START_TRACKING
putExtra("tripSource", tripSource)
}
context.startForegroundService(serviceIntent)
}
private fun stopLocationTracking(context: Context) {
val serviceIntent = Intent(context, LocationUpdateService::class.java).apply {
action = LocationUpdateService.STOP_TRACKING
}
context.startForegroundService(serviceIntent)
}
private fun showNotification(context: Context, activityType: Int, from: String) {
val notificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val channel = NotificationChannel(
CHANNEL_ID,
"Activity Recognition Notifications",
NotificationManager.IMPORTANCE_HIGH
).apply {
description = "Notifications for activity recognition"
}
notificationManager.createNotificationChannel(channel)
val activityName = ActivityTransitionsUtil.toActivityString(activityType)
val notification = NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(android.R.drawable.ic_dialog_info)
.setContentTitle("Activity Detected")
.setContentText("Detected: $activityName from: $from")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
.build()
notificationManager.notify(ACTIVITY_TRANSITION_NOTIFICATION_ID, notification)
}
}
<receiver
android:name=".gpstracking.receiver.ActivityTransitionReceiver"
android:exported="true"
android:permission="com.google.android.gms.permission.ACTIVITY_RECOGNITION">
<intent-filter>
<action android:name="com.example.driver.ACTIVITY_RESULT" />
</intent-filter>
</receiver>
<service
android:name=".gpstracking.service.ActivityRecognitionService"
android:enabled="true"
android:exported="false"
android:foregroundServiceType="location" />
本文标签:
版权声明:本文标题:Android Activity Recognition Service stops receiving updates after 15 hours (Foreground Service, WorkManager, BroadcastReceiver) 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741326816a2372534.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论