Android 地理围栏在进入/退出时触发,没有错误但没有 GEOFENCE_TRANSITION_ 标志

Posted

技术标签:

【中文标题】Android 地理围栏在进入/退出时触发,没有错误但没有 GEOFENCE_TRANSITION_ 标志【英文标题】:Android Geofence triggers on enter/exit with no error but no GEOFENCE_TRANSITION_ flag 【发布时间】:2017-05-19 19:12:45 【问题描述】:

我正在使用下面的代码监控地理围栏转换

LocationServices.GeofencingApi
    .addGeofences(AssistApplication.getApiHelper().getClient(),
                  getGeofencingRequest(),
                  getPendingIntent(context,  
                              GeofenceTransitionIntentService.class))
    .setResultCallback(this);

这就是我构建 GeofencingRequest 的方式

private GeofencingRequest getGeofencingRequest()

    return new GeofencingRequest.Builder()
            .setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER |
                    GeofencingRequest.INITIAL_TRIGGER_EXIT)
            .addGeofence(getGeofence())
            .build();


private Geofence getGeofence()

    return new Geofence.Builder()
            .setRequestId(requestId)
            .setCircularRegion(latitude, longitude, 100)
            .setExpirationDuration(Geofence.NEVER_EXPIRE)
            .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
                    Geofence.GEOFENCE_TRANSITION_EXIT)
            .build();

地理围栏在进入和退出时正确触发,但是当我使用 getGeofenceTransition() 时,我没有得到三个 GEOFENCE_TRANSITION_ 标志中的任何一个。

protected void onHandleIntent(Intent intent)

    final GeofencingEvent event = GeofencingEvent.fromIntent(intent);
    if (event.hasError())
    
        Log.e(TAG, getErrorMessage(event.getErrorCode()));
        return;
    

    switch (event.getGeofenceTransition())
    
        case Geofence.GEOFENCE_TRANSITION_EXIT:
            // Not triggered 
            break;
        case Geofence.GEOFENCE_TRANSITION_ENTER:
        case Geofence.GEOFENCE_TRANSITION_DWELL:
            // Not triggered
            break;
        default:
            // Triggered on exit and enter
    

请告诉我这里缺少什么

【问题讨论】:

您在GeofencingRequest.Builder 中设置了什么?你从getGeofenceTransition() 得到什么?如果它是 -1,那么您的意图不是来自转换警报。广播接收器是否接收到您的地理围栏事件? 我在构建请求的地方添加了代码。我将INITIAL_TRIGGER_ENTERINITIAL_TRIGGER_EXIT 设置为初始触发,将GEOFENCE_TRANSITION_ENTERGEOFENCE_TRANSITION_EXIT 设置为转换。我没有得到任何GEOFENCE_TRANSITION_ 标志,因此根据API 参考它必须是-1,但我知道它被触发而没有错误,因为default 代码在我进入/退出该区域时执行。如果它不是转换警报并且没有错误,那么触发服务的原因是什么?我没有使用任何广播接收器,只有IntentService 【参考方案1】:

根据问题中的信息,我看不出您的代码有任何具体问题,但我怀疑您正在处理的 Intent 不是来自转换警报?

我个人使用广播接收器从地理围栏接收Intent,使用IntentFilter 过滤它。我使用的结构如下:-

Activity 中声明广播接收器

private BroadcastReceiver passedGeofenceReceiver = new BroadcastReceiver() 
        @Override
        public void onReceive(Context context, Intent intent) 
            int geofenceTransition;

            // get the Geofencing Event
            GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
            if (geofencingEvent.hasError()) 
                return;
            

            // Get the transition type.
            geofenceTransition = geofencingEvent.getGeofenceTransition();

            if ( geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER) 
                // etc etc 

在你的ActivityonCreate方法中注册这个接收器:-

    // register this Activity as the receiver of Geofence notifications
    IntentFilter filter = new IntentFilter();
    filter.addAction("com.example.HIT_GEOFENCE");
    this.registerReceiver(this.passedGeofenceReceiver, filter);

在创建广播PendingIntent 时,设置过滤器(mGeofencePendingIntent 是成员PendingIntent 变量):-

private PendingIntent getGeofencePendingIntent() 
    // Reuse the PendingIntent if we already have it.
    if (mGeofencePendingIntent != null) 
        return mGeofencePendingIntent;
    

    Intent hitGeofenceIntent = new Intent("com.example.HIT_GEOFENCE"); //- intent to send a broadcast

    mGeofencePendingIntent = PendingIntent.getBroadcast(this, 0, hitGeofenceIntent,  PendingIntent.FLAG_UPDATE_CURRENT);
    return mGeofencePendingIntent;

监控您的地理围栏:-

private void monitorGeofences() 
    if ( <check permissions> ) 
        GeofencingRequest geofencingRequest = getGeofencingRequest();
        PendingIntent pendingIntent = getGeofencePendingIntent();
        LocationServices.GeofencingApi.addGeofences(mGoogleApiClient, geofencingRequest, pendingIntent)
                        .setResultCallback(this); // Result callback fires 'onResult'
    

我希望这会有所帮助。

【讨论】:

该活动在地理围栏转换发生时不活动,我不希望它开始。我只想显示一个通知。那还能用吗? 您的应用程序结构如何?您可以将广播接收器作为一个独立的类,或者在服务中声明它。我建议,如果您只是在等待地理围栏触发而没有运行活动,那么您将其编写为广播接收器应用程序组件。对不起,我的回答没有用。 我现在正在做一个不同的项目,所以我还没有尝试过你的答案。会告诉你它是否有效。【参考方案2】:

我在 android 12 上使用地理围栏时遇到了同样的问题。没有转换 (-1),没有触发位置,也没有触发意图中的地理围栏。

那是因为我在创建待处理 Intent 时使用了PendingIntent.FLAG_IMMUTABLE 而不是PendingIntent.FLAG_MUTABLE

所以在广播意图的情况下应该这样创建:

PendingIntent.getBroadcast(
    context, 0,
    Intent(context, GeofenceBroadcastReceiver::class.java),
    PendingIntent.FLAG_UPDATE_CURRENT or
        (if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) PendingIntent.FLAG_MUTABLE else 0)
)

【讨论】:

以上是关于Android 地理围栏在进入/退出时触发,没有错误但没有 GEOFENCE_TRANSITION_ 标志的主要内容,如果未能解决你的问题,请参考以下文章

Android地理围栏不会触发一次位置关闭和再次打开[重复]

在打开另一个 GPS 应用程序之前,地理围栏随机无法触发

Android Geofences (Location Services) - 如何触发应用内事件

如何提高 Android 地理围栏进入/退出通知的一致性?

获取 Android 应用程序用户进入地理围栏的方向

没有 requestLocationUpdates 不会触发 Android 地理围栏