Android Geofence不会在位置关闭和打开时触发

Android Geofence不会在位置关闭和打开时触发,android,android-location,android-geofence,Android,Android Location,Android Geofence,我正在使用Android GeoFerning API。添加GeoFerning后,当位置处于打开状态时,它可以正常工作。但如果我关闭位置并再次打开,则在进入或退出时,GeoFerning不会触发。我已经在我的Moto G上使用安卓5.0.2设备进行了测试。如果位置关闭,Geofence是否会过期 我在Android文档中看到 如果用户禁用了网络位置提供程序,则 geofence服务将停止更新,所有已注册的geofence将被删除 已删除,并由提供的挂起意图生成意图。在里面 在这种情况下,根据此

我正在使用Android GeoFerning API。添加GeoFerning后,当位置处于打开状态时,它可以正常工作。但如果我关闭位置并再次打开,则在进入或退出时,GeoFerning不会触发。我已经在我的Moto G上使用安卓5.0.2设备进行了测试。如果位置关闭,Geofence是否会过期

我在Android文档中看到

如果用户禁用了网络位置提供程序,则 geofence服务将停止更新,所有已注册的geofence将被删除 已删除,并由提供的挂起意图生成意图。在里面 在这种情况下,根据此意图创建的GeofencingEvent表示 错误事件,其中hasError()返回true,getErrorCode()返回 土工围栏不可用


将此项添加到清单中:

<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>
然后我添加了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());
    }
}
公共类GeofenceReceiver扩展了BroadcastReceiver{
语境;
意向广播意向=新意向();
@凌驾
公共void onReceive(上下文、意图){
this.context=上下文;
broadcastIntent.addCategory(GeofenceUtils.CATEGORY\u LOCATION\u SERVICES);
if(LocationClient.hasError(intent)){
handleError(意图);
}否则{
handleinterexit(意图);
}
}
私有无效句柄错误(意图){
//获取错误代码
int errorCode=LocationClient.getErrorCode(intent);
//获取错误消息
String errorMessage=LocationServiceErrorMessages.getErrorString(
上下文、错误代码);
//记录错误
Log.e(GeofenceUtils.APPTAG,
context.getString(R.string.geofrance\u transition\u error\u detail,
错误消息);
//为广播目的设置操作和错误消息
广播意图
.setAction(GeofenceUtils.ACTION\u GEOFENCE\u错误)
.putExtra(geofenseUtils.EXTRA\u geofense\u状态,错误消息);
//将错误*本地*广播到此应用程序中的其他组件
LocalBroadcastManager.getInstance(上下文).sendBroadcast(
广播意图);
}
私有无效HandleInterExit(意向){
//获取转换类型(入口或出口)
int transition=LocationClient.getGeofenceTransition(意图);
//测试是否报告了有效的转换
如果((转换==地理围栏。地理围栏\转换\输入)
||(过渡==地理围栏。地理围栏\过渡\出口)){
//张贴通知
列出geofences=LocationClient
.gettriggeringgeofenses(意图);
String[]geofineids=新字符串[geofines.size()];
String ID=TextUtils.join(geofenseutils.geofense\u ID\u分隔符,
大地水准面);
字符串transitionType=GeofenceUtils
.getTransitionString(转换);
对于(int index=0;index= 4
NotificationCompat.Builder=新建NotificationCompat.Builder(
上下文);
//设置通知内容
builder.setSmallIcon(R.drawable.ic_通知)
.setContentTitle(transitionType+“:”+locationName)
.setContentText(
context.getString(R.string.geopfence\u transition\u notification\u text))
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());
    }
}
<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
        }
    }
}