概述
转自http://blog.csdn.net/ameyume/article/details/9150755
版权声明:本文为博主原创文章,未经博主允许不得转载。
Service如果要防止尽可能不被系统杀掉,需要设置为在前台运行。
由于设置前台运行service的方法在2.0之前和2.0之后有所变化。
所以需要根据不同的版本进行区分;或者完全使用反射机制来处理,这样只要有相应的方法就可以使用,否则使用其他版本的方法。
下面是一个设置servcie前台运行的例子,参考了API中对Service的说明。
http://developer.android.com/reference/android/app/Service.html#
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import android.app.Notification;
- import android.app.NotificationManager;
- import android.app.PendingIntent;
- import android.app.Service;
- import android.content.Context;
- import android.content.Intent;
- import android.os.IBinder;
- import android.os.Build.VERSION;
- import android.util.Log;
- public class ForegroundService extends Service {
- private static final String TAG = "ForegroundService";
- private boolean mReflectFlg = false;
- private static final int NOTIFICATION_ID = 1; // 如果id设置为0,会导致不能设置为前台service
- private static final Class<?>[] mSetForegroundSignature = new Class[] {
- boolean.class};
- 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 mSetForeground;
- private Method mStartForeground;
- private Method mStopForeground;
- private Object[] mSetForegroundArgs = new Object[1];
- private Object[] mStartForegroundArgs = new Object[2];
- private Object[] mStopForegroundArgs = new Object[1];
- @Override
- public void onCreate() {
- super.onCreate();
- Log.d(TAG, "onCreate");
- mNM = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
- try {
- mStartForeground = ForegroundService.class.getMethod("startForeground", mStartForegroundSignature);
- mStopForeground = ForegroundService.class.getMethod("stopForeground", mStopForegroundSignature);
- } catch (NoSuchMethodException e) {
- mStartForeground = mStopForeground = null;
- }
- try {
- mSetForeground = getClass().getMethod("setForeground",
- mSetForegroundSignature);
- } catch (NoSuchMethodException e) {
- throw new IllegalStateException(
- "OS doesn't have Service.startForeground OR Service.setForeground!");
- }
- Notification.Builder builder = new Notification.Builder(this);
- PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
- new Intent(this, MainActivity.class), 0);
- builder.setContentIntent(contentIntent);
- builder.setSmallIcon(R.drawable.icon);
- builder.setTicker("Foreground Service Start");
- builder.setContentTitle("Foreground Service");
- builder.setContentText("Make this service run in the foreground.");
- Notification notification = builder.build();
- startForegroundCompat(NOTIFICATION_ID, notification);
- }
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- super.onStartCommand(intent, flags, startId);
- Log.d(TAG, "onStartCommand");
- return START_STICKY;
- }
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
- @Override
- public void onDestroy() {
- super.onDestroy();
- Log.d(TAG, "onDestroy");
- stopForegroundCompat(NOTIFICATION_ID);
- }
- void invokeMethod(Method method, Object[] args) {
- try {
- method.invoke(this, args);
- } catch (InvocationTargetException e) {
- // Should not happen.
- Log.w("ApiDemos", "Unable to invoke method", e);
- } catch (IllegalAccessException e) {
- // Should not happen.
- Log.w("ApiDemos", "Unable to invoke method", e);
- }
- }
- /**
- * This is a wrapper around the new startForeground method, using the older
- * APIs if it is not available.
- */
- void startForegroundCompat(int id, Notification notification) {
- if (mReflectFlg) {
- // If we have the new startForeground API, then use it.
- if (mStartForeground != null) {
- mStartForegroundArgs[0] = Integer.valueOf(id);
- mStartForegroundArgs[1] = notification;
- invokeMethod(mStartForeground, mStartForegroundArgs);
- return;
- }
- // Fall back on the old API.
- mSetForegroundArgs[0] = Boolean.TRUE;
- invokeMethod(mSetForeground, mSetForegroundArgs);
- mNM.notify(id, notification);
- } else {
- /* 还可以使用以下方法,当sdk大于等于5时,调用sdk现有的方法startForeground设置前台运行,
- * 否则调用反射取得的sdk level 5(对应Android 2.0)以下才有的旧方法setForeground设置前台运行 */
- if(VERSION.SDK_INT >= 5) {
- startForeground(id, notification);
- } else {
- // Fall back on the old API.
- mSetForegroundArgs[0] = Boolean.TRUE;
- invokeMethod(mSetForeground, mSetForegroundArgs);
- mNM.notify(id, notification);
- }
- }
- }
- /**
- * This is a wrapper around the new stopForeground method, using the older
- * APIs if it is not available.
- */
- void stopForegroundCompat(int id) {
- if (mReflectFlg) {
- // If we have the new stopForeground API, then use it.
- if (mStopForeground != null) {
- mStopForegroundArgs[0] = Boolean.TRUE;
- invokeMethod(mStopForeground, mStopForegroundArgs);
- 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);
- mSetForegroundArgs[0] = Boolean.FALSE;
- invokeMethod(mSetForeground, mSetForegroundArgs);
- } else {
- /* 还可以使用以下方法,当sdk大于等于5时,调用sdk现有的方法stopForeground停止前台运行,
- * 否则调用反射取得的sdk level 5(对应Android 2.0)以下才有的旧方法setForeground停止前台运行 */
- if(VERSION.SDK_INT >= 5) {
- stopForeground(true);
- } else {
- // 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);
- mSetForegroundArgs[0] = Boolean.FALSE;
- invokeMethod(mSetForeground, mSetForegroundArgs);
- }
- }
- }
- }
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.os.Build.VERSION;
import android.util.Log;
public class ForegroundService extends Service {
private static final String TAG = "ForegroundService";
private boolean mReflectFlg = false;
private static final int NOTIFICATION_ID = 1; // 如果id设置为0,会导致不能设置为前台service
private static final Class<?>[] mSetForegroundSignature = new Class[] {
boolean.class};
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 mSetForeground;
private Method mStartForeground;
private Method mStopForeground;
private Object[] mSetForegroundArgs = new Object[1];
private Object[] mStartForegroundArgs = new Object[2];
private Object[] mStopForegroundArgs = new Object[1];
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate");
mNM = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
try {
mStartForeground = ForegroundService.class.getMethod("startForeground", mStartForegroundSignature);
mStopForeground = ForegroundService.class.getMethod("stopForeground", mStopForegroundSignature);
} catch (NoSuchMethodException e) {
mStartForeground = mStopForeground = null;
}
try {
mSetForeground = getClass().getMethod("setForeground",
mSetForegroundSignature);
} catch (NoSuchMethodException e) {
throw new IllegalStateException(
"OS doesn't have Service.startForeground OR Service.setForeground!");
}
Notification.Builder builder = new Notification.Builder(this);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class), 0);
builder.setContentIntent(contentIntent);
builder.setSmallIcon(R.drawable.icon);
builder.setTicker("Foreground Service Start");
builder.setContentTitle("Foreground Service");
builder.setContentText("Make this service run in the foreground.");
Notification notification = builder.build();
startForegroundCompat(NOTIFICATION_ID, notification);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Log.d(TAG, "onStartCommand");
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
stopForegroundCompat(NOTIFICATION_ID);
}
void invokeMethod(Method method, Object[] args) {
try {
method.invoke(this, args);
} catch (InvocationTargetException e) {
// Should not happen.
Log.w("ApiDemos", "Unable to invoke method", e);
} catch (IllegalAccessException e) {
// Should not happen.
Log.w("ApiDemos", "Unable to invoke method", e);
}
}
/**
* This is a wrapper around the new startForeground method, using the older
* APIs if it is not available.
*/
void startForegroundCompat(int id, Notification notification) {
if (mReflectFlg) {
// If we have the new startForeground API, then use it.
if (mStartForeground != null) {
mStartForegroundArgs[0] = Integer.valueOf(id);
mStartForegroundArgs[1] = notification;
invokeMethod(mStartForeground, mStartForegroundArgs);
return;
}
// Fall back on the old API.
mSetForegroundArgs[0] = Boolean.TRUE;
invokeMethod(mSetForeground, mSetForegroundArgs);
mNM.notify(id, notification);
} else {
/* 还可以使用以下方法,当sdk大于等于5时,调用sdk现有的方法startForeground设置前台运行,
* 否则调用反射取得的sdk level 5(对应Android 2.0)以下才有的旧方法setForeground设置前台运行 */
if(VERSION.SDK_INT >= 5) {
startForeground(id, notification);
} else {
// Fall back on the old API.
mSetForegroundArgs[0] = Boolean.TRUE;
invokeMethod(mSetForeground, mSetForegroundArgs);
mNM.notify(id, notification);
}
}
}
/**
* This is a wrapper around the new stopForeground method, using the older
* APIs if it is not available.
*/
void stopForegroundCompat(int id) {
if (mReflectFlg) {
// If we have the new stopForeground API, then use it.
if (mStopForeground != null) {
mStopForegroundArgs[0] = Boolean.TRUE;
invokeMethod(mStopForeground, mStopForegroundArgs);
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);
mSetForegroundArgs[0] = Boolean.FALSE;
invokeMethod(mSetForeground, mSetForegroundArgs);
} else {
/* 还可以使用以下方法,当sdk大于等于5时,调用sdk现有的方法stopForeground停止前台运行,
* 否则调用反射取得的sdk level 5(对应Android 2.0)以下才有的旧方法setForeground停止前台运行 */
if(VERSION.SDK_INT >= 5) {
stopForeground(true);
} else {
// 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);
mSetForegroundArgs[0] = Boolean.FALSE;
invokeMethod(mSetForeground, mSetForegroundArgs);
}
}
}
}
前台Service运行后的效果如图:
(1).通知栏显示内容:
(2).下拉后通知栏显示内容:
最后
以上就是细心篮球为你收集整理的Android创建前台运行的Service的全部内容,希望文章能够帮你解决Android创建前台运行的Service所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复