地理围栏 api 无法在 Android 中以未决意图工作

发布于 2025-01-17 19:57:51 字数 3332 浏览 1 评论 0原文

我正在尝试实现简单的Geofence应用程序,但根本没有被触发。

这是我到目前为止所做的工作的代码 -

class GeoFencingHelper(context: Context, private val task: Task, private val pendingIntent: PendingIntent){

private val geofencingClient = LocationServices.getGeofencingClient(context)

init {
    Timber.e(task.id.toString())
}

@SuppressLint("MissingPermission")
fun initiateGeoFencing() {

    val geoReq  = createGeoFenceList()

    geofencingClient.addGeofences(geoReq, pendingIntent).apply {
        addOnSuccessListener {
            Timber.e("added geofence!")
        }

        addOnFailureListener {
            Timber.e("geofence failed!")
        }
    }

}

private fun createGeoFenceList(): GeofencingRequest {

    val geofenceList = arrayListOf<Geofence>()


    geofenceList.add(Geofence.Builder().apply {
        setRequestId(task.id.toString())

        setCircularRegion(
                task.location.latitude,
                task.location.longitude,
                task.range.toFloat()
        )

            // Set the expiration duration of the geofence. This geofence gets automatically
            // removed after this period of time.
        setExpirationDuration(Geofence.NEVER_EXPIRE)
        setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER or Geofence.GEOFENCE_TRANSITION_EXIT)
            // Create the geofence.

    }.build())


    
    return getGeofencingRequest(geofenceList)
}

private fun getGeofencingRequest(
    fenceList: List<Geofence>,
): GeofencingRequest {
    return GeofencingRequest.Builder().apply {
        setInitialTrigger(
            if(task.reminderCondition == ReminderCondition.ON_ENTRY)
                GeofencingRequest.INITIAL_TRIGGER_ENTER
            else
                GeofencingRequest.INITIAL_TRIGGER_EXIT)
        addGeofences(fenceList)
    }.build()}

我在这里添加地理围栏是广播接收器

fun createGeoFence(context: Context, task: Task){
val geofencePendingIntent: PendingIntent by lazy {
    task.range = 150.0
    val intent = Intent(context, ReminderNotificationBroadcastReceiver::class.java)

    intent.putExtra(TASK_ID, task.id)

    if(Build.VERSION.SDK_INT > 30){
        PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
    }else{
        PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
    }
}
val geoFencingHelper = GeoFencingHelper(context, task, geofencePendingIntent)

geoFencingHelper.initiateGeoFencing()}

,该广播接收器是在触发地理五项事件时向用户显示通知的广播接收器。

class ReminderNotificationBroadcastReceiver @Inject constructor(private val dao: TaskDao): BroadcastReceiver() {

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

    val builder = NotificationCompat.Builder(context, "2222")
        .setSmallIcon(R.drawable.ic_launcher_background)
        .setContentTitle("Reminder \"\".")
        .setContentText("Reminder \".")
        .setOngoing(true)
        .setColor(Color.BLUE)

    with(NotificationManagerCompat.from(context)) {
        notify(2222, builder.build())
    }}}

到目前为止,我已经做过的事情 -

  1. 残疾电池优化。
  2. 始终允许背景位置权限。

问题 -

我使用了Lockito和GPS仿真器(例如Lockito和GPS模拟器)的模拟位置应用程序来测试该应用。 但是,Geofence事件没有被触发,我还尝试构建和测试由Android Codelab提供的样本项目,但我也在该应用程序中面临同样的问题。

I'm trying to implement simple geofence app but its not getting triggered at all.

here is the code of what I've done so far -

