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」會如何改變! –