• Android 开发 8.0版本启动Service的方法


    前言 

    google在更新Android8.0后对Service的权限越发收紧。导致目前想要启动服务必需实现服务的前台化(否则在服务启动5秒后,系统将自动报错)。下面我们就来看看如何在8.0上启动服务。

    看看8.0之前的版本怎么启动Service

      在看8.0启动服务的方法之前,我们先看看8.0之前是怎么启动服务的。这样可以对比,也可以理解增加了那些部分。

      1.在Activity启动服务:

    Intent intent = new Intent(MainActivity.this,MainService.class);
    startService(intent);

      8.0之前是使用startService 直接启动服务的。后续服务就可以在后台运行了

      2.将服务前台化:

      虽然8.0之前如果没有明确需求,是可以不需要让服务前台化通知栏显示的,但是我们为了对比实现下8.0之前的服务前台化。

    public void onCreate() {
            super.onCreate();
            Notification notification = new Notification.Builder(this)
                    .setContentTitle("主服务")//设置标题
                    .setContentText("运行中...")//设置内容
                    .setWhen(System.currentTimeMillis())//设置创建时间
                    .setSmallIcon(R.mipmap.ic_launcher)//设置状态栏图标
             .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))//设置通知栏图标
                    .build();
            startForeground(1,notification);
        }

    可以服务启动后,可以在服务的onCreate()里直接实现服务前台化。

    8.0版本怎么启动Service

      1.在Activity里启动服务

    Intent intent = new Intent(MainActivity.this,MainService.class);
    startForegroundService(intent);

      可以看到启动的方法变成了startForegroundService();

      2.创建8.0版本必需实现的服务前台化

    private static final String CHANNEL_ID = "NFCService";
    public void onCreate() {
            super.onCreate();
            NotificationManager manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
            NotificationChannel Channel = new NotificationChannel(CHANNEL_ID,"主服务",NotificationManager.IMPORTANCE_HIGH);                
         Channel.enableLights(true);//设置提示灯
         Channel.setLightColor(Color.RED);//设置提示灯颜色
            Channel.setShowBadge(true);//显示logo
            Channel.setDescription("ytzn");//设置描述
            Channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC); //设置锁屏可见 VISIBILITY_PUBLIC=可见
            manager.createNotificationChannel(Channel);
    
            Notification notification = new Notification.Builder(this)
                    .setChannelId(CHANNEL_ID)
                    .setContentTitle("主服务")//标题
                    .setContentText("运行中...")//内容
                    .setWhen(System.currentTimeMillis())
                    .setSmallIcon(R.mipmap.ic_launcher)//小图标一定需要设置,否则会报错(如果不设置它启动服务前台化不会报错,但是你会发现这个通知不会启动),如果是普通通知,不设置必然报错
                   .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
                    .build();
            startForeground(1,notification);//服务前台化只能使用startForeground()方法,不能使用 notificationManager.notify(1,notification); 这个只是启动通知使用的,使用这个方法你只需要等待几秒就会发现报错了
    
            
        }  

    8.0版本后多了一个需要创建的NotificationChannel,在Notification里多了一个需要设置的setChannelId();

      8.0版本启动服务注意点:

    1. 请注意8.0版本只能使用startForegroundService()启动服务,不能在使用startService()
    2. 请注意在new NotificationChannel(CHANNEL_ID,"主服务",NotificationManager.IMPORTANCE_HIGH); 的第一个参数id为Channel的通道id需要与NotificationsetChannelId()设置的id一致,否则会报前台服务无效的异常。
    3. 注意启动服务前台化通知的方法是startForeground(),如果使用notificationManager.notify(),将不会关联你启动的服务,系统会将它作为一个普通通知处理

    最后了解什么是NotificationChannel

    Android O 引入了 通知渠道(Notification Channels),以提供统一的系统来帮助用户管理通知,如果是针对 android O 为目标平台时,必须实现一个或者多个通知渠道,以向用户显示通知。若并不以 Android O 为目标平台,当应用运行在 android O 设备上时,其行为将与运行在 Android 7.0 上时相同。
    开发者可以为需要发送的每个不同的通知类型创建一个通知渠道。还可以创建通知渠道来反映应用的用户做出的选择。例如,可以为聊天应用的用户创建的每个聊天组建立单独的通知渠道。
    Android O 的用户可以使用一致的系统 UI 管理大多数与通知有关的设置。所有发布至通知渠道的通知都具有相同的行为。当用户修改任何下列特性的行为时,修改将作用于通知渠道:

    • 重要性
    • 声音
    • 振动
    • 在锁屏上显示
    • 替换免打扰模式

    通知优先级和重要性

    Android O 弃用了为单个通知设置优先级的功能。创建通知渠道时可以设置建议重要性级别。为通知渠道指定的重要性级别适用于发布至该渠道的所有通知消息。可以配置五个级别中的一个,这些级别代表着通知渠道可以打断用户的程度,范围是 IMPORTANCE_NONE(0)IMPORTANCE_HIGH(4)。默认重要性级别为 3:在所有位置显示,发出提示音,但不会对用户产生视觉干扰。创建通知渠道后,只有系统可以修改其重要性。用户可以在设置中找到。

    创建通知渠道

    要创建通知渠道,请执行下列操作:

    • 构建一个在软件包内具有唯一 ID 的通知渠道对象。
    • 为该通知渠道对象配置所需的任何初始设置(例如提示音以及对用户可见的可选说明)。
    • 将通知渠道对象提交到通知管理器。

    如果试图使用初始值创建的通知渠道已存在,不会执行任何操作,因此启动应用时可以放心地执行以上步骤序列。

    创建通知渠道组

    如果应用支持多个帐户,则可为每个帐户创建一个通知渠道组。通知渠道组用于对一款应用内的多个同名通知渠道进行管理。例如,一款社交网络应用可能提供面向个人帐户以及企业帐户的支持。在此情境下,每个帐户可能都需要多个功能和名称相同的通知渠道。
    一个包括 2 个通知渠道的个人帐户:

    • 帖子新增评论的通知。
    • 联系人推荐帖子的通知。

    一个包括 2 个通知渠道的企业帐户:

    • 帖子新增评论的通知。
    • 联系人推荐帖子的通知。

    在本例中,将与每个用户帐户相关的通知渠道组织成专用组可确保用户能在 Settings 中轻松地进行区分。每个通知渠道组都必须在软件包内具有唯一 ID,并具有用户可见的名称。下面这段代码演示了如何创建通知渠道组。

    // 通知渠道组的id.
    String group = "my_group_01";
    // 用户可见的通知渠道组名称.
    CharSequence name = getString(R.string.group_name);
    NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    mNotificationManager.createNotificationChannelGroup(new NotificationChannelGroup(group, name));

    新建渠道组后,便可调用 setGroup()将某个新渠道关联到该组。注意,只能在将渠道提交给通知管理器之前修改通知渠道与组之间的关联。

    创建通知

    要创建通知,请调用 Notification.Builder.build(),它返回的 Notification对象包含的指定值。要发出通知,请通过调用 [notify()](https://developer.android.google.cn/reference/android/app/NotificationManager.html#notify(int, android.app.Notification))将 Notification对象传递给系统。
    创建的通知Notification对象必须包含以下内容:

    如果 应用是以 Android O 为目标平台并且在不指定有效通知渠道的情况下发布通知,那么通知将无法发布,系统会记录错误。
    注:可以在 Android O 中启用一个新设置,当针对 Android O 的应用试图在没有通知渠道的情况下发布时,以 toast 形式显示屏幕警告。要为运行 Android O 的开发设备启用该设置,请转到 Settings > Developer options,然后打开 Show notification channel warnings

    向渠道发布通知

    下面这段代码说明如何向通知渠道发布简单通知。请注意,代码利用渠道的 ID 将通知与通知渠道关联起来。

    mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    // 为该通知设置一个id
    int notifyID = 1;
    // 通知渠道的id
    String CHANNEL_ID = "my_channel_01";
    // Create a notification and set the notification channel.
    Notification notification = new Notification.Builder(MainActivity.this)
    .setContentTitle("New Message")
    .setContentText("You've received new messages.")
    .setSmallIcon(R.drawable.ic_notify_status) 
    .setChannelId(CHANNEL_ID)
    .build();
    // 发布通知
    mNotificationManager.notify(id, notification);  

    读取通知渠道设置

    用户可以修改通知渠道的设置,包括振动和提示音等行为。开发者可以调用以下两个方法来发现用户对通知渠道应用的设置:

    更新通知渠道设置

    一旦创建了通知渠道,其设置和行为就由用户掌控。可以再次调用 createNotificationChannel()以重命名现有通知渠道,或更新其说明。以下示例代码说明如何通过创建启动 Activity 的 Intent 将用户重定向到通知渠道的设置。在本例中,Intent 要求提供扩展数据,包括通知渠道的 ID 和应用的软件包名称。

    Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
    intent.putExtra(Settings.EXTRA_CHANNEL_ID,mChannel.getId());
    intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());startActivity(intent);

    删除通知渠道

    可以通过调用 deleteNotificationChannel()
    来删除通知渠道。作为一个垃圾信息预防机制,通知设置中将显示已删除渠道的数量。可以通过以下任一方法清除开发设备上的测试渠道:重新安装应用;清除与应用副本关联的数据。以下示例代码演示了如何删除通知渠道。

    NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    // 通知渠道的id
    String id = "my_channel_01";
    NotificationChannel mChannel = mNotificationManager.getNotificationChannel(id);
    mNotificationManager.deleteNotificationChannel(mChannel);
  • 相关阅读:
    string与wstring之间的转换
    QTableWidget去除选中虚边框
    在新机器部署Qt+mysql程序
    Qt文件路径分隔符
    MySQL通过增加用户实现远程连接数据库
    Qt 配置文件QSettings读取以及中文问题
    git config proxy
    ubuntu14.04 us sources.list
    How to keep Environment Variables when Using SUDO
    ubuntu hash sum mismatch error
  • 原文地址:https://www.cnblogs.com/guanxinjing/p/9861476.html
Copyright © 2020-2023  润新知