I'm trying to construct a geofencing app, but it seems to only register geofences when the main activity started, and the intent service stops receiving them when the app is closed. So, I moved the add geofence logic into the intent service (along with the intent handling code) and make sure that service gets started, but now the service doesn't get receive any intents at all!
Service definition
public class GeofenceTransitionsIntentService extends IntentService implements ConnectionCallbacks, OnConnectionFailedListener, ResultCallback<Status>
Everything in the service (google api client built and connected) is done in onCreate
, with both the intent handlers and the geofence registration stuff onConnected
registers geofences, etc. Basically, I've tried to implement heavily borrowed geofencing sample code (from the docs) in the same service intended to handle those intents.
All the main activity does is starts the service and draws things related to the geofence notifications received in the service.
If you need more info, just let me know.
edit
Ok so it seems like we need more information -- an outline of the service:
public class GeofenceTransitionsIntentService extends IntentService implements ConnectionCallbacks, OnConnectionFailedListener, ResultCallback<Status> {
protected static final String TAG = "GeofenceTransitionsIS";
protected GoogleApiClient mGoogleApiClient;
protected ArrayList<Geofence> mGeofenceList;
private boolean mGeofencesAdded;
private PendingIntent mGeofencePendingIntent;
private SharedPreferences mSharedPreferences;
public GeofenceTransitionsIntentService() {
super(TAG);
}
@Override
public void onCreate() {
super.onCreate();
buildGoogleApiClient();
populateGeofenceList();
mGoogleApiClient.connect();
}
...
@Override
protected void onHandleIntent(Intent intent) {
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
// handle the intent, send a notification
}
private void sendNotification(String notificationDetails) {
// sends a notification
}
@Override
public void onConnected(Bundle connectionHint)
{
LocationServices.GeofencingApi.addGeofences(
mGoogleApiClient,
getGeofencingRequest(),
getGeofencePendingIntent()
).setResultCallback(this);
}
// straight out of the example
private GeofencingRequest getGeofencingRequest()
{
...
}
// from a branch of the example that reuses the pending intent
private PendingIntent getGeofencePendingIntent()
{
if (mGeofencePendingIntent != null)
{
return mGeofencePendingIntent;
}
Intent intent = new Intent(this, GeofenceTransitionsIntentService.class);
mGeofencePendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return mGeofencePendingIntent;
}
public void populateGeofenceList() {
for (thing place : listofplaces) {
mGeofenceList.add(...)
}
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
public void onResult(Status status)
{
// were fences added? usually yes
}
}
My research has been frustrating -- I see people claiming to be able to do something like this from a broadcast receiver (see first comment) but not from a service?
I have a pretty mangled manifest.xml from all the revisions I've been working through:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<application
android:allowBackup="true"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<service android:name=".GeofenceTransitionsIntentService"
android:exported="true"
android:enabled="true">
<intent-filter >
<action android:name="com.aol.android.geofence.ACTION_RECEIVE_GEOFENCE"/>
</intent-filter>
</service>
...
</application>
Neither adding the intent-filter
nor the android:exported="true"
to the service definition helped at all.