addProximityAlert 无法按预期工作

Posted

技术标签:

【中文标题】addProximityAlert 无法按预期工作【英文标题】:addProximityAlert doesn't work as expected 【发布时间】:2013-12-23 18:53:03 【问题描述】:

ios sdk 具有强大的区域监控功能。我在android中需要类似的东西,我认为我们有两种选择。地理围栏和 LocationManager。

地理围栏有非常整洁的示例和错误,所以我更喜欢 LocationManager。除了一个之外,Everyting 在 LocationManager 中都可以正常工作。如果您将当前位置添加为 ProximityAlert ,它会立即触发“ENTERING”,但这是我当前的位置,并不意味着我进入了该区域。因此,如果我在区域内,每次启动应用程序时都会触发“ENTERING”。(即使我没有移动)

只有当用户真正进入该区域时,我才能解决这个问题并触发事件?

这是我为我的位置添加 PeddingIntents 的方式。

    LocationManager locationManager =  (LocationManager)mContext.getSystemService(Context.LOCATION_SERVICE);

    for(Place p : places)
    
        Log.e("location", p.location);

        Bundle extras = new Bundle();
        extras.putString("name", p.displayName);
        extras.putString("id", p.id);
        Intent intent = new Intent(CommandTypes.PROX_ALERT_INTENT);
        intent.putExtra(CommandTypes.PROX_ALERT_INTENT, extras);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext,Integer.parseInt(p.id), intent,PendingIntent.FLAG_CANCEL_CURRENT);
        float radius = 50f;
        locationManager.addProximityAlert(p.lat,
                p.lon, radius, 1000000, pendingIntent);

           

接收者

public class ProximityReceiver extends BroadcastReceiver 

@Override
public void onReceive(Context context, Intent intent) 

    final String key = LocationManager.KEY_PROXIMITY_ENTERING;
    final Boolean entering = intent.getBooleanExtra(key, false);

    Bundle b = intent.getBundleExtra(CommandTypes.PROX_ALERT_INTENT);
    String id = b.getString("id");
    Log.e("here" + id, "here");

    if (entering) 
        Log.e(TAG,"entering");
     else 
        Log.e(TAG,"leaving");
    
 

清单

   <receiver android:name=".ProximityReceiver">
        <intent-filter>
            <action android:name="ACTION_PROXIMITY_ALERT" />
        </intent-filter>            
    </receiver>

非常感谢

PS:iOS 没有这个问题,他们的文档是这样解释的

注册授权应用程序后立即开始对地理区域的监控。但是,不要期望立即收到事件。只有越界才会产生事件。因此,如果在注册时用户的位置已经在区域内,则位置管理器不会自动生成事件。相反,您的应用程序必须等待用户跨越区域边界,然后才能生成事件并将其发送给委托。也就是说,您可以使用 CLLocationManager 类的 requestStateForRegion: 方法来检查用户是否已经在区域的边界内。

【问题讨论】:

如果您查看源代码 locationManager.addProximity(..),那么您将看到此方法适用于地理围栏。 【参考方案1】:

编辑:自从我写这篇文章以来,地理围栏 API 中添加了一个新的东西,'setInitialTrigger' 可以缓解这个问题:

https://developers.google.com/android/reference/com/google/android/gms/location/GeofencingRequest.Builder#setInitialTrigger%28int%29

是的,这很麻烦,不幸的是,这是 Android 和 IOS 地理围栏不同的主要点之一。

如果 Android 知道您之前在外面或者您在其中添加了地理围栏,则当您在地理围栏内时,Android 会发出警报。

我解决这个问题的方法是在我的广播接收器中设置一个“宽限期”。基本上,当我创建地理围栏时,我会将其创建时间存储在 sharedpreferences 中,并在 onReceive 中检查该值。

通过这样做,任何“立即”命中都将被过滤掉。也许 3 分钟对其他人来说太长了,但根据我在应用程序中使用地理围栏的方式,它对我有用。

private static final Long MIN_PROXALERT_INTERVAL = 18000l; // 3 mins in milliseconds

...

long geofenceCreationTime = session.getPrefs().getCurrentGeofenceCreation();
long elapsedSinceCreation = now - geofenceCreationTime;
if(elapsedSinceCreation < CREATIONTIME_GRACE_PERIOD)
        if (ApplicationSession.DEBUG) 
            Log.d(TAG, "elapsedSinceCreation;"+elapsedSinceCreation+";less than;"+CREATIONTIME_GRACE_PERIOD+";exiting");
        
        return;

    

希望你明白我的意思。

希望对你有帮助。

【讨论】:

只需将 SystemClock.elapsedRealtime() 添加到待处理的意图中,然后在收到广播时与该意图进行比较。无需存储为首选项。 嗯,我想可能是有原因的。如果手机重新启动,并且您想重新创建地理围栏,您将需要跟踪地理围栏的原始创建时间,以便您可以设置重新创建的地理围栏的适当超时。假设您希望它是 12 小时,并且手机在 4 小时后重新启动。然后,您需要原始创建时间才能将“新”地理围栏的超时设置为 8 小时。这就是我将其存储在首选项中的原因。

以上是关于addProximityAlert 无法按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

willPresentNotification 无法按预期工作

地理围栏无法按预期工作

UIViewPropertyAnimator 无法按预期工作

酶按钮模拟无法按预期工作

异步方法无法按预期工作

SaveFileDialog AddExtension 无法按预期工作