Android O/Android P行为变更及适配

Android O行为变更

后台服务运行的限制:

当应用进入后台状态几分钟后,android系统就会将app视为空闲状态并停止该app的后台服务。所以不能依赖后台service做定时性的任务。

前台服务启动的限制:

在 Android 8.0之前,创建前台服务的方式通常是先创建一个后台服务(context.startService()),然后将该服务推到前台(startForeground())。但是android8.0上,系统不允许后台应用创建后台服务。因此,Android 8.0 引入了一种全新的方法,即 Context.startForegroundService(),以在前台启动新服务。在系统创建服务后,应用有五秒的时间来调用服务的 startForeground() 方法以显示新服务的用户可见通知。如果应用在此时间限制用 startForeground(),则系统将停止服务并声明此应用为 ANR。针对这一变动,如果app需要定时地在后台执行一些任务,google建议使用Jobscheduler来实现,但是经测试发现,在国产手机中,Jobscheduler并不能正常工作。

广播限制:

如果应用注册接收广播,则在每次发送广播时,应用的接收器都会消耗资源。 如果多个应用注册为接收基于系统事件的广播,这会引发问题;触发广播的系统事件会导致所有应用快速地连续消耗资源,从而降低用户体验。为了缓解这一问题,Android 7.0(API 级别 25)对广播施加了一些限制,Android 8.0 让这些限制更为严格。大多数系统的隐式广播,app将无法再接收到。除了以下广播,见链接https://blog.csdn.net/hqocshheqing/article/details/76850164

针对被限制的隐式广播,虽然不能在清单文件中进行注册,但是可以在代码中进行动态注册,Context.registerReceiver().

后台位置限制:

为降低功耗,无论应用的目标 SDK 版本为何,Android 8.0 都会对后台应用检索用户当前位置的频率进行限制。

如果您的应用在后台运行时依赖实时提醒或运动检测,这一位置检索行为就显得特别重要,必须紧记。

通知栏变化:

Android O,对Notification引入了Notification Channel的概念,当app tagrget >=26,发送通知时就必须加入channel id参数,否则通知无法再通知栏显示。

意味着app必须初始化通知渠道,并且对于一个应用来说,通知渠道只能初始化一次,如果想重新加入更多的渠道,用户必须卸载app并重新安装。所以建议在初始化通知渠道的时候,将各个重要性等级的通知渠道都添加。

Starting in Android 8.0 (API level 26), all notifications must be assigned to a channel. For each channel, you can set the visual and auditory behavior that is applied to all notifications in that channel. Then, users can change these settings and decide which notification channels from your app should be intrusive or visible at all.

示例代码:

private void createNotificationChannel() {
    // Create the NotificationChannel, but only on API 26+ because
    // the NotificationChannel class is new and not in the support library
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        CharSequence name = getString(R.string.channel_name);
        String description = getString(R.string.channel_description);
        int importance = NotificationManager.IMPORTANCE_DEFAULT;
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
        channel.setDescription(description);
        // Register the channel with the system; you can't change the importance
        // or other notification behaviors after this
        NotificationManager notificationManager = getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(channel);
    }
}

chanel的样式一旦指定,后面就不能再更改,除非用户更改。所以可以在app的settings界面,添加一个改动通知样式的入口,代码实例:

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

 

运行时限制:

在 Android 8.0 之前,如果应用在运行时请求权限并且被授予该权限,系统会错误地将属于同一权限组并且在清单中注册的其他权限也一起授予应用。 
对于针对 Android 8.0 的应用,此行为已被纠正。系统只会授予应用明确请求的权限。然而,一旦用户为应用授予某个权限,则所有后续对该权限组中权限的请求都将被自动批准。 
例如,假设某个应用在其清单中列出 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE。应用请求 READ_EXTERNAL_STORAGE,并且用户授予了该权限。如果该应用针对的是 API 级别 24 或更低级别,系统还会同时授予 WRITE_EXTERNAL_STORAGE,因为该权限也属于同一 STORAGE 权限组并且也在清单中注册过。如果该应用针对的是 Android 8.0,则系统此时仅会授予 READ_EXTERNAL_STORAGE;不过,如果该应用后来又请求 WRITE_EXTERNAL_STORAGE,则系统会立即授予该权限,而不会提示用户。

