7

У меня странная проблема.Android Geofencing - Нет намерений?

Я применил геообслуживание с помощью Служб Google. (Реализация ниже) На моих устройствах (Samsung Galaxy S и Moto X) они работают идеально. На некоторых других устройствах (HTC Incredible S, Galaxy Note) я не получаю никаких изменений. Никогда. С отличным, точным GPS-фиксатором, стоящим посреди забора. Ничего. Ничего подозрительного в журналах. Нет ошибок, никаких предупреждений. Никаких приключений не приходит, сервис не начинается.

Кто-нибудь когда-нибудь видел такую ​​вещь? (Это странно, потому что я не вижу никакой связи между устройствами, которые работают, и устройствами, которые этого не делают. Это не производитель, это не версия для Android, Play Services были в курсе всех из них.)

Внедрение:

Manifest:

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

Update Геозоны:

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

В конечном счете, мне удалось исправить это, установив exported = "true" в ShowNofiticationService.

Как это:

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

Кажется, что намерения были уволены процессом с неправильным идентификатором, и что coused ошибка безопасности. Не знаю, почему это произойдет, хотя ...

+0

не могли бы вы рассказать мне, какой лат длинный и радиус мне нужно положить в geofence2, в демо, который доступен на сайте develoer. ? –

+1

Я не вижу, как андроид: exported = "true" может иметь какое-либо значение! –