If you can tell on a shutdown event occurs, and since you can subscribe for the "ON-BOOT-COMPLETED" event - why not combine both of them?
Save the date on your app SharedPrefernces for the last time a "Shutdown" event happened - after a "On boot completed" event compare the date to the one's saved - if the time difference is lower than (per say) 5 minutes do your "restart" action.
I added a code example which works for me (galaxy S4 running android 4.3) I dont have the main activitis but those are not necessary for your example (just throw a blank one or copy the service and bootloader to yours...) -
manifest -
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.servicelifecycle"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".StartedServiceActivity"
android:label="@string/title_activity_main" >
</activity>
<service android:name=".StartedService" >
</service>
<service android:name="BoundService" >
</service>
<activity android:name="BoundServiceActivity" >
</activity>
<activity android:name="MainActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="BoundedServiceUsingMessangerInterface" >
</service>
<activity android:name="MessangerServiceActivity" >
</activity>
<activity android:name="IntentServiceActivity" >
</activity>
<service android:name="IntentServiceDemo" >
</service>
<service android:name="ForeGroundServiceDemo" >
</service>
<activity android:name="ForeGroundServiceActivity" >
</activity>
<activity android:name=".AIDLActivity" >
</activity>
<service
android:name="BoundedServiceUsingAIDL"
android:exported="false" >
<intent-filter>
<action android:name="com.example.bindservice.AIDL" />
</intent-filter>
</service>
<receiver android:name=".BootCompletedReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
Service -
package com.example.servicelifecycle;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class StartedService extends Service {
private static final String tag = StartedService.class.getSimpleName();
Timer timer;
ToastHandler t;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
t = new ToastHandler(getApplicationContext());
t.showToast(tag + " onCreate", 3000);
Log.d(tag, "onCreate");
timer = new Timer();
timer.scheduleAtFixedRate(new RemindTask(), 10000, 6000);
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
t.showToast(tag + " onCreate", 3000);
Log.d(tag, "onStartCommand startId=" + startId);
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
timer.cancel();
Log.d(tag, "onDestroy");
super.onDestroy();
}
@Override
public boolean onUnbind(Intent intent) {
t.showToast(tag + " onCreate", 3000);
Log.d(tag, "onUnbind");
return super.onUnbind(intent);
}
class RemindTask extends TimerTask {
public void run() {
t.play();
}
}
}
BootReciever -
package com.example.servicelifecycle;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class BootCompletedReceiver extends BroadcastReceiver {
final static String TAG = BootCompletedReceiver.class.getSimpleName();
@Override
public void onReceive(Context context, Intent intent) {
Log.w(TAG, "starting service...");
context.startService(new Intent(context, StartedService.class));
}
}
Some example task to be run
package com.example.servicelifecycle;
import android.content.Context;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Handler;
import android.widget.Toast;
/**
* A class for showing a <code>Toast</code> from background processes using a
* <code>Handler</code>.
*
* @author kaolick
*/
public class ToastHandler {
// General attributes
private Context mContext;
private Handler mHandler;
/**
* Class constructor.
*
* @param _context
* The <code>Context</code> for showing the <code>Toast</code>
*/
public ToastHandler(Context _context) {
this.mContext = _context;
this.mHandler = new Handler();
}
/**
* Runs the <code>Runnable</code> in a separate <code>Thread</code>.
*
* @param _runnable
* The <code>Runnable</code> containing the <code>Toast</code>
*/
private void runRunnable(final Runnable _runnable) {
Thread thread = new Thread() {
public void run() {
mHandler.post(_runnable);
}
};
thread.start();
thread.interrupt();
thread = null;
}
/**
* Shows a <code>Toast</code> using a <code>Handler</code>. Can be used in
* background processes.
*
* @param _resID
* The resource id of the string resource to use. Can be
* formatted text.
* @param _duration
* How long to display the message. Only use LENGTH_LONG or
* LENGTH_SHORT from <code>Toast</code>.
*/
public void showToast(final int _resID, final int _duration) {
final Runnable runnable = new Runnable() {
@Override
public void run() {
// Get the text for the given resource ID
String text = mContext.getResources().getString(_resID);
Toast.makeText(mContext, text, _duration).show();
}
};
runRunnable(runnable);
}
/**
* Shows a <code>Toast</code> using a <code>Handler</code>. Can be used in
* background processes.
*
* @param _text
* The text to show. Can be formatted text.
* @param _duration
* How long to display the message. Only use LENGTH_LONG or
* LENGTH_SHORT from <code>Toast</code>.
*/
public void showToast(final CharSequence _text, final int _duration) {
final Runnable runnable = new Runnable() {
@Override
public void run() {
Toast.makeText(mContext, _text, _duration).show();
}
};
runRunnable(runnable);
}
/**
* Shows a <code>Toast</code> using a <code>Handler</code>. Can be used in
* background processes.
*
* @param _text
* The text to show. Can be formatted text.
* @param _duration
* How long to display the message. Only use LENGTH_LONG or
* LENGTH_SHORT from <code>Toast</code>.
*/
public void play() {
final Runnable runnable = new Runnable() {
@Override
public void run() {
playSound();
}
};
runRunnable(runnable);
}
private void playSound() {
MediaPlayer mp;
// mp = MediaPlayer.create(mContext,);
mp = MediaPlayer.create(mContext, R.raw.click);
mp.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
mp.release();
}
});
mp.setVolume(100, 100);
mp.start();
}
}
PS - If you want - send me an email address and Ill send you the whole project.