2

当我尝试在我的应用中使用地理围栏时遇到问题。我已成功注册地理围栏,但我从未收到通知。

首先,我按照http://developer.android.com/training/location/geofencing.html中提供的示例进行操作,但即使我正在走向或离开区域,代码也不会触发意图服务。

我注册地理围栏和调用意图服务的代码如下:

清单内:

<service
        android:name="com.example.zukami.apps.blynk.geofence.ReceiveTransitionsIntentService"
        android:exported="true" >
    </service>

在我的 MainActivity

    private boolean registerGeofence() {
        mRequestType = GeofenceUtils.REQUEST_TYPE.ADD;
        if (!servicesConnected()) {
            return false;
        }


        SimpleGeofence testGeo = new SimpleGeofence(Flag.GEOFENCE + "_"
                + 1, Double.valueOf("1.317342"),
                Double.valueOf("103.841998"), (float) (200),
                GEOFENCE_EXPIRATION_IN_HOURS,
                Geofence.GEOFENCE_TRANSITION_ENTER);

        mPrefs.setGeofence(Flag.GEOFENCE + "_" + 1, testGeo);
        mCurrentGeofences.add(testGeo.toGeofence());

        SimpleGeofence testGeo2 = new SimpleGeofence(Flag.GEOFENCE + "_"
                + 2, Double.valueOf("1.303961"),
                Double.valueOf("103.909356"), (float) (200),
                GEOFENCE_EXPIRATION_IN_HOURS,
                Geofence.GEOFENCE_TRANSITION_ENTER);

        mPrefs.setGeofence(Flag.GEOFENCE + "_" + 2, testGeo2);
        mCurrentGeofences.add(testGeo2.toGeofence());
        // end deleted this code after testing

        try {
            mGeofenceRequester.addGeofences(mCurrentGeofences);
            Log.e(TAG, "ADDING GEOFENCE ??? YES WE DID IT");
        } catch (UnsupportedOperationException e) {
            Toast.makeText(this,
                    R.string.add_geofences_already_requested_error,
                    Toast.LENGTH_LONG).show();
        }
        return true;
    }

 @Override
    protected void onResume() {
        super.onResume();
        // Register the broadcast receiver to receive status updates
        LocalBroadcastManager.getInstance(this).registerReceiver(mBroadcastReceiver, mIntentFilter);

在我的 GeofenceRequester

private PendingIntent createRequestPendingIntent() {
     Log.e(TAG, "CREATE REQUEST PENDING INTENT");
     // If the PendingIntent already exists
     if (null != mGeofencePendingIntent) {
     Log.e(TAG, "PENDING INTENT NOT NULL");
     return mGeofencePendingIntent;

     // If no PendingIntent exists
     } else {
     Log.e(TAG, "PENDING INTENT  NULL, LET'S CREATED IT");
     // Create an Intent pointing to the IntentService
     Intent intent = new Intent(mActivity,
     ReceiveTransitionsIntentService.class);
     Log.e(TAG,
     return PendingIntent.getService(mActivity, 0, intent,
     PendingIntent.FLAG_UPDATE_CURRENT);
     }

在类中,来自 IntentService 的子类与示例相同。

我确实搜索了这个问题并找到了这个链接上描述的解决方案: Android Geofence 最终停止获取转换意图,所以我完全按照建议更改了我的代码,但我仍然无法从我的 GeofenceReceiver 类中的代码中获得通知,这一行的代码

LocationClient.getGeofenceTransition(intent);

总是返回-1,这意味着我永远不会进入或离开该区域(表示 GEOFENCE NEVER_EXPIRED),所以我永远不会收到通知。请在我的 GeofenceReceiver 类下面找到:

public class GeofenceReceiver extends BroadcastReceiver {

    public static String TAG = GeofenceReceiver.class.getCanonicalName();
    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) {
        int errorCode = LocationClient.getErrorCode(intent);
        String errorMessage = LocationServiceErrorMessages.getErrorString(
                context, errorCode);
        Log.e(GeofenceUtils.APPTAG, context.getString(
                R.string.geofence_transition_error_detail, errorMessage));

        broadcastIntent.setAction(GeofenceUtils.ACTION_GEOFENCE_ERROR)
                .putExtra(GeofenceUtils.EXTRA_GEOFENCE_STATUS, errorMessage);
        LocalBroadcastManager.getInstance(context).sendBroadcast(
                broadcastIntent);
    }

    private void handleEnterExit(Intent intent) {

        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 = getTransitionString(transition);

            for (int index = 0; index < geofences.size(); index++) {
                Geofence geofence = geofences.get(index);
                geofenceIds[index] = geofences.get(index).getRequestId();
            }

            sendNotification(transitionType, ids);

            // 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(context).sendBroadcast(
                    broadcastIntent);

            // Log the transition type and a message
            Log.e(GeofenceUtils.APPTAG, transitionType + ": " + ids);
            Log.e(GeofenceUtils.APPTAG, context
                    .getString(R.string.geofence_transition_notification_text));
            Log.e(GeofenceUtils.APPTAG, "transition");
        } else {
            // Always log as an error
            Log.e(TAG, "TRANSITION = " + transition);
        }
    }

请告知我应该如何修复此代码,并非常感谢您提供任何帮助。

4

3 回答 3

5

对我来说,我只是在createPendingIntent方法中更改了一些代码行

private PendingIntent createRequestPendingIntent() {
 Log.e(TAG, "CREATE REQUEST PENDING INTENT");
 // If the PendingIntent already exists
 if (null != mGeofencePendingIntent) {
 Log.e(TAG, "PENDING INTENT NOT NULL");
 return mGeofencePendingIntent;

 // If no PendingIntent exists
 } else {
 Log.e(TAG, "PENDING INTENT  NULL, LET'S CREATED IT");
 // Create an Intent pointing to the IntentService
 Intent intent = new Intent(mActivity,
 ReceiveTransitionsIntentService.class);
 Log.e(TAG,
 return PendingIntent.getService(mActivity, 0, intent,
 PendingIntent.FLAG_UPDATE_CURRENT);
 }

所以代替return PendingIntent.getService(mActivity, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

使用这块蛋糕 return PendingIntent.getBroadcast(mActivity, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

并确保您已在应用程序清单文件中声明了您的 BroadcastReceiver。祝您好运!!!!

于 2014-04-04T06:15:01.673 回答
2

注意:当位置提供程序设置更改或设备重新启动时,地理围栏确实被删除。不幸的是,Android 文档没有在任何地方提到这一点。

为了解决这个问题,您可以注册一个 Boot-Completed Receiver 和一个 Location Provider Changed Receiver:

    <!-- Boot Completed Receiver -->
    <receiver android:name="com.mydemoapp.geofencing.BootCompleteReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

    <!-- Location Service Provider Changed Receiver -->
    <receiver android:name="com.mydemoapp.geofencing.LocationProviderChangedReceiver">
        <intent-filter>
            <action android:name="android.location.PROVIDERS_CHANGED" />
        </intent-filter>
    </receiver>

在这两个广播接收器中,您可以实现重新注册先前删除的地理围栏的逻辑。

于 2014-08-05T06:33:22.700 回答
0

在清单中,您已经注册了服务。

<service
android:name="com.example.zukami.apps.blynk.geofence.ReceiveTransitionsIntentService"
android:exported="true" >
</service>

但是您使用了广播接收器,所以那里可能是个问题。我不确定广播接收器,但使用 ReceiveTransitionIntent 它确实可以按照文档工作。

但是现在我被卡住了,因为当位置服务被禁用或设备重新启动时,我认为地理围栏已被删除,我无法在后台添加地理围栏。

于 2014-03-28T08:07:05.800 回答