Android8.0使用通知创建前台服务

Android8.0后台执行限制

为提高设备性能,系统会限制未在前台运行的应用的某些行为。具体而言:


在后台运行的应用对后台服务的访问受到限制
应用无法使用其清单注册大部分隐式广播


默认情况下,这些限制仅适用于针对O的应用。不过用户可以从Settinfs屏幕为任意应用启用这些限制,即使应用并不是以O为目标平台。

Android8.0还对特定函数做出了如下变更:


如果针对Android8.0的应用尝试子不允许创建其后台服务的情况下使用startService()函数,则该函数将引发一个IllegalStateException.
Context.startForegroundService()函数将启动一个前台服务。即使应用在后台运行,系统也允许其调用Context.startForegroundService().不过,应用必须在创建服务后的5秒内调用改服务的startForegroun()函数,否则将报ANR(Application Not Responding)错误。


Android8.0具体行为变更:https://developer.android.com/about/versions/oreo/android-8.0-changes?hl=zh-cn

 

创建和管理通知渠道

从Android8.0开始,需要为发送的每种不同类型的通知创建一个渠道,如果在Android8.0及以上在未指定通知频道的情况下发送通知,通知不会显示,会记录错误。
创建通知渠道步骤:


通过一个唯一的channel ID ,对用户可见的channel name,通知重要程度importance level构建一个通知渠道。
可选的使用setDescription()指定用户在系统设置页面看到的关于通知的相关描述。
通过createNotificationChannel()注册通知渠道。

 


//Channel ID 必须保证唯一
private static final String CHANNEL_ID = "com.appname.notification.channel";
/**
*创建通知渠道
*/
private void createNotificationChannel() {
    // 在API>=26的时候创建通知渠道
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        //设定的通知渠道名称
        String channelName = getString(R.string.channel_name);
        //设置通知的重要程度
        int importance = NotificationManager.IMPORTANCE_LOW;
        //构建通知渠道
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, channelName, importance);
        channel.setDescription(description);
        //向系统注册通知渠道,注册后不能改变重要性以及其他通知行为
        NotificationManager notificationManager = getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(channel);
    }
}1234567891011121314151617181920

importance level主要有七种层次:


IMPORTANCE_DEFAULT: 默认notification importance,可以在任何地方显示,有声音。
IMPORTANCE_HIGH:可以在任何地方显示,有声音.
IMPORTANCE_LOW:可以在任何地方显示,没有声音.
IMPORTANCE_MAX:重要程度最高,可以在任何地方显示,有声音,可以在用户当前屏幕上显示通知,可以使用full screen intents.比如来电。
IMPORTANCE_MIN:无声音,不会出现在状态栏中。
IMPORTANCE_NONE:在任何地方都不会显示,被阻塞。
IMPORTANCE_UNSPECIFIED:表示用户没有表示重要性的值。这个值是为了持久的首选项,并且永远不应该与实际的通知相关联。


如何选择重要性可以参考:
https://material.io/design/platform-guidance/android-notifications.html#behavior

开启前台服务

public class MonitorService extends Service { 
    /*
     * @param intent
     * @param flags
     * @param startId
     * @return
     */
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //处理任务
        return START_STICKY;
    }
    @SuppressLint("CommitPrefEdits")
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("foreground", "onCreate");
        //如果API在26以上即版本为O则调用startForefround()方法启动服务
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            setForegroundService();
        }
    }

   /**
   *通过通知启动服务
   */
   @TargetApi(Build.VERSION_CODES.N)
    public void  setForegroundService()
    {
        //设定的通知渠道名称
        String channelName = getString(R.string.channel_name);
        //设置通知的重要程度
        int importance = NotificationManager.IMPORTANCE_LOW;
        //构建通知渠道
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, channelName, importance);
        channel.setDescription(description);
        //在创建的通知渠道上发送通知
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
        builder.setSmallIcon(R.drawable.ic_logo) //设置通知图标
                .setContentTitle(notificationTitle)//设置通知标题
                .setContentText(notificationContent)//设置通知内容
                .setAutoCancel(true) //用户触摸时,自动关闭
                .setOngoing(true);//设置处于运行状态
         //向系统注册通知渠道,注册后不能改变重要性以及其他通知行为
        NotificationManager notificationManager = getSystemService( Context.NOTIFICATION_SERVICE);
        notificationManager.createNotificationChannel(channel);
        //将服务置于启动状态 NOTIFICATION_ID指的是创建的通知的ID
        startForeground(NOTIFICATION_ID,builder.build());
    }
  }
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051

在Application或需要开启服务的地方调用

 

  // Android 8.0使用startForegroundService在前台启动新服务
   if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
   {
       context.startForegroundService(mMonitorService);
   }
   else{
       context.startService(mMonitorService);
   }12345678           
      

---------------------

本文来自 Root_Q 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/Haienzi/article/details/81268022?utm_source=copy

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值