I have a IntentService
that does a long work, it takes about 15 minutes to be done. It is a synchronization process to get new data from my server.
When this service starts, I start a activity too, to display the progess.
This activity creates a BroadcastReceiver
, that intercepts messages sent from the service about the process progress.
If I leave the app doing it job, after a while the SO switch off the screen.
When I switch on the screen again, after about 15 minutes, the service has been already done, but the progress appears to be out of date. The BroadcastReceiver
has stopped to work, and my END OF SYNCHRONIZATION
message hasn't been received by the activity.
The problem is that, at this message I start the main activity again to leave the user to use the app again.
How can I solve this?
Broadcast Receivers are not made to do long duration work.
The lifetime of a broadcast receiver lasts about 10-15 seconds.
A recommended or typical use of a broadcast receiver is to
- Start a service
- Show a Toast
- Start an Activity
In your case you should start a service from your broadcast Receiver and do all the work in that service.
I solved with this http://developer.android.com/intl/pt-br/guide/components/services.html#Foreground .
My service
public class MyService extends Service {
public interface MyCallback {
void onProgress(int progress);
}
public class MyBinder {
public MyService getService() {
return MyService.this;
}
}
public IBinder onBind(Intent intent) {
return new MyBinder();
}
public void make(MyCallback callback) {
Notification n = new Notification.Builder(this)
.setContentTitle("Processing")
.getNotification();
startForeground(666 /*some ID*/, n);
try {
callback.onProgress(0);
// do the hard sutff and report progress
callback.onProgress(100); // report 100%
} finally {
stopForeground(true);
}
}
}
My activity
public MyActivity extends Activity implements ServiceConnection, MyService.MyCallback {
@Override
protected onStart() {
super.onStart();
// 1 - bind service to this activity
Intent i = new Intent(this, MyService.class);
this.bindService(i, this, BIND_AUTO_CREATE);
}
@Override
public void onServiceConnected(ComponentName componentName, final IBinder iBinder) {
// 2 - when the service was binded, starts the process asynchronous
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids) {
((MyService.MyBinder) iBinder).getService().make(MyActivity.this);
return null;
}
}.execute();
}
@Override
public void onProgress(int progress) {
// 3 - when to callback is fired, update the UI progress bar
runOnUiThread(new Runnable() {
@Override
public void run() {
// call ProgressBar.setProgress(progress);
}
});
}
}