class GeoFencingHelper(context: Context, private val task: Task, private val pendingIntent: PendingIntent){

private val geofencingClient = LocationServices.getGeofencingClient(context)

init {
    Timber.e(task.id.toString())
}

@SuppressLint("MissingPermission")
fun initiateGeoFencing() {

    val geoReq  = createGeoFenceList()

    geofencingClient.addGeofences(geoReq, pendingIntent).apply {
        addOnSuccessListener {
            Timber.e("added geofence!")
        }

        addOnFailureListener {
            Timber.e("geofence failed!")
        }
    }

}

private fun createGeoFenceList(): GeofencingRequest {

    val geofenceList = arrayListOf<Geofence>()


    geofenceList.add(Geofence.Builder().apply {
        setRequestId(task.id.toString())

        setCircularRegion(
                task.location.latitude,
                task.location.longitude,
                task.range.toFloat()
        )

            // Set the expiration duration of the geofence. This geofence gets automatically
            // removed after this period of time.
        setExpirationDuration(Geofence.NEVER_EXPIRE)
        setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER or Geofence.GEOFENCE_TRANSITION_EXIT)
            // Create the geofence.

    }.build())


    
    return getGeofencingRequest(geofenceList)
}

private fun getGeofencingRequest(
    fenceList: List<Geofence>,
): GeofencingRequest {
    return GeofencingRequest.Builder().apply {
        setInitialTrigger(
            if(task.reminderCondition == ReminderCondition.ON_ENTRY)
                GeofencingRequest.INITIAL_TRIGGER_ENTER
            else
                GeofencingRequest.INITIAL_TRIGGER_EXIT)
        addGeofences(fenceList)
    }.build()}

I'm adding geofencing here

fun createGeoFence(context: Context, task: Task){
val geofencePendingIntent: PendingIntent by lazy {
    task.range = 150.0
    val intent = Intent(context, ReminderNotificationBroadcastReceiver::class.java)

    intent.putExtra(TASK_ID, task.id)

    if(Build.VERSION.SDK_INT > 30){
        PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
    }else{
        PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
    }
}
val geoFencingHelper = GeoFencingHelper(context, task, geofencePendingIntent)

geoFencingHelper.initiateGeoFencing()}

here is the broadcast receiver to show notification to user when geofence event gets triggered.

class ReminderNotificationBroadcastReceiver @Inject constructor(private val dao: TaskDao): BroadcastReceiver() {

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

    val builder = NotificationCompat.Builder(context, "2222")
        .setSmallIcon(R.drawable.ic_launcher_background)
        .setContentTitle("Reminder \"\".")
        .setContentText("Reminder \".")
        .setOngoing(true)
        .setColor(Color.BLUE)

    with(NotificationManagerCompat.from(context)) {
        notify(2222, builder.build())
    }}}

things I've done so far -

  1. disabled battery optimization.
  2. background location permission is allowed all the time.

Issue -

I used mock location apps like lockito and gps emulator to test the app.
but the geofence event is not getting triggered, I also tried to build and test sample project provided by android codelab, but I'm facing same issue in that app as well.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

春花秋月 2025-01-24 19:57:52

关于SO和网上也有类似的问题,但简而言之,Google Codelab并非最新。 pENDENTINTENT用于地理申请的才能使其工作。因此,在您的情况下:

fun createGeoFence(context: Context, task: Task){
val geofencePendingIntent: PendingIntent by lazy {
    ....

    if(Build.VERSION.SDK_INT > 30){
        PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE)
    } else{
        PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
    }
}

或这样的情况下,如果 作为pendentIntent的,默认情况下是可以突变的,直到build> build> build.version_codes.r

fun createGeoFence(context: Context, task: Task){
val geofencePendingIntent: PendingIntent by lazy {
    ....

    PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE)
}

There are similar questions on SO and on the net but in short, Google codelab is not up to date for this. The PendingIntent used for Geofencing needs to be mutable for it to work. So in your case:

fun createGeoFence(context: Context, task: Task){
val geofencePendingIntent: PendingIntent by lazy {
    ....

    if(Build.VERSION.SDK_INT > 30){
        PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE)
    } else{
        PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
    }
}

or just like this without the if as PendingIntent is mutable by default up until Build.VERSION_CODES.R:

fun createGeoFence(context: Context, task: Task){
val geofencePendingIntent: PendingIntent by lazy {
    ....

    PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE)
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文