7

我有一个奇怪的问题。Android Geofencing - 没有即将到来的意图?

我使用Google Services实施了地理围栏。 (执行如下) 在我的设备上(Samsung Galaxy S和Moto X),它们的工作非常完美。在其他一些设备上(HTC Incredible S,Galaxy Note),我没有收到过渡意图。决不。通过精确的GPS定位,站在栅栏中间。没有。在日志中没有可疑的东西。没有错误,没有警告。没有迭代,服务没有启动。

有没有人见过这样的事情? (这很奇怪,因为我看不到任何工作的设备和没有工作的设备之间的任何连接,它不是制造商,它不是Android版本,Play Services在所有设备上都是最新的。)

执行:

清单:

<?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

最后,我设法通过在ShowNofiticationService中设置exported =“true”来解决这个问题。

像这样:

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

它似乎意图通过使用进程ID错误解雇,并致毒安全错误。不知道为什么会发生,虽然...

+0

你能告诉我什么拉长和半径我需要把geofence2,在demoer这是可以在developer网站。 ? –

+1

我不明白android:exported =“true”会如何改变! –