I have a strange problem.
I implemented geo-service using Google services. (Implementation below) On my devices (Samsung Galaxy S and Moto X) they work perfectly. On some other devices (HTC Incredible S, Galaxy Note) I do not receive any changes. Never. With an excellent, accurate GPS lock in the middle of the fence. Nothing. Nothing suspicious in the magazines. No errors, no warnings. No attacks come, the service does not start.
Has anyone ever seen this? (This is strange because I do not see any connection between devices that work and devices that do not. This is not a manufacturer, this is not a version of Android, Play Services was aware of all of them.)
Implementation:
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 geoprocessing:
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();
Show notification service:
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")); } } } }
In UpdateGeofences, I skipped the methods needed to connect to PlayServices, since they are mainly copied from the demo application, and I successfully use them in other places ...
The core activity doesn't matter, it just sends a broadcast to launch UpdateGeofences every time it starts.
GeofenceProvider is also not a problem, I use the same code elsewhere without problems.