##1. 通知栏
Android 8.0 引入了通知渠道,其允许您为要显示的每种通知类型创建用户可自定义的渠道。用户界面将通知渠道称之为通知类别。
针对 8.0 的应用,创建通知前需要创建渠道,创建通知时需要传入 channelId,否则通知将不会显示。如下:
// 创建通知渠道
private void initNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = mContext.getString(R.string.app_name);
NotificationChannel channel = new NotificationChannel(mChannelId, name, NotificationManager.IMPORTANCE_DEFAULT);
mNotificationManager.createNotificationChannel(channel);
}
}
// 创建通知传入channelId
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NotificationBarManager.getInstance().getChannelId());
##2. 允许安装未知来源应用
针对 8.0 的应用需要在 AndroidManifest.xml 中声明 REQUEST_INSTALL_PACKAGES 权限,否则将无法进行应用内升级。
##3.桌面图标适配
AndroidManifest.xml中设置桌面图标如下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.icontest">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
android:icon这个属性,通过这个属性,我们将应用的图标指定为了mipmap目录下的ic_launcher文件。另外大家可能注意到还有一个android:roundIcon属性,这是一个只适用在Android 7.1系统上的过渡版本,很快就被8.0系统的应用图标适配所替代了,我们不用去管它。
在sdk不低于26的情况下,其res资源中会有一个mipmap-anydpi-v26文件夹
Android 8.0或以上系统的手机,都会使用这个目录下的ic_launcher来作为图标
mipmap-anydpi-v26目录下的ic_launcher并不是一张图片,而是一个XML文件,我们打开这个文件看一下,代码如下所示:
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
这是一个8.0系统应用图标适配的标准写法,在标签中定义一个标签用于指定图标的背景层,定义一个标签用于指定图标的前景层。
ic_launcher_foreground文件内容也类似
可以发现是前景层盖在背景层上搭配而成的一张图片
所以需要准备前景层和背景层,接下来我们正式开始进行8.0系统的应用图标适配。回到项目当中,然后按下Windows:Ctrl+Shift+A / Mac:command+shft+A 快捷键,并在action中输入Image Asset搜索,进入Asset Studio进行桌面图标适配即可。
##4.透明主题的Activity
这个是在targetSdk=27,Android为8.0的手机时,出现的bug(因为官方已经在8.1修复)。问题的探究可以查看这里。
只有全屏不透明的activity才可以设置方向。否则报错如下:
java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2957)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3032)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at adroid.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6944)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
问题出现情况的比如启动页面,微信分享、支付的回调页面,我们习惯设为透明。
解决办法:
要么去掉对应activity中的 screenOrientation 属性,或者对应设置方向的代码。
要么舍弃透明效果,在它的Theme中添加:
<item name="android:windowIsTranslucent">false</item>
方案2最好是添加 values-v26目录,单独处理8.0版本。个人推荐方案1。
##5.权限
在Android 8.0之前,如果应用在运行时请求某个权限并且被授予,系统会错误地将属于同一权限组并且在清单中注册的其他权限也一并授予该应用。对于Android 8.0的应用,此行为已被纠正。系统只会授予应用明确请求的权限。然而,一旦用户为应用授予某个权限,则所有后续对该权限组中权限的请求都将被自动批准,而不会提示用户
这一行文字摘选自官方文档,读起来有点拗口。我用最简单的例子来解释一下:8.0之前你申请读外部存储的权限READ_EXTERNAL_STORAGE,你会自动被赋予写外部存储的权限WRITE_EXTERNAL_STORAGE,因为他们属于同一组(android.permission-group.STORAGE)权限,但是现在8.0不一样了,读就是读,写就是写,不能混为一谈。不过你授予了读之后,虽然下次还是要申请写,但是在申请的时候,申请会直接通过,不会让用户再授权一次了