Android地理围栏不会触发一次位置关闭和再次打开[重复]
Posted
技术标签:
【中文标题】Android地理围栏不会触发一次位置关闭和再次打开[重复]【英文标题】:Android Geofence not triggers once location OFF and ON again [duplicate] 【发布时间】:2015-07-24 12:10:04 【问题描述】:我正在使用 android 地理围栏 API。添加地理围栏后,它在位置打开时工作正常。但是如果我关闭位置并再次打开,之后地理围栏在进入或退出时不会触发。我已经在我的 Moto G 上使用 Android 5.0 进行了测试。 2 装置。如果位置关闭,地理围栏是否会过期?
我在 Android 文档上看到过,
如果用户禁用了网络位置提供程序,则 地理围栏服务将停止更新,所有注册的地理围栏将 已删除,并由提供的待处理意图生成意图。在 在这种情况下,从此意图创建的 GeofencingEvent 表示 错误事件,其中 hasError() 返回 true 并且 getErrorCode() 返回 GEOFENCE_NOT_AVAILABLE。
Document link
【问题讨论】:
【参考方案1】:是的,一旦关闭位置,地理围栏将被删除。
您应该在清单中使用BroadcastReceiver
来收听位置提供商广播,例如:
<receiver android:name="your.Receiver">
<intent-filter>
<action android:name="android.location.PROVIDERS_CHANGED"/>
</intent-filter>
</receiver>
然后再次注册您的地理围栏。
public class LocationProviderReceiver extends BroadcastReceiver
public LocationProviderReceiver()
@Override
public void onReceive(Context context, Intent intent)
if (action.equals(LocationManager.PROVIDERS_CHANGED_ACTION))
// if location services enabled
// restart geofences
【讨论】:
这不再有效,因为LocationManager.PROVIDERS_CHANGED_ACTION will not work on API 26 and higher【参考方案2】:将此添加到清单中:
<receiver android:name="com.aol.android.geofence.GeofenceReceiver"
android:exported="false">
<intent-filter >
<action android:name="com.aol.android.geofence.ACTION_RECEIVE_GEOFENCE"/>
</intent-filter>
</receiver>
然后在 GeofenceRequester 类中,您需要更改 createRequestPendingIntent 方法,以便它转到您的 BroadcastReceiver 而不是 ReceiveTransitionsIntentService
private PendingIntent createRequestPendingIntent()
// If the PendingIntent already exists
if (null != mGeofencePendingIntent)
// Return the existing intent
return mGeofencePendingIntent;
// If no PendingIntent exists
else
// Create an Intent pointing to the IntentService
Intent intent = new Intent("com.aol.android.geofence.ACTION_RECEIVE_GEOFENCE");
// Intent intent = new Intent(context, ReceiveTransitionsIntentService.class);
/*
* Return a PendingIntent to start the IntentService.
* Always create a PendingIntent sent to Location Services
* with FLAG_UPDATE_CURRENT, so that sending the PendingIntent
* again updates the original. Otherwise, Location Services
* can't match the PendingIntent to requests made with it.
*/
return PendingIntent.getBroadcast(
context,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT);
然后我添加了 GeofenceReceiver 类,看起来像这样:
public class GeofenceReceiver extends BroadcastReceiver
Context context;
Intent broadcastIntent = new Intent();
@Override
public void onReceive(Context context, Intent intent)
this.context = context;
broadcastIntent.addCategory(GeofenceUtils.CATEGORY_LOCATION_SERVICES);
if (LocationClient.hasError(intent))
handleError(intent);
else
handleEnterExit(intent);
private void handleError(Intent intent)
// Get the error code
int errorCode = LocationClient.getErrorCode(intent);
// Get the error message
String errorMessage = LocationServiceErrorMessages.getErrorString(
context, errorCode);
// Log the error
Log.e(GeofenceUtils.APPTAG,
context.getString(R.string.geofence_transition_error_detail,
errorMessage));
// Set the action and error message for the broadcast intent
broadcastIntent
.setAction(GeofenceUtils.ACTION_GEOFENCE_ERROR)
.putExtra(GeofenceUtils.EXTRA_GEOFENCE_STATUS, errorMessage);
// Broadcast the error *locally* to other components in this app
LocalBroadcastManager.getInstance(context).sendBroadcast(
broadcastIntent);
private void handleEnterExit(Intent intent)
// Get the type of transition (entry or exit)
int transition = LocationClient.getGeofenceTransition(intent);
// Test that a valid transition was reported
if ((transition == Geofence.GEOFENCE_TRANSITION_ENTER)
|| (transition == Geofence.GEOFENCE_TRANSITION_EXIT))
// Post a notification
List<Geofence> geofences = LocationClient
.getTriggeringGeofences(intent);
String[] geofenceIds = new String[geofences.size()];
String ids = TextUtils.join(GeofenceUtils.GEOFENCE_ID_DELIMITER,
geofenceIds);
String transitionType = GeofenceUtils
.getTransitionString(transition);
for (int index = 0; index < geofences.size(); index++)
Geofence geofence = geofences.get(index);
...do something with the geofence entry or exit. I'm saving them to a local sqlite db
// Create an Intent to broadcast to the app
broadcastIntent
.setAction(GeofenceUtils.ACTION_GEOFENCE_TRANSITION)
.addCategory(GeofenceUtils.CATEGORY_LOCATION_SERVICES)
.putExtra(GeofenceUtils.EXTRA_GEOFENCE_ID, geofenceIds)
.putExtra(GeofenceUtils.EXTRA_GEOFENCE_TRANSITION_TYPE,
transitionType);
LocalBroadcastManager.getInstance(MyApplication.getContext())
.sendBroadcast(broadcastIntent);
// Log the transition type and a message
Log.d(GeofenceUtils.APPTAG, transitionType + ": " + ids);
Log.d(GeofenceUtils.APPTAG,
context.getString(R.string.geofence_transition_notification_text));
// In debug mode, log the result
Log.d(GeofenceUtils.APPTAG, "transition");
// An invalid transition was reported
else
// Always log as an error
Log.e(GeofenceUtils.APPTAG,
context.getString(R.string.geofence_transition_invalid_type,
transition));
/**
* Posts a notification in the notification bar when a transition is
* detected. If the user clicks the notification, control goes to the main
* Activity.
*
* @param transitionType
* The type of transition that occurred.
*
*/
private void sendNotification(String transitionType, String locationName)
// Create an explicit content Intent that starts the main Activity
Intent notificationIntent = new Intent(context, MainActivity.class);
// Construct a task stack
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
// Adds the main Activity to the task stack as the parent
stackBuilder.addParentStack(MainActivity.class);
// Push the content Intent onto the stack
stackBuilder.addNextIntent(notificationIntent);
// Get a PendingIntent containing the entire back stack
PendingIntent notificationPendingIntent = stackBuilder
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
// Get a notification builder that's compatible with platform versions
// >= 4
NotificationCompat.Builder builder = new NotificationCompat.Builder(
context);
// Set the notification contents
builder.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(transitionType + ": " + locationName)
.setContentText(
context.getString(R.string.geofence_transition_notification_text))
.setContentIntent(notificationPendingIntent);
// Get an instance of the Notification manager
NotificationManager mNotificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
// Issue the notification
mNotificationManager.notify(0, builder.build());
【讨论】:
com.aol.android.geofence.ACTION_RECEIVE_GEOFENCE
不是隐含意图。以上是关于Android地理围栏不会触发一次位置关闭和再次打开[重复]的主要内容,如果未能解决你的问题,请参考以下文章