悬浮窗适配:

使用 SYSTEM_ALERT_WINDOW 权限的应用无法再使用以下窗口类型来在其他应用和系统窗口上方显示提醒窗口:

TYPE_PHONE

TYPE_PRIORITY_PHONE

TYPE_SYSTEM_ALERT

TYPE_SYSTEM_OVERLAY

TYPE_SYSTEM_ERROR

相反,应用必须使用名为 TYPE_APPLICATION_OVERLAY 的新窗口类型。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { mWindowParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY }else { mWindowParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT }

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />

安装Apk:

Android 8.0去除了“允许未知来源”选项,所以如果我们的App有安装App的功能(检查更新之类的),那么会无法正常安装。

首先在AndroidManifest文件中添加安装未知来源应用的权限:

<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>

这样系统会自动询问用户完成授权。当然你也可以先使用 canRequestPackageInstalls()查询是否有此权限,如果没有的话使用Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES这个action将用户引导至安装未知应用权限界面去授权。

 

新功能:

  1. 全面屏适配。app未进行全面屏适配前,在全面屏手机上底部会有黑色空白。适配方法:

<application>

……

<meta-data android:name="android.max_aspect" android:value="2.4" />

</application>

 

2、能自动改变大小的textview,可利用support v4中的textviewcompat

3、自适应app图标,app图标显示行为能自适应手机系统。

4、快捷方式(Shortcut),长按app桌面图标,可以弹出一些快捷入口。
     

5、自动填充框架。帐号创建、登录和信用卡交易需要时间并且容易出错。在使用要求执行此类重复性任务的应用时,用户很容易遭受挫折。

Android 8.0 通过引入自动填充框架,简化了登录和信用卡表单之类表单的填写工作。在用户选择接受自动填充之后,新老应用都可使用自动填充框架。

6、画中画模式。

7、Contentprovider支持分页。

8、JobScheduler 改进。

新功能的代码Demo链接:

https://developer.android.com/about/versions/oreo/android-8.0-samples

Android P行为变更:

1、禁止访问android SDK非公开接口。

2、屏幕缺口支持。可以查询当前手机的开口位置和尺寸。

3、针对 Android P 或更高版本并使用前台服务的应用必须请求 FOREGROUND_SERVICE 权限。 这是普通权限,因此,系统会自动为请求权限的应用授予此权限。

4、Build.SERIAL 字段在 Android 8.0(API 级别 26)中已被弃用。 在 Android P 中,Build.SERIAL 始终设置为 "UNKNOWN"。 此变更旨在保护用户的隐私。如果您的应用需要访问设备的硬件序列号,您应请求 READ_PHONE_STATE 权限,然后调用 getSerial()

5、同一应用的不同进程不在共享cookie,如果需要,可以手工传输。

6、在 Android P 中,您不能从非 Activity 环境中启动 Activity,除非您传递 Intent 标志 FLAG_ACTIVITY_NEW_TASK。 如果您尝试在不传递此标志的情况下启动 Activity,则该 Activity 不会启动,系统会在日志中输出一则消息。

7、通知增强,以及对android o引入的channel功能添加了小的修改。

8、适用于位图和可绘制对象的 ImageDecoder,可以用于替代现在的BitmapFactory.

9、Android P 引入了一个新的 AnimatedImageDrawable 类,用于绘制和显示 GIF 和 WebP 动画图像。

10、为避免无意的旋转,我们新增了一个模式,哪怕设备位置发生变化,也会固定在当前屏幕方向上。

猜你喜欢

转载自blog.csdn.net/HelloMagina/article/details/81502393