最近(2018年11月15日)在上传App升级包至Google Play时,遇到了如下问题:

即:当前App的Target API Level 为25(Android 7.1.1 Nougat),要求将App的Target API Level提升到26(Android 8.0 Oreo)或以上。

查阅资料发现,Google开发者在持续提高 Android 应用的安全性与性能一文中提到:

为了提升 App 安全性和性能,确保每个用户都能够获取最佳体验,探索和安装自己喜欢的 App 和游戏,Google对Android 开发者提出了一些变更。从 2018 年下半年开始,Google Play 管理中心将要求 App 设定target API Level为近期版本:

  • 2018 年 8 月:新 App 需要将 target API 等级设定为 26(Android 8.0)或者更高

  • 2018 年 11 月,现有 App 的更新包需要将 target API 等级设定为 26 或者更高

  • 2019 年之后:每年 targetSdkVersion 会提出新的要求。Android 新版本系统发布一年内,App 的开发和更新都需要将 API 调整到相应或者更高等级。

现有但不再更新的 App 并不受影响。开发者可以自行选择是否使用 minSdkVersion,依旧可以进行基于旧版本 Android 系统的 App 开发。

  • 问题

为了能够提交Google Play ,只得将App Target Level提升至26。然后打包、测试、提交市场。测试过程中发现无法接收到Push推送,并且是在Android8.0及以上的设备上无法接收到push,抓取到如下log:

11-15 19:01:05.794  1603  3283 E NotificationService: No Channel found for pkg=com.xxxxxxx.xxxxxx, channelId=null, id=1627843789, tag=null, opPkg=com.xxxxxxx.xxxxxx, callingUid=10719, userId=0, incomingUserId=0, notificationUid=10719, notification=Notification(channel=null pri=0 contentView=null vibrate=default sound=default defaults=0xffffffff flags=0x11 color=0x00000000 category=msg groupKey=com.xxxxxxxx.xxxxxx.notifygrp vis=PUBLIC)

查看创建Notification的代码,如下(Demo):

