Service设置前台服务&提高优先级
来源:互联网 发布:c语言的主函数类型 编辑:程序博客网 时间:2024/06/05 18:53
就一点,希望大神指正本文中的错误,谢谢!有哪里我没写的或者写漏了的地方也欢迎提出来,谢谢大佬们。
1.啥是前台服务?
555,我的图片被吃了…其实所谓的前台服务就是在Service中发送了一个通知。
2.怎么设为前台服务呢?
在你的服务的onStartCommand方法里写如下代码就好了
构建Notification有两种方式,一种用于API11之后,一种用于API16之后:
@Override public int onStartCommand(Intent intent, int flags, int startId) { //api11的写法 Notification.Builder builder = new Notification.Builder(this.getApplicationContext()); //intent指定点击Notification后跳转的Activity Intent intent = new Intent(this,MainActivity.class); builder.setContentIntent() .setLargeIcon(BitmapFactory.decodeResource(this.getResources(), R.mipmap.ic_launcher)) // 设置下拉列表里的标题 title icon text为必需选项,这三项不设置通知不会显示。 .setContentTitle("Title") // 设置状态栏内的小图标 .setSmallIcon(R.mipmap.ic_launcher) // 设置上下文内容 .setContentText("content") // 设置该通知发生的时间 .setWhen(System.currentTimeMillis()); //设置前台服务点击后的动作(这里就是点击跳到MainActivity) .setContentIntent(PendingIntent.getActivity(this, 0, intent , 0)) // 获取构建好的Notification Notification notification = builder.getNotification(); //第一个参数是通知的唯一标识id,后面就是我们的通知 startForeground(12346, notification); //API16之后的写法 Intent notificationIntent = new Intent(this, MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); Notification notification = new Notification.Builder(this) .setContentTitle("Title") .setContentText("Message") .setSmallIcon(R.mipmap.ic_launcher) .setContentIntent(pendingIntent) .build(); startForeground(12346, notification ); return START_STICKY; }
提示用户去开启通知
但是有很多机型(比如说oppo)安装app的时候默认是没有发送通知的权限的,只能由用户手动去开启,而用户一般来说是不知道你需要发送通知的,在userPermission中也没有对应的权限名称,因此我们只能自己去申请权限,让用户开启,不然你的通知是没法显示的。
package com.example.servicedemo;import android.annotation.SuppressLint;import android.app.AppOpsManager;import android.content.Context;import android.content.pm.ApplicationInfo;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;/** * Created by LZC on 2017/9/20. */public class NotificationUtil { private static final String CHECK_OP_NO_THROW = "checkOpNoThrow"; private static final String OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION"; @SuppressLint("NewApi") public static boolean isNotificationEnabled(Context context) { AppOpsManager mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); ApplicationInfo appInfo = context.getApplicationInfo(); String pkg = context.getApplicationContext().getPackageName(); int uid = appInfo.uid; Class appOpsClass = null; /* Context.APP_OPS_MANAGER */ try { appOpsClass = Class.forName(AppOpsManager.class.getName()); Method checkOpNoThrowMethod = appOpsClass.getMethod(CHECK_OP_NO_THROW, Integer.TYPE, Integer.TYPE, String.class); Field opPostNotificationValue = appOpsClass.getDeclaredField(OP_POST_NOTIFICATION); int value = (Integer) opPostNotificationValue.get(Integer.class); return ((Integer) checkOpNoThrowMethod.invoke(mAppOps, value, uid, pkg) == AppOpsManager.MODE_ALLOWED); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return false; }}
isNotificationEnabled()方法返回true则通知权限已经打开,我们就不需要做处理了,如果没有打开的话,那我们就去申请一下:
private void getAppDetailSettingIntent(Context context) { Intent localIntent = new Intent(); localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (Build.VERSION.SDK_INT >= 9) { localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS"); localIntent.setData(Uri.fromParts("package", getPackageName(), null)); } else if (Build.VERSION.SDK_INT <= 8) { localIntent.setAction(Intent.ACTION_VIEW); localIntent.setClassName("com.android.settings","com.android.settings.InstalledAppDetails"); localIntent.putExtra("com.android.settings.ApplicationPkgName", getPackageName()); } startActivity(localIntent); }
提高Service优先级的其他方法
- Application加上Persistent属性。
android:persistent=”true”放在application标签下,但是很遗憾,如果你不是做系统级应用开发的,只是普通的第三方app,那么这个属性是无效的。一般来说设为前台服务就能够满足需求。 - 在intent fillter中设置Service的优先级
android:priority=”1000”,其中数字越小优先级越低,1000代表优先级最高,不过这个的效果并没有设为前台服务好,这个1000的优先级顶多与前台服务的优先级相同。其实Priority属性不仅仅可以用于Service,只要是有intent fillter的组件都可以,比如说Activity和BroadcastReceiver。这个属性多是用来按指定一个执行顺序的。
<service android:name=".BindService"> <intent-filter android:priority="1000"> <action android:name="android.intent.action.RESPOND_VIA_MESSAGE"/> </intent-filter></service>
- 将Service设为黏性服务
只需要将Service的onStartCommand()方法的返回值设为START_STICKY即可。想知道为啥的可以百度onStartCommand()方法的四个返回值。
@Override public int onStartCommand(Intent intent, int flags, int startId) { return START_STICKY; }
- 在Service的onDestroy()里发送广播重启服务
实现原理是Service注册广播,当服务被杀死的时候发送一条广播,监听到对应广播后在broadcastReceiver的onReceive()方法里重新开启服务。
缺点就是很可能你的服务是被因为app直接被kill掉了,并不会走onDestroy()。
//在Service的onCreate()中注册广播 @Override public void onCreate() { playerReceiver = new PlayerReceiver(); IntentFilter mFilter = new IntentFilter(); mFilter.addAction("destroy"); registerReceiver(playerReceiver, mFilter); }
//Service的onDestroy()发送广播 @Override public void onDestroy() { Intent intent = new Intent("destroy"); sendBroadcast(intent); stopForeground(true); super.onDestroy(); }
//onReceive()方法中根据action重新开启服务public class PlayerReceiver extends BroadcastReceiver { public PlayerReceiver() {} @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if("destroy".equals(action)){ MyIntentService myIntentService = new MyIntentService(); context.startService(new Intent(context,MyIntentService.class)); } }}
- 通过监听系统广播来重启服务
和上面的方法类似,都是监听广播,不过一个是我们发的,一个是系统发的。
//这是静态注册receiver,你也可以动态进行注册<receiver android:name="com.example.servicedemo.MyReceiver" > <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.USER_PRESENT" /> <action android:name="android.intent.action.PACKAGE_RESTARTED" /> </intent-filter> </receiver>
//onReceice()方法 @Override public void onReceive(Context context, Intent intent) { if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) { //做你对应的操作 } if (Intent.ACTION_USER_PRESENT.equals(intent.getAction())) { //做你对应的操作 } }
讲到这,差不多提高服务优先级的方法就说完了。
阅读全文
0 0
- Service设置前台服务&提高优先级
- 设置Service为前台服务,保证service不会被杀死!!
- Android Service提高优先级
- Service优先级提高
- 进程保活-将Service设置为前台服务
- Android service(三)前台服务
- android如何让后台服务service不被杀死(设置前台服务)
- 服务(Service)全解析(五)--前台Service
- 提高服务运行级别(前台服务)
- 提高Android Service 优先级的方法
- 提高Android Service 优先级的方法 .
- 提高Service优先级,避免被系统回收
- android中如何提高service的优先级
- 提高第三方app的service优先级
- Android_Service(2)前台服务(service)和远程服务(service)
- Android中service的使用,前台服务
- 四大组件之Service 前台服务
- Android四大组件之Service--前台服务
- 今天又学习了新的函数
- java导出excel
- JavaScript学习笔记
- CentOS中安装nginx以及无法访问的解决办法
- 在土耳其,他是阿里唯一的员工
- Service设置前台服务&提高优先级
- 关闭被占用的tomcat端口
- 数据结构思维 第十章 哈希
- 2017.9.20
- Revit中Dynamo编程——Python Script模块(引用RevitApi、RevitApiUI、math库)
- 注册界面的设计
- 为什么说Flutter是革命性的?
- 教你自制ST-LinkV2下载器
- 关于Dynamic附件上传的那些事儿!