Android 8.0适配

话不多说,进入正题,由于本人的App最近在适配Android 8.0,因此把适配过程中遇到的一些内容写下来,作为一篇博客,一则可以自己过段时间的回顾。二则也可以给别人一些建议和参考。App主要适配了以下四点

1.通知

官方文档

以 SDK 的 Android 8.0 版本为目标平台的应用必须实现一个或多个通知渠道,以便向用户发布通知。

适配方案

在Android 8.0之前,我们要创建一个通知主要是以下的方法

        NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext);
复制代码

或者

        Notification.Builder builder = new Notification.Builder(mContext);
复制代码

这两个方案都只需要传入Context一个参数即可。但到了8.0系统引入了ChannelId,ChannelGroup概念。若不加ChannelId这个参数,通知是不会被唤起的。构造通知的话代码需如下处理

  1. 创建小组(这个可有可无,有点话分类更加清晰)
 public static String createNotificationChannelGroup(Context context, String groupId, String groupName) {
        if (Build.VERSION.SDK_INT >= 26) {
            ArrayList<NotificationChannelGroup> groups = new ArrayList<>();
            NotificationChannelGroup group = new NotificationChannelGroup(groupId, groupName);
            groups.add(group);
            NotificationManager notificationManager = (NotificationManager) context.getSystemService(
                    Context.NOTIFICATION_SERVICE);
            if (notificationManager != null) {
                notificationManager.createNotificationChannelGroups(groups);
            }
        }
        return groupId;
    }
复制代码
  1. 创建通道
public static String createNotificationChannel(Context context, String groupId, String channelId, String channelName) {
        if (Build.VERSION.SDK_INT >= 26) {
            NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT);
            channel.enableLights(true);
            channel.setLightColor(ContextCompat.getColor(context, R.color.colorPrimary));
            channel.setShowBadge(true);
            channel.setLockscreenVisibility(NotificationCompat.VISIBILITY_PRIVATE);
            channel.setBypassDnd(true);
            channel.setGroup(groupId);
            NotificationManager notificationManager = (NotificationManager) context.getSystemService(
                    Context.NOTIFICATION_SERVICE);
            if (notificationManager != null) {
                notificationManager.createNotificationChannel(channel);
            }
        }
        return channelId;
    }
复制代码
  1. 构建通知
NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext, channelId);
复制代码
适配后感受

适配完了,效果图如图所示

组名和包名id需注意需要唯一,建议可以使用业务名来进行命名。

2.广播限制

官方文档

Android 8.0 的应用无法继续在其清单中为隐式广播注册广播接收器。

适配方案

Context.registerReceiver()进行动态注册广播或者添加包名发送唯一的显示广播。 本来google有这个限制就是为了你一个广播下去各个App都起来了,导致资源的浪费。发个唯一确定包的广播,当然没什么问题。代码如下。

intent.setPackage(context.getPackageName());
复制代码
适配后感受

这个适配还是比较好处理的。通过反编译查看AndroidManifest.xml中广播接收器即可。不过有个坑是第三方静态广播的处理。尤其是各种推送sdk里面有很多静态广播。这些需要查看相应的文档去适配。自己的项目中用到的推送主要有个推以及信鸽。这两个最新版已经兼容了Android 8.0.

3.应用快捷键

官方文档

Android 8.0 对应用快捷方式做出了以下变更: com.android.launcher.action.INSTALL_SHORTCUT 广播不再会对您的应用有任何影响,因为它现在是私有的隐式广播。相反,您应使用 ShortcutManager 类中的 requestPinShortcut() 函数创建应用快捷方式。

适配方案

简而言之由于Android 8.0对私有的隐式广播的限制,导致8.0之前用隐式广播方法来创建快捷方式将失效。而系统推荐我们使用ShortcutManager类来实现创建快捷方式。 适配代码如下:

      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
          ShortcutManager scm = (ShortcutManager) context.getSystemService(Context.SHORTCUT_SERVICE);
            if (scm != null) {
                ShortcutInfo si = new ShortcutInfo.Builder(context, "id")
                        .setIcon(Icon.createWithResource(context, R.drawable.watermelon))
                        .setShortLabel(context.getResources().getString(R.string.watermelon))
                        .setIntent(intent)
                        .build();
                boolean result = scm.requestPinShortcut(si, null);
            }
        } else {
           Intent shortcut = new Intent("com.android.launcher.action.INSTALL_SHORTCUT");
           shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME,context.getResources().getString(R.string.watermelon));
           ShortcutIconResource iconRes = ShortcutIconResource.fromContext(context, R.drawable.watermelon);
           shortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconRes);
           shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, intent);
           shortcut.putExtra("duplicate", false);
           context.sendBroadcast(shortcut);
        }
        
复制代码
适配后感受

自己在搞这个适配的时候发现应该是国内各厂商自定义了8.0系统,导致某些现象会和文档有出入。比如华为会默认安装自动生成一个快捷方式。当你再创建一个快捷方式时若名字和Mainfest中清单app名相同时其会当作同一个快捷方式并告知你已有一个快捷方式存在。不过这个并没有什么特别的影响。快捷方式需要注意的避免重复添加。

4.后台服务

官方说明

如果针对 Android 8.0 的应用尝试在不允许其创建后台服务的情况下使用 startService() 函数,则该函数将引发一个 IllegalStateException。

适配方案

刚看到文档有点懵逼,什么是不允许创建后台服务。于是自己写了一个demo,试了一下,思路就是每隔20秒app调用一下startService()函数。果然一分多钟的时候看到了如下内容。 


因此也明白了文档所描述的意思,就是当app在后台一定时间以后,app若再调用startService()方法就会报错,这个时间其实跟设备坏境都有关系,但是时间不长。

具体适配跟官方文档给的建议一样。使用了JobScheduler代替了Service的功能

在大多数情况下,应用都可以使用 JobScheduler 作业克服这些限制。 这种方式让应用安排为在未活跃运行时执行工作,不过仍能够使系统可以在不影响用户体验的情况下安排这些作业。

适配后感受

JobScheduler 这个掌握基础的还是比较容易的。可以看下官方文档。

其他Android 8.0行为变更

  • 悬浮窗适配
  • 运行时权限
  • APK安装

这些因为对自己的App没有特定影响所以未进行特定的处理。有需要的可以查看一下google适配的文档 参考资料:developer.android.google.cn/about/versi…


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值