private void onLaunchNotificationBtnClick() {String textTitle = "This is Title";String textContent = "This is Content";//创建NotificationNotificationCompat.Builder builder = new NotificationCompat.Builder(this).setSmallIcon(R.drawable.ic_launcher_foreground).setContentTitle(textTitle).setContentText(textContent).setPriority(NotificationCompat.PRIORITY_DEFAULT);//Launch NotificationNotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(getApplicationContext());notificationManagerCompat.notify(NOTIFICATION_ID, builder.build());}

Log 如下:

11-17 16:06:51.670 13096-13096/com.example.cxc.fullscreendemo E/NotificationManager: notifyAsUser: tag=null, id=888, user=UserHandle{0}
11-17 16:06:51.678 1272-1875/? E/NotificationService: No Channel found for pkg=com.example.cxc.fullscreendemo, channelId=null, id=888, tag=null, opPkg=com.example.cxc.fullscreendemo, callingUid=10487, userId=0, incomingUserId=0, notificationUid=10487, notification=Notification(channel=null pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x0 color=0x00000000 vis=PRIVATE)

关于Notification的介绍与使用可以参考: Notifications Overview

  • 定位

参考 Android Developers https://developer.android.com/guide/topics/ui/notifiers/notifications
Starting in Android 8.0 (API level 26), all notifications must be assigned to a channel or it will not appear. By categorizing notifications into channels, users can disable specific notification channels for your app (instead of disabling all your notifications), and users can control the visual and auditory options for each channel—all from the Android system settings (figure 11). Users can also long-press a notification to change behaviors for the associated channel.

即:从Android 8.0 (API level 26)开始,所有的notification必须关联一个channel,否则将不会显示。通过将Notification分到各个不同的Channel中,用户可以禁掉App某个Channel中的通知(而不是禁止App的所有Notification),并且用户可以在系统设置中控制各个Channel通知的形式,如是否有声音。

关于Notification Channel的介绍及深入理解可以参考:Exploring Android O: Notification Channels

  • 解决

先创建一个Notification Channel,然后将通知关联到该Channel。

package com.example.cxc.fullscreendemo.notification;import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Build;public class NotificationUtils {private static final String CHANEL_ID = "com.example.cxc.fullscreendeme.channelId";private static final String CHANEL_DESCRIPTION = "Channel描述";private static final String CHANEL_NAME = "Channel名称";public static String createNotificationChannel(Context context) {// NotificationChannels are required for Notifications on O (API 26) and above.if (context != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {// Initializes NotificationChannel.NotificationChannel notificationChannel =new NotificationChannel(CHANEL_ID,CHANEL_NAME,NotificationManager.IMPORTANCE_DEFAULT);notificationChannel.setDescription(CHANEL_DESCRIPTION);// Adds NotificationChannel to system. Attempting to create an existing notification// channel with its original values performs no operation, so it's safe to perform the// below sequence.NotificationManager notificationManager =(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);notificationManager.createNotificationChannel(notificationChannel);return CHANEL_ID;} else {// Returns null for pre-O (26) devices.return null;}}
}
    private void onLaunchNotificationBtnClick() {String textTitle = "This is Title";String textContent = "This is Content";//创建Notification ChannelString channelId = NotificationUtils.createNotificationChannel(getApplicationContext());//创建Notification并与Channel关联NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId).setSmallIcon(R.drawable.ic_launcher_foreground).setContentTitle(textTitle).setContentText(textContent).setPriority(NotificationCompat.PRIORITY_DEFAULT);//Launch NotificationNotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(getApplicationContext());notificationManagerCompat.notify(NOTIFICATION_ID, builder.build());}

最后运行,可以正常显示Notification:

关于每一个发布的Android版本,Android Developers上都对新功能及形为变更做了详细的介绍,具体可以参考 Android Releases Versions.

最后,总结一下教训,幸亏在提升target API Level至26后,测试发现了该问题,否则后果还是很严重的。2019年之后Google Play要求新发布或者更新的App必须是一年内发布的Android版本,未来可能更多的应用发布渠道(如应用宝)会跟进,所以提升targetSdkVersion势在必行,也请各个应用开发者赶紧跟上步伐。

完整代码请参考:https://github.com/cxcbupt/FullscreenDemo.git

References:

  1. 持续提高 Android 应用的安全性与性能
  2. Notifications Overview
  3. Exploring Android O: Notification Channels

Android 8.0 Oreo 形为变更之 Notification Channels相关推荐

  1. Android 8.0 Oreo 国内可用测试平台上线

    Android 8.0 Oreo 已经发布两个月了,无数开发者已经跃跃欲试,想在这个全新版本的 Android 系统上让自己的应用一展身手,我们很清楚,Android 8.0 为了更流畅的系统,以及更 ...

  2. Android开发周报:Google 推出AR SDK、Android 8.0 Oreo 最终版发布

    \ <Android漏洞扫描工具Code Arbiter>:目前 Android 应用代码漏洞扫描工具种类繁多,效果良莠不齐,这些工具有一个共同的特点,都是在应用打包完成后对应用进行解包扫 ...

  3. Android 8.0 Oreo 现已推出!

    历经一年多的开发和数月以来开发者与早期用户的反复测试,Android 8.0 Oreo 终于正式面向全球发布.Android 8.0 为用户带来了诸如画中画 (Picture in picture). ...

  4. android 画中画模式自定义,Android 8.0 Oreo 画中画模式

    Android 8.0 Oreo(API Level 26)允许活动启动画中画 Picture-in-picture(PIP)模式.PIP 是一种特殊类型的多窗口模式,主要用于视频播放.PIP 模式已 ...

  5. android8.0于与ios,android 8.0 oreo抄袭苹果吗 android oreo和ios 11对比

    在开发Android Oreo时,谷歌被传android 8.0 oreo抄袭了苹果iOS的部分创意,例如应用图标通知角标.表情符号.画中画.自动填写等. 谷歌刚刚公布了Android Oreo,它提 ...

  6. android8 测试,Android 8.0 Oreo 国内可用测试平台上线

    原标题:Android 8.0 Oreo 国内可用测试平台上线 Android 8.0 Oreo 已经发布一个月了,无数开发者已经跃跃欲试,想在这个全新版本的 Android 系统上让自己的应用一展身 ...

  7. 面向开发者的 Android 8.0 Oreo 详细介绍

    无需原生开发基础,也能完美呈现京东商城.<混合开发京东商城系统,提前布局大前端>课程融合vue.Android.IOS等目前流行的前端和移动端技术,混合开发经典电商APP--京东.课程将各 ...

  8. Android 8.0 - AccountManager之行为变更

    Android 8.0 - AccountManager之权限变更 获取系统帐号的接口: 获取系统帐号的权限 条件 1: 条件 2: 条件 3: 条件 4: 其他解决方案 写在最后: 获取系统帐号的接 ...

  9. Android 10.0相关权限的变更(使用WiFi Direct必须打开定位)

    最近很多厂商推送了Android10.0 的ROM.Android之后,大量的App出现了闪退或者打不开,白屏等问题. Pangu-Immortal (Pangu-Immortal) · GitHub ...

最新文章

  1. 恭喜你发现了宝藏,编程习惯-日积月累
  2. Nature综述:植物与微生物组的相互作用:从群落装配到植物健康(上)
  3. java 工厂模式 计算器_简单工厂模式实现简易计算器
  4. OpenMp使用例子
  5. OpenGL envmapsphere球形环境图的实例
  6. 吃透 | Elasticsearch filter和query的不同
  7. mysql 复制延迟诊断_新特性解读 | MySQL 8 复制延迟观测新方式,更全面更精准
  8. python 正则表达式 sub_python 正则表达式 re.sub re.subn
  9. 7-14 排座位 (25 分)
  10. 追根溯源:EntityFramework 实体的状态变化
  11. python自学行吗-python自学行吗 有哪些用处
  12. linux link path walk,python之os.walk()与os.path.walk()
  13. 小米蓝牙音箱驱动_2020年度智能音箱拆解报告汇总,涵盖27个品牌72款产品
  14. 软件测试是做什么的?具体工作内容?
  15. mpa和pis_有关压力单位pis-bar-mpa的换算
  16. 微信公众号编辑模式下推送消息
  17. 使用transferTo方法转换MultipartFile(处理NoSuchFileException异常)
  18. 求个人所得税和税后收入
  19. 认识DDR SDRAM
  20. HTML5文件夹隐藏了怎么打开,如何打开隐藏文件夹,详细教您打开隐藏文件夹的方法...

热门文章

  1. ajax 请求调用问题
  2. unity3d 多人寻路堵塞堆叠问题
  3. 【CV论文阅读】 Fast RCNN + SGD笔记
  4. 业务实体 数据实体
  5. js date 前一天
  6. 网站鼠标禁止右键的解开方法
  7. 第11讲++数据的基本查询
  8. Bootstrap入门(二十九)JS插件6:弹出框
  9. C++ 系列:基础知识储备
  10. C、Shell、Perl基于Tomcat开发CGI程序环境配置