基于Android 10.11 实现的Service服务保活
最近公司要实现app程序不被杀死 实现持续定位,在网上看了很多个文章 也看到双进程保活,我忘了在那看到这篇文章了
下面 具体显现
创建 MyService 集成 service 服务
public class MyService extends Service {
private final static String TAG = MyService.class.getSimpleName();
// 启动notification的id,两次启动应是同一个id
private final static int NOTIFICATION_ID = android.os.Process.myPid();
private AssistServiceConnection mServiceConnection;
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
public void onCreate() {
super.onCreate();
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
//数字是随便写的“40”,
nm.createNotificationChannel(new NotificationChannel("40", "App Service", NotificationManager.IMPORTANCE_DEFAULT));
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "40");
//其中的2,是也随便写的,正式项目也是随便写
startForeground(2 ,builder.build());
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 测试线程,判断Service是否在工作
new Thread(mRunnable).start();
// 设置为前台进程,降低oom_adj,提高进程优先级,提高存活机率
setForeground();
return START_STICKY;
}
// 要注意的是android4.3之后Service.startForeground() 会强制弹出通知栏,解决办法是再
// 启动一个service和推送共用一个通知栏,然后stop这个service使得通知栏消失。
private void setForeground() {
if (Build.VERSION.SDK_INT < 18)
{
startForeground(NOTIFICATION_ID, getNotification());
return;
}
if (mServiceConnection == null)
{
mServiceConnection = new AssistServiceConnection();
}
// 绑定另外一条Service,目的是再启动一个通知,然后马上关闭。以达到通知栏没有相关通知
// 的效果
bindService(new Intent(this, AssistService.class), mServiceConnection,
Service.BIND_AUTO_CREATE);
}
private class AssistServiceConnection implements ServiceConnection
{
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Service assistService = ((AssistService.LocalBinder)service)
.getService();
MyService.this.startForeground(NOTIFICATION_ID, getNotification());
assistService.startForeground(NOTIFICATION_ID, getNotification());
assistService.stopForeground(true);
MyService.this.unbindService(mServiceConnection);
mServiceConnection = null;
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
private Notification getNotification()
{
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "")
.setContentTitle("服务运行于前台")
.setContentText("service被设为前台进程")
.setTicker("service正在后台运行...")
.setPriority(NotificationCompat.PRIORITY_MAX)
.setWhen(System.currentTimeMillis())
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setContentIntent(pendingIntent);
Notification notification = builder.build();
notification.flags = Notification.FLAG_AUTO_CANCEL;
return notification;
}
Runnable mRunnable = new Runnable() {
@Override
public void run() {
while (true)
{
Log.e(TAG+1111, "" + System.currentTimeMillis());
发送广播
Intent intent=new Intent();
//指定广播的名字
intent.setAction("com.yy.time.TIME_CHANGED_ACTION");
//指定广播的内容
// 此行 对8.0以上广播接受不到 增加处理 “包名” ,“广播地址” intent.setComponent( new ComponentName( "com.example.webwebsocket" ,
"com.example.webwebsocket.Service.UITimeReceiver") );
try {
intent.setComponent( new ComponentName( "com.example.webwebsocket" ,
"com.example.webwebsocket.Service.UITimeReceiver") );
//此处我传递了值 你们不传递也行
intent.putExtra("time",getTime());
} catch (ParseException e) {
e.printStackTrace();
}
//发送广播
sendBroadcast(intent);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
@Override
public void onDestroy() {
super.onDestroy();
stopForeground(true);
}
}
再创建 AssistService 一个类也集成service服务
public class AssistService extends Service {
public AssistService() {
}
public class LocalBinder extends Binder
{
public AssistService getService()
{
return AssistService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return new LocalBinder();
}
}
在AndroidManifest.xml 清单文件里注册service服务 和一个广播
<service android:name=".Service.MyService"></service>
<!--注册广播-->
<receiver
android:name=".Service.UITimeReceiver"
android:exported="false">
<intent-filter>
<action android:name="com.yy.time.TIME_CHANGED_ACTION" />
</intent-filter>
</receiver>
在创建一个广播接收器 利用广播传递消息
public class UITimeReceiver extends BroadcastReceiver {
private Context mContext;
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(MainActivity.TIME_CHANGED_ACTION.equals(action)){
//此处处理你需要处理的逻辑 我写的接口回调 具体看个人需求
}
}
}
在MainActivity使用注册启动service 服务 此处做个Android版本判断 否则会出错
//开启服务做兼容处理
Intent intentOne = new Intent(this, MyService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(intentOne);
} else {
startService(intentOne);
}
完毕
我觉得直接复制就好 完成用不上demo 本人亲测 Android10 .11 oppo 小米机型 保活24小时 再往常的时间没试,大家可以试试 ,可以给楼主反馈。