我已成功使用Flag NEVER_EXPIRE添加地理围栏。一切似乎都运转正常。
但现在测试时我发现如果我停止位置服务地理围栏停止工作为EXPECTED。此外,当我再次启动位置服务时,我之前添加的地理围栏应该再次开始工作,但不会生成任何通知,并且一旦禁用位置服务,地理围栏似乎会自动删除。我必须再次设置所有位置以恢复工作状态下的地理围栏。
任何建议或任何想法为什么会这样做?
编辑::
当设备关闭/重新启动等时也会出现类似问题。因此,如果禁用位置服务/重新启动设备,基本上所有注册的地理围栏都将过期。其中很少我尝试通过Session处理,但我正在寻找一种解决方案,通过该解决方案,我们可以在启用位置服务时将Geofences设置回来。
答案 0 :(得分:5)
为了在后台观看,我遇到了同样的问题,并且能够通过将示例代码从IntentService更改为BroadcastReceiver来解决它。所有细节都可以在我的帖子中找到:
Android Geofence eventually stop getting transition intents
这就是我所说的(如果有人懒得关注链接):
所以在稍微讨论一下之后,看起来示例代码中定义的ReceiveTransitionsIntentService将在应用程序不在时停止获取通知。我认为这是示例代码的一个大问题......似乎会像我一样绊倒那些人。
所以我使用的是广播接收器,到目前为止它似乎正在我的测试中工作。
将其添加到清单:
<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());
}
}
希望这有助于其他人。
答案 1 :(得分:1)
发现此答案::: http://developer.android.com/reference/com/google/android/gms/location/LocationClient.html
如果用户禁用了网络位置提供程序,则地理围栏服务将停止更新,将删除所有已注册的地理围栏,并通过提供的待处理意图生成意图。在这种情况下,hasError(Intent)返回true,getErrorCode(Intent)返回GEOFENCE_NOT_AVAILABLE。
现在::::当位置服务回来时,我们如何注册地理围栏...(在背景中)
答案 2 :(得分:0)
@ rns.ravi - 查看文档所说的内容 - 您必须注册一个意图,然后您可以重新添加所有地理围栏
public void requestLocationUpdates (LocationRequest request, PendingIntent callbackIntent)
Requests location updates with a callback on the specified PendingIntent.
This method is suited for the background use cases, more specifically for receiving location updates, even when the app has been killed by the system. In order to do so, use a PendingIntent for a started service. For foreground use cases, the LocationListener version of the method is recommended, see requestLocationUpdates(LocationRequest, LocationListener).
Any previous LocationRequests registered on this PendingIntent will be replaced.
Location updates are sent with a key of KEY_LOCATION_CHANGED and a Location value on the intent.
Parameters
request The location request for the updates.
callbackIntent A pending intent to be sent for each location update.
答案 3 :(得分:0)
在前台服务中运行地理围栏代码。它将按预期工作