如何在Oreo后台监控地理围栏?

10

我按照这个教程:https://developer.android.com/training/location/geofencing进行操作,对于Android < 8版本可以正常运行,但在Oreo版本中由于新的操作系统后台限制出现了问题。

如何在后台运行应用程序时获得地理围栏转换触发器?

我还尝试使用BroadcastReceiver代替IntentService,但结果是一样的。

Pending Intent:

private val geofencePendingIntent: PendingIntent by lazy {
    val intent = Intent(context, GeofenceBroadcastReceiver::class.java)
    intent.action = "com.example.GEOFENCE_TRANSITION"
    PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}

注册地理围栏:

geofencingClient.addGeofences(request, geofencePendingIntent).run {
    addOnSuccessListener {
        Log.d(TAG, "Geofence added")
    }
    addOnFailureListener {
        Log.e(TAG, "Failed to create geofence")
    }
} 

广播接收器:

class GeofenceBroadcastReceiver : BroadcastReceiver() {
    override fun onReceive(p0: Context?, p1: Intent?) {
        Log.d(TAG, "onReceive")
    }
}

清单中的接收者:

<receiver android:name=".GeofenceBroadcastReceiver">
    <intent-filter>
        <action android:name="com.example.GEOFENCE_TRANSITION"/>
    </intent-filter>
</receiver>

谢谢

编辑:IntentService版本

待定意图:

private val geofencePendingIntent: PendingIntent by lazy {
    val intent = Intent(context, GeofenceIntentService::class.java)
    PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}

Intent Service(意图服务):

class GeofenceIntentService : IntentService("GeofenceIntentService") {
    override fun onHandleIntent(p0: Intent?) {
        Log.d(TAG, "onHandleIntent")
    }
}

清单中的服务:

<service android:name=".GeofenceIntentService"/>

你能否在使用IntentService时发布代码? - Quick learner
是的,我编辑了这个问题。 - Federico Matera
阅读这些链接。 - Quick learner
https://dev59.com/M6Pia4cB1Zd3GeqP5-1Y - Quick learner
https://dev59.com/R5ffa4cB1Zd3GeqP-ZxR - Quick learner
请检查您的位置分辨率,确定其为低、中或高。 - edhair
2个回答

1
当您的后台地理围栏转换被触发时,Android 8会每隔几分钟发送一个Intent。请参见:https://developer.android.com/training/location/geofencing#java

处理地理围栏转换 当位置服务检测到用户已进入或退出地理围栏时,它会发送包含在添加地理围栏请求中的PendingIntent中的Intent。这个Intent被像GeofenceTransitionsIntentService这样的服务接收,该服务从意图中获取地理围栏事件,确定Geofence转换类型,并确定哪个定义的地理围栏被触发。然后它将发送通知作为输出。

注意:在Android 8.0(API级别26)及更高版本上,如果应用程序在监视地理围栏时在后台运行,则设备每隔几分钟响应地理围栏事件。要了解如何使您的应用程序适应这些响应限制,请参阅后台位置限制。

一旦地理围栏服务被注册,它就一直存在,你不需要做其他事情,只需检查特定的PendingIntent。除非设备重新启动,否则无需重新注册地理围栏服务。
还要检查:https://developer.android.com/about/versions/oreo/background-location-limits

请记住,在多种情况下,您需要重新注册地理围栏。有关更多信息,请参见我对相关问题的回答 - Michael Krause

-1

我使用Dexter库来获取权限地理围栏,这适用于Android 8、9、10及以上版本,您必须添加后台权限。

 Dexter.withActivity(this@Activity_Map)
            .withPermissions(
                    Manifest.permission.ACCESS_COARSE_LOCATION
                    ,Manifest.permission.ACCESS_FINE_LOCATION
                    ,Manifest.permission.ACCESS_BACKGROUND_LOCATION
            )
            .withListener(object: MultiplePermissionsListener {
                override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
                    report?.let {
                        if(report.areAllPermissionsGranted()){
                  //put your code here
                            }
                }

即使添加了权限,应用程序也可以在没有前台位置服务的情况下读取位置,就像打开Google Maps应用程序一样。 - Zaher88abd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接