官方文档
https://www.jianshu.com/p/d9f5b0801c6b
https://blog.csdn.net/yang1349day/article/details/80016607
//8.0通知栏适配
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(String.valueOf(NotificationConfig.SERVICE_CHANNEL_ID), "", NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription("");
NotificationManager manager = (NotificationManager) MyApplication.getInstance().getSystemService(Context.NOTIFICATION_SERVICE);
manager.createNotificationChannel(channel);//创建NotificationChannel
notificationBuilder.setChannelId(channel.getId());
}
notificationManager.notify(tag, liveChatGroupId, notificationBuilder.build());
...
Android 8.0 和 Android 支持库 26 允许您从提供程序应用请求字体,而无需将字体绑定到 APK 中或让 APK 下载字体。此功能可减小 APK 大小,提高应用安装成功率,使多个应用可以共享同一种字体。
如需了解有关下载字体的详细信息,请参阅 可下载字体。
Android 8.0 允许您根据 TextView 的大小自动设置文本展开或收缩的大小。这意味着,在不同屏幕上优化文本大小或者优化包含动态内容的文本大小比以往简单多了。如需了解有关如何在 Android 8.0 中自动调整 TextView 的大小的详细信息,请参阅自动调整 TextView 的大小。
Android O (Android 8.0) 中,Google 移除掉了容易被滥用的“允许未知来源”应用的开关,在安装 Play Store 之外的第三方来源的 Android 应用的时候,竟然没有了“允许未知来源”的检查框,如果你还是想要安装某个被自己所信任的开发者的 app,则需要在每一次都手动授予“安装未知应用”的许可。
首先在AndroidManifest.xml 清单文件中添加安装未知来源应用的权限
boolean hasInstallPerssion = getPackageManager().canRequestPackageInstalls();
if (hasInstallPerssion ) {
//安装应用的逻辑
} else {
//跳转至“安装未知应用”权限界面,引导用户开启权限,可以在onActivityResult中接收权限的开启结果
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
startActivityForResult(intent, REQUEST_CODE_UNKNOWN_APP);
}
}
应用请求 READ_EXTERNAL_STORAGE,并且用户授予了该权限。如果该应用针对的是 API 级别 24 或更低级别,系统还会同时授予 WRITE_EXTERNAL_STORAGE,因为该权限也属于同一 STORAGE 权限组并且也在清单中注册过。如果该应用针对的是 Android 8.0,则系统此时仅会授予 READ_EXTERNAL_STORAGE;不过,如果该应用后来又请求 WRITE_EXTERNAL_STORAGE,则系统会立即授予该权限,而不会提示用户。
final class ActivityRecord extends ... {
void setRequestedOrientation(int requestedOrientation) {
if (ActivityInfo.isFixedOrientation(requestedOrientation) && !fullscreen
&& appInfo.targetSdkVersion > O) {
throw new IllegalStateException("Only fullscreen activities can request orientation");
}
final int displayId = getDisplayId();
final Configuration displayConfig = mStackSupervisor.getDisplayOverrideConfiguration(displayId);
final Configuration config = mWindowContainerController.setOrientation(requestedOrientation,
displayId, displayConfig, mayFreezeScreenLocked(app));
if (config != null) {
frozenBeforeDestroy = true;
if (!service.updateDisplayOverrideConfigurationLocked(config, this, false /* deferResume */, displayId)) {
mStackSupervisor.resumeFocusedStackTopActivityLocked();
}
}
service.mTaskChangeNotificationController.notifyActivityRequestedOrientationChanged(
task.taskId, requestedOrientation);
}
}
如果一个Activity的Style符合下面三个条件之一,认为不是“fullscreen”:
这个问题貌似在最新的SDK中已经修复,我们在API Level 27的设备上已经无法重现,但在API Level 26的设备还是能重现。
Android 8.0 对应用在用户不与其直接交互时可以执行的操作施加了限制
注:默认情况下,这些限制仅适用于针对 O 的应用。 不过,用户可以从 Settings 屏幕为任意应用启用这些限制,即使应用并不是以 O 为目标平台。
在大多数情况下,应用都可以使用 JobScheduler 作业克服这些限制。 这种方式让应用安排为在未活跃运行时执行工作,不过仍能够使系统可以在不影响用户体验的情况下安排这些作业。
JobScheduler 可以声明其预估的数据大小、信号预提取,并指定具体的网络要求,而运营商可以报告网络拥塞或无限流量。 然后,JobScheduler 根据网络状态管理工作。 例如,当网络拥塞时,JobScheduler 可能会延迟较大的网络请求。 如果使用的是无限流量网络,则 JobScheduler 可运行预提取作业以提升用户体验(例如预提取标题)。
添加作业时,确保使用 setEstimatedNetworkBytes()、setIsPrefetch() 和 setRequiredNetwork()(如果适用),以帮助 JobScheduler 正确处理工作。 在执行作业时,请确保使用 JobParameters.getNetwork() 返回的 Network 对象。 否则,您将隐式使用设备的默认网络,其可能不符合您的要求,从而导致意外的流量消耗
Android 8.0 引入了一种全新的方法,即 Context.startForegroundService(),以在前台启动新服务。在系统创建服务后,应用有五秒的时间来调用该服务的 startForeground() 方法以显示新服务的用户可见通知。
在此时间限制内未调用 startForeground(),则系统将停止服务并声明此应用为 ANR。
对于在 OTA 之前安装到某个版本 Android 8.0(API 级别 26)的应用,除非在 OTA 后卸载并重新安装,否则 ANDROID_ID 的值将保持不变。要在 OTA 后在卸载期间保留值,开发者可以使用密钥/值备份关联旧值和新值。(也就是说,Android8.0中Android_Id算法和之前不一样,需要兼容处理)
对于安装在运行 Android 8.0 的设备上的应用,ANDROID_ID 的值现在将根据应用签署密钥和用户确定作用域。应用签署密钥、用户和设备的每个组合都具有唯一的 ANDROID_ID 值。因此,在相同设备上运行但具有不同签署密钥的应用将不会再看到相同的 Android ID(即使对于同一用户来说,也是如此)。 (每个手机获取的Android_Id都不会一样了)
只要签署密钥相同(并且应用未在 OTA 之前安装到某个版本的 O),ANDROID_ID 的值在软件包卸载或重新安装时就不会发生变化。(安卓8.0以后才安卓的应用,只要应用的签名秘钥不变不会影响Android_Id,下次获取的值还是一样的)
即使系统更新导致软件包签署密钥发生变化,ANDROID_ID 的值也不会变化。
在 Android 8.0 中,Collections.sort() 是在 List.sort() 的基础上实现的。在 Android 7.x(API 级别 24 和 25)中,则恰恰相反。在过去,List.sort() 的默认实现会调用 Collections.sort()。
在大多数情况下,您也可以使用根据 API 级别委托给其他默认实现的实现重写 List.sort()。例如:
@Override
public void sort(Comparator super E> comparator) {
if (Build.VERSION.SDK_INT <= 25) {
Collections.sort(this);
} else {
super.sort(comparator);
}
}
应用快捷键
com.android.launcher.action.INSTALL_SHORTCUT 广播不再会对您的应用有任何影响,因为它现在是私有的隐式广播。相反,您应使用 ShortcutManager 类中的 requestPinShortcut() 函数创建应用快捷方式。
现在,ACTION_CREATE_SHORTCUT Intent 可以创建可使用ShortcutManager 类进行管理的应用快捷方式。此 Intent 还可以创建不与 ShortcutManager 交互的旧版启动器快捷方式。在以前,此 Intent 只能创建旧版启动器快捷方式。
现在,使用 requestPinShortcut() 创建的快捷方式和在处理 ACTION_CREATE_SHORTCUT Intent 的操作组件中创建的快捷方式均已转换为功能齐全的应用快捷方式。因此,应用现在可以使用 ShortcutManager 中的函数来更新这些快捷方式。
旧版快捷方式仍然保留了它们在旧版 Android 中的功能,但您必须在应用中手动将它们转换成应用快捷方式。
为降低功耗,无论应用的目标 SDK 版本为何,Android 8.0 都会对后台应用检索用户当前位置的频率进行限制。
如果您的应用在后台运行时依赖实时提醒或运动检测,这一位置检索行为就显得特别重要,必须紧记。
重要说明:作为起点,我们只允许后台应用每小时接收几次位置更新。我们将在整个预览版阶段继续根据系统影响和开发者的反馈优化位置更新间隔。