I have a Service that uses a custom Connection class (extends thread) to a hardware controller. When the User prefers, I wish to maintain this connection on a permanent basis. I already have the code to handle when the Android device loses its internet connection, switches between wi-fi, etc.
In order to stay connected, the controller requires that you speak to it within every 5 minutes. I currently, within the Connection class start a thread that runs in a while(), and checks the system time and the last time it communicated, and when > 4 minutes it requests a status. For some reason, at different times the communication doesn’t occur in time. i.e., occurs after 5 minutes. The Service doesn’t die, as far as I can tell but the “Ping” to the controller is late. This doesn’t happen when I have the phone plugged into the charger (or debugger). Additionally, the behavior is the same when I move the Service to the foreground.
Does the phone slow down it’s processor when it goes to sleep?
Is there a better way?
I’m thinking it’s the AlarmManger, but I’m having trouble getting it to work with an inner-class, within the Service. I tried using the API demos as a starting point, but I can’t seem to figure out how to get the Broadcast receiver registered. I am trying to register the receiver programmatically, with no changes to the manifest.
public class DeviceConnectionService extends Service {
@Override
public void onCreate() {
Intent intent = new Intent(this, PingConnection.class);
intent.setAction("KEEP_CONNECTION_ALIVE");
PendingIntent sender = PendingIntent.getBroadcast(this,
0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// We want the alarm to go off 30 seconds from now.
long firstTime = SystemClock.elapsedRealtime();
firstTime += 15*1000;
// Schedule the alarm!
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
firstTime, 15*1000, sender);
// register to listen to the Alarm Manager
if (mPingConnectionReceiver == null) {
mPingConnectionReceiver = new PingConnection();
getApplicationContext().registerReceiver(mPingConnectionReceiver,
new IntentFilter("KEEP_CONNECTION_ALIVE"));
}
}
// ...
public class PingConnection extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (dBug) Log.i("PingConnection", "Pinging Controller");
// do real work here
}
}
}
The phone shuts down its processor when it goes to sleep. That is the definition of “sleep”.
That is an unusual approach for
AlarmManager. That being said, since you declined to describe “having trouble” in any detail, it is difficult to help you.Get rid of
getApplicationContext()(you don’t need it and really don’t want it in this case). I would register the receiver before touchingAlarmManager. Before you go to production, please choose an action name that has your package name in it (e.g.,com.something.myapp.KEEP_CONNECTION_ALIVE).Beyond that, check LogCat for warnings.
UPDATE
In your LogCat, you should have a warning from
AlarmManagercomplaining about not being able to talk to yourBroadcastReceiver.Replace:
with:
and you may have better luck.