无法使用广播接收器检测用户活动转换

Posted

技术标签:

【中文标题】无法使用广播接收器检测用户活动转换【英文标题】:Unable to detect User activity transition , using broadcast receivers 【发布时间】:2018-09-09 14:06:58 【问题描述】:

我使用了谷歌最近推出的Activity Transition API 来检测用户何时进出车辆。下面是我用来实现相同目的的代码。

 val intent = Intent(context, ActivityTransitionReceiver::class.java)
    val pendingIntent = PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT)

    transitions.apply 
        add(ActivityTransition.Builder()
                .setActivityType(DetectedActivity.IN_VEHICLE)
                .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER)
                .build())

        add(ActivityTransition.Builder()
                .setActivityType(DetectedActivity.IN_VEHICLE)
                .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT)
                .build())
    

    var transitionRequest = ActivityTransitionRequest(transitions)

    // myPendingIntent is the instance of PendingIntent where the app receives callbacks.
    val task = ActivityRecognition.getClient(context).requestActivityTransitionUpdates(transitionRequest, pendingIntent)

    task.addOnSuccessListener 
        // Handle success
        context.toast("Task added successfully")
    

    task.addOnFailureListener 
        // Handle error
        context.toast("Error adding task")
    

该应用运行良好,并在未从最近的应用选项卡中删除时接收广播。但是当应用程序从最近的应用程序选项卡中删除或被系统杀死时,我无法接收广播。我不知道我做错了什么。有没有其他方法可以达到同样的效果?

我考虑过使用前台服务,这样应用就不会被杀死,但后来认为显示永久通知只是为了检测用户活动转换并不是一个好主意。

编辑:我看到一些应用程序要求特殊许可,例如“忽略电池优化”,当获得此许可时,该应用程序似乎总是可以工作并不断发送通知。

【问题讨论】:

您要在onDestroy 中注销吗?您是否在多个设备上进行了测试?对于某些***.com/a/42120277/1256219,需要一个“受保护的应用程序” 您在哪里使用此代码。在服务或活动中? 用这个PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 4, intent, PendingIntent.FLAG_NO_CREATE);pendingIntent = PendingIntent.getBroadcast(this, 4, intent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT);替换你的待处理意图的东西 ***.com/questions/41277671/… 看看我的问题..这可以帮助你 【参考方案1】:

您应该在后台服务中执行此操作,并在清单文件中将“stopWithTask”标志设置为 false。

这样当用户从最近的应用中删除你的应用时,你的服务不会被杀死。

https://developer.android.com/reference/android/content/pm/ServiceInfo.html

当用户从最近的应用程序中删除您的任务时,服务中的回调将被调用:onTaskRemoved https://developer.android.com/reference/android/app/Service.html#onTaskRemoved(android.content.Intent)

你可以在这个回调中做一些清理或任何你想做的事情

最后,以 STICKY 身份启动您的服务。这样,如果用户终止了您的应用程序,服务将重新启动,您可以继续工作。 (这不保证会发生,但这是一个不错的妥协)

希望对你有帮助

【讨论】:

【参考方案2】:

根据documentation,如果您的目标 API 为 26 或更高,则不应期望调用隐式接收器:

注意:如果您的应用面向 API 级别 26 或更高级别,则不能使用 清单以声明隐式广播的接收器(广播 不专门针对您的应用程序),除了一些隐含的 不受该限制的广播。在大多数情况下,您 可以改为使用计划作业。

唯一好的解决方案似乎是前台服务。您可以始终将其保留在后台,并且仅在使用 Service.onTaskRemoved 关闭应用程序时将其移动到前台。

【讨论】:

以上是关于无法使用广播接收器检测用户活动转换的主要内容,如果未能解决你的问题,请参考以下文章

为特定活动实现广播接收器

为啥当主应用停止时我的小部件广播接收器服务停止

如何检测服务和广播接收器中的关键事件

如何检测服务和广播接收器中的关键事件

活动中的广播接收器

从广播接收器更改片段