Android地理围栏-没有出现意图?

7
我有一个奇怪的问题。
我使用Google服务实现了地理围栏。(下面是实现)
在我的设备上(Samsung Galaxy S和Moto X)它们运行得很好。但是在其他一些设备(HTC Incredible S,Galaxy Note)上,我收不到转换意图。从来没有。即使在围栏中心有着非常准确的GPS定位也是如此。日志中没有任何可疑的内容。没有错误,没有警告。没有意图,服务也不会启动。
有人见过这样的事情吗?(这很奇怪,因为我看不出能够区分它们工作和不工作的设备之间的任何联系。不是制造商,也不是Android版本,所有设备上的Play服务都是最新的。)
实现:
清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="test.package"
android:installLocation="auto"
android:versionCode="17"
android:versionName="1.1" >

<uses-sdk
    android:minSdkVersion="7"
    android:targetSdkVersion="19" />

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true" />


<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >

    <activity
        android:name="test.package.MainActivity"
        android:label="Compass"
        android:screenOrientation="portrait" />

    <service android:name="test.package.services.geofences.ShowNotificationService"
            android:label="@string/app_name"
            android:exported="false"/>

    <receiver android:name="test.package.services.geofences.UpdateGeofences">
        <intent-filter>
            <action android:name="test.package.updateGeofecnes"/>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

更新地理围栏:

 public class UpdateGeofences extends BroadcastReceiver implements
        GooglePlayServicesClient.ConnectionCallbacks,
        GooglePlayServicesClient.OnConnectionFailedListener,
        LocationClient.OnAddGeofencesResultListener,
        DataUpdateCallback {

    private LocationClient mLocationClient;
    private Context ctx;

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d("NOTICE", "Updating Geofences");
        ctx = context;
        mLocationClient = new LocationClient(context, this, this);
        mLocationClient.connect();
    }

    @Override
    public void onConnected(Bundle bundle) {
        GeofenceProvider geofenceProvider = new GeofenceProvider(ctx);
        geofenceProvider.open();

        //reactivate geofences
        List<Geofence> geofences = geofenceProvider.getActiveGeofences(mLocationClient.getLastLocation());
        Intent intent = new Intent(ctx, ShowNotificationService.class);
        PendingIntent pendingIntent = PendingIntent.getService(ctx, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        if (geofences.size() > 0) mLocationClient.addGeofences(geofences, pendingIntent, this);
        else mLocationClient.disconnect();
    }

    @Override
    public void onAddGeofencesResult(int i, String[] strings) {
        // If adding the geofences was successful
        if (LocationStatusCodes.SUCCESS != i) {
            Log.e("Geofences", "Error adding geofences: "+ Arrays.toString(strings)+ " Code: "+i);
        }
        mLocationClient.disconnect();
    }    
}

显示通知服务:

    public class ShowNotificationService extends IntentService {

    public ShowNotificationService() {
        super("ReceiveTransitionsIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Log.d("NOTICE", "Android geofence notification!");
        if (LocationClient.hasError(intent)) {
            int errorCode = LocationClient.getErrorCode(intent);
            Log.e("ReceiveTransitionsIntentService", "Location Services error: " + Integer.toString(errorCode));
            Crashlytics.logException(new RuntimeException("Location Services error: "+errorCode));
        } else {
            int transitionType = LocationClient.getGeofenceTransition(intent);
            if (transitionType == Geofence.GEOFENCE_TRANSITION_ENTER) { //ak vstupujem pozriem sa ci uz sa mi to nevyhodilo dnes
                List<Geofence> triggerList = LocationClient.getTriggeringGeofences(intent);
                Log.d("NOTICE", "Transition Enter");
                GeofenceProvider mProvider = new GeofenceProvider(this);
                mProvider.open();
                try {
                    for (Geofence geofence : triggerList) {
                        String id = geofence.getRequestId();
                        String[] data = id.split(MyGeofence.delimiter);
                        Log.d("NOTICE", "Show notification: "+id);
                        if (data.length != 3) {
                            Crashlytics.logException(new RuntimeException("Invalid geofence id: " + id + "Data: "+ Arrays.toString(data)));
                            continue;
                        }
                        if (mProvider.updateLastFire(Integer.valueOf(data[2]))) {
                            NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
                            builder.setContentTitle(data[0]);
                            builder.setContentText(data[1]);
                            builder.setSmallIcon(R.drawable.noticon);
                            Intent result = new Intent(this, CompassActivity.class);
                            PendingIntent pendingResult = PendingIntent.getActivity(this, 0, result, PendingIntent.FLAG_UPDATE_CURRENT);
                            builder.setContentIntent(pendingResult);
                            builder.setOngoing(false);
                            builder.setAutoCancel(true);
                            Notification not = builder.build();
                            not.defaults = Notification.DEFAULT_ALL;
                            NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                            int notID = Integer.valueOf(data[2]);
                            mNotificationManager.notify(notID, not);
                        }
                    }
                } catch (Exception e) {
                    Crashlytics.logException(e);
                    e.printStackTrace();
                } finally {
                    mProvider.close();
                }

            } else if(transitionType == Geofence.GEOFENCE_TRANSITION_EXIT) {    //ak odchadzam, oznacim to patricne v db
                List<Geofence> triggerList = LocationClient.getTriggeringGeofences(intent);
                Log.d("NOTICE", "Transition leave");
                GeofenceProvider mProvider = new GeofenceProvider(this);
                mProvider.open();
                try {
                    for (Geofence geofence : triggerList) {
                        String id = geofence.getRequestId();
                        String[] data = id.split(MyGeofence.delimiter);
                        if (data.length != 3) {
                            Crashlytics.logException(new RuntimeException("Invalid geofence id: " + id + "Data: "+ Arrays.toString(data)));
                            continue;
                        }
                        mProvider.invalidateLastFire(Integer.valueOf(data[2]));
                        Log.d("NOTICE", "Invalidate last fire: "+id);
                    }
                } catch (Exception e) {
                    Crashlytics.logException(e);
                    e.printStackTrace();
                } finally {
                    mProvider.close();
                }

            } else {    // An invalid transition was reported
                Log.e("ReceiveTransitionsIntentService", "Geofence transition error: " + Integer.toString(transitionType));
                Crashlytics.logException(new RuntimeException("Invalid geofence transition"));
            }
        }
    }
}

在 UpdateGeofences 中,我省略了连接到 PlayServices 所需的方法,因为它们基本上是从演示应用程序复制的,而且我在其他地方成功使用它们...

主活动并不重要,它只是在每次启动时发送广播以启动 UpdateGeofences。

GeofenceProvider 也不是问题,我在其他地方使用相同的代码没有问题。

1个回答

1
最终,我通过在ShowNotificationService中设置exported="true"来解决了这个问题。
就像这样:
<service android:name="test.package.services.geofences.ShowNotificationService"
        android:label="@string/app_name"
        android:exported="true"/>

似乎意图被错误的进程触发,导致安全错误。不确定为什么会发生这种情况...


你能告诉我在开发者网站提供的演示中,我需要在geofence2中放置什么经纬度和半径吗? - Amit Jayaswal
1
我不明白 android:exported="true" 怎么可能有任何影响! - IgorGanapolsky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接