Reputation: 613
I have problem when I'm trying to use geofence with my app. I have succeed to register geofence but I have never get the notification.
First I follow the example that provide in http://developer.android.com/training/location/geofencing.html ,but the code never trigger intent service even I'm walking toward or away from area.
My code for register geofence and calling the intent service as follow :
inside manifest :
<service
android:name="com.example.zukami.apps.blynk.geofence.ReceiveTransitionsIntentService"
android:exported="true" >
</service>
in my MainActivity
private boolean registerGeofence() {
mRequestType = GeofenceUtils.REQUEST_TYPE.ADD;
if (!servicesConnected()) {
return false;
}
SimpleGeofence testGeo = new SimpleGeofence(Flag.GEOFENCE + "_"
+ 1, Double.valueOf("1.317342"),
Double.valueOf("103.841998"), (float) (200),
GEOFENCE_EXPIRATION_IN_HOURS,
Geofence.GEOFENCE_TRANSITION_ENTER);
mPrefs.setGeofence(Flag.GEOFENCE + "_" + 1, testGeo);
mCurrentGeofences.add(testGeo.toGeofence());
SimpleGeofence testGeo2 = new SimpleGeofence(Flag.GEOFENCE + "_"
+ 2, Double.valueOf("1.303961"),
Double.valueOf("103.909356"), (float) (200),
GEOFENCE_EXPIRATION_IN_HOURS,
Geofence.GEOFENCE_TRANSITION_ENTER);
mPrefs.setGeofence(Flag.GEOFENCE + "_" + 2, testGeo2);
mCurrentGeofences.add(testGeo2.toGeofence());
// end deleted this code after testing
try {
mGeofenceRequester.addGeofences(mCurrentGeofences);
Log.e(TAG, "ADDING GEOFENCE ??? YES WE DID IT");
} catch (UnsupportedOperationException e) {
Toast.makeText(this,
R.string.add_geofences_already_requested_error,
Toast.LENGTH_LONG).show();
}
return true;
}
@Override
protected void onResume() {
super.onResume();
// Register the broadcast receiver to receive status updates
LocalBroadcastManager.getInstance(this).registerReceiver(mBroadcastReceiver, mIntentFilter);
in my GeofenceRequester
private PendingIntent createRequestPendingIntent() {
Log.e(TAG, "CREATE REQUEST PENDING INTENT");
// If the PendingIntent already exists
if (null != mGeofencePendingIntent) {
Log.e(TAG, "PENDING INTENT NOT NULL");
return mGeofencePendingIntent;
// If no PendingIntent exists
} else {
Log.e(TAG, "PENDING INTENT NULL, LET'S CREATED IT");
// Create an Intent pointing to the IntentService
Intent intent = new Intent(mActivity,
ReceiveTransitionsIntentService.class);
Log.e(TAG,
return PendingIntent.getService(mActivity, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
}
and in class that subclass from IntentService remain same as an example.
I do search for this problem and found this solutions that describe on this link : Android Geofence eventually stop getting transition intents ,so I change my code exactly as per suggestion, but still I cannot getting the notification, from my code inside GeofenceReceiver class, the code in this line
LocationClient.getGeofenceTransition(intent);
always return me -1 that means I never enter or leave the area (indicate GEOFENCE NEVER_EXPIRED),so I never get the notification. Please find below my GeofenceReceiver class :
public class GeofenceReceiver extends BroadcastReceiver {
public static String TAG = GeofenceReceiver.class.getCanonicalName();
Context context;
Intent broadcastIntent = new Intent();
@Override
public void onReceive(Context context, Intent intent) {
this.context = context;
broadcastIntent.addCategory(GeofenceUtils.CATEGORY_LOCATION_SERVICES);
if (LocationClient.hasError(intent)) {
handleError(intent);
} else {
handleEnterExit(intent);
}
}
private void handleError(Intent intent) {
int errorCode = LocationClient.getErrorCode(intent);
String errorMessage = LocationServiceErrorMessages.getErrorString(
context, errorCode);
Log.e(GeofenceUtils.APPTAG, context.getString(
R.string.geofence_transition_error_detail, errorMessage));
broadcastIntent.setAction(GeofenceUtils.ACTION_GEOFENCE_ERROR)
.putExtra(GeofenceUtils.EXTRA_GEOFENCE_STATUS, errorMessage);
LocalBroadcastManager.getInstance(context).sendBroadcast(
broadcastIntent);
}
private void handleEnterExit(Intent intent) {
int transition = LocationClient.getGeofenceTransition(intent);
// Test that a valid transition was reported
if ((transition == Geofence.GEOFENCE_TRANSITION_ENTER)
|| (transition == Geofence.GEOFENCE_TRANSITION_EXIT)) {
// Post a notification
List<Geofence> geofences = LocationClient
.getTriggeringGeofences(intent);
String[] geofenceIds = new String[geofences.size()];
String ids = TextUtils.join(GeofenceUtils.GEOFENCE_ID_DELIMITER,
geofenceIds);
String transitionType = getTransitionString(transition);
for (int index = 0; index < geofences.size(); index++) {
Geofence geofence = geofences.get(index);
geofenceIds[index] = geofences.get(index).getRequestId();
}
sendNotification(transitionType, ids);
// Create an Intent to broadcast to the app
broadcastIntent
.setAction(GeofenceUtils.ACTION_GEOFENCE_TRANSITION)
.addCategory(GeofenceUtils.CATEGORY_LOCATION_SERVICES)
.putExtra(GeofenceUtils.EXTRA_GEOFENCE_ID, geofenceIds)
.putExtra(GeofenceUtils.EXTRA_GEOFENCE_TRANSITION_TYPE,
transitionType);
LocalBroadcastManager.getInstance(context).sendBroadcast(
broadcastIntent);
// Log the transition type and a message
Log.e(GeofenceUtils.APPTAG, transitionType + ": " + ids);
Log.e(GeofenceUtils.APPTAG, context
.getString(R.string.geofence_transition_notification_text));
Log.e(GeofenceUtils.APPTAG, "transition");
} else {
// Always log as an error
Log.e(TAG, "TRANSITION = " + transition);
}
}
Kindly advise what should I do for fix this code and really appreciate for any kind help.
Upvotes: 3
Views: 4239
Reputation: 498
Beware: Geofences are indeed being removed when Location Provider Settings change or the device is restarted. Unfortunately the Android documentation doesn't mention this anywhere.
To counter this, you can register for a Boot-Completed Receiver and a Location Provider Changed Receiver:
<!-- Boot Completed Receiver -->
<receiver android:name="com.mydemoapp.geofencing.BootCompleteReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<!-- Location Service Provider Changed Receiver -->
<receiver android:name="com.mydemoapp.geofencing.LocationProviderChangedReceiver">
<intent-filter>
<action android:name="android.location.PROVIDERS_CHANGED" />
</intent-filter>
</receiver>
Inside these two BroadcastReceivers you can implement your logic of re-registering your previously deleted geofences.
Upvotes: 3
Reputation: 2110
for me I just changed some lines of code in createPendingIntent method
private PendingIntent createRequestPendingIntent() {
Log.e(TAG, "CREATE REQUEST PENDING INTENT");
// If the PendingIntent already exists
if (null != mGeofencePendingIntent) {
Log.e(TAG, "PENDING INTENT NOT NULL");
return mGeofencePendingIntent;
// If no PendingIntent exists
} else {
Log.e(TAG, "PENDING INTENT NULL, LET'S CREATED IT");
// Create an Intent pointing to the IntentService
Intent intent = new Intent(mActivity,
ReceiveTransitionsIntentService.class);
Log.e(TAG,
return PendingIntent.getService(mActivity, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
}
So in place of return PendingIntent.getService(mActivity, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
use this piece of cake return PendingIntent.getBroadcast(mActivity, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
and make sure you have declared your BroadcastReceiver in application manisfest file.Good luck!!!!
Upvotes: 5
Reputation: 41
In the Manifest you have registered the Service.
<service
android:name="com.example.zukami.apps.blynk.geofence.ReceiveTransitionsIntentService"
android:exported="true" >
</service>
But you have used broadcast receiver so can be an issue there. I am not sure about the broadcast receiver but with ReceiveTransitionIntent it does work as per the documentation.
However now i am stuck because when Location Service is Disabled or When Device is restarted i think Geofences are removed and I am not able to Add the Geofences back in Background.
Upvotes: 0