Created
March 4, 2010 13:59
-
-
Save Gautier/321717 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.fryit.snapexpense; | |
import java.lang.reflect.InvocationTargetException; | |
import java.lang.reflect.Method; | |
import android.app.Notification; | |
import android.app.NotificationManager; | |
import android.app.Service; | |
import android.util.Log; | |
/** | |
* This class largely inspired from a post of android devs. | |
* | |
* It ensure that we can put the service in a foreground state (so that it | |
* doesn't get killed) in < 2.0 and > 2.0 Android APIs. | |
* | |
* See: http://android-developers.blogspot.com/2010/02/service-api-changes-starting-with.html | |
*/ | |
public abstract class BetterService extends Service { | |
private static final String TAG = BetterService.class.getName(); | |
private static final Class[] mStartForegroundSignature = new Class[] { | |
int.class, Notification.class}; | |
private static final Class[] mStopForegroundSignature = new Class[] { | |
boolean.class}; | |
private NotificationManager mNM; | |
private Method mStartForeground; | |
private Method mStopForeground; | |
private Object[] mStartForegroundArgs = new Object[2]; | |
private Object[] mStopForegroundArgs = new Object[1]; | |
private boolean checked = false; | |
/** | |
* Lazy checking of Service foreground API level | |
*/ | |
public void checkServiceNotificationAPILevel() { | |
// only need to check once | |
if (checked){ | |
return; | |
} | |
checked = true; | |
mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); | |
try { | |
mStartForeground = getClass().getMethod("startForeground", | |
mStartForegroundSignature); | |
mStopForeground = getClass().getMethod("stopForeground", | |
mStopForegroundSignature); | |
} catch (NoSuchMethodException e) { | |
// Running on an older platform. | |
mStartForeground = mStopForeground = null; | |
} | |
} | |
/** | |
* This is a wrapper around the new startForeground method, using the older | |
* APIs if it is not available. | |
*/ | |
protected void startForegroundCompat(int id, Notification notification) { | |
checkServiceNotificationAPILevel(); | |
// If we have the new startForeground API, then use it. | |
if (mStartForeground != null) { | |
mStartForegroundArgs[0] = Integer.valueOf(id); | |
mStartForegroundArgs[1] = notification; | |
try { | |
mStartForeground.invoke(this, mStartForegroundArgs); | |
} catch (InvocationTargetException e) { | |
// Should not happen. | |
Log.w(TAG, "Unable to invoke startForeground", e); | |
} catch (IllegalAccessException e) { | |
// Should not happen. | |
Log.w(TAG, "Unable to invoke startForeground", e); | |
} | |
return; | |
} | |
// Fall back on the old API. | |
setForeground(true); | |
mNM.notify(id, notification); | |
} | |
/** | |
* This is a wrapper around the new stopForeground method, using the older | |
* APIs if it is not available. | |
*/ | |
protected void stopForegroundCompat(int id) { | |
checkServiceNotificationAPILevel(); | |
// If we have the new stopForeground API, then use it. | |
if (mStopForeground != null) { | |
mStopForegroundArgs[0] = Boolean.TRUE; | |
try { | |
mStopForeground.invoke(this, mStopForegroundArgs); | |
} catch (InvocationTargetException e) { | |
// Should not happen. | |
Log.w(TAG, "Unable to invoke stopForeground", e); | |
} catch (IllegalAccessException e) { | |
// Should not happen. | |
Log.w(TAG, "Unable to invoke stopForeground", e); | |
} | |
return; | |
} | |
// Fall back on the old API. Note to cancel BEFORE changing the | |
// foreground state, since we could be killed at that point. | |
mNM.cancel(id); | |
setForeground(false); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment