AndroidQ介绍与版本适配
Android Q 也就是 Andriod 10 对应的 api为29
api26对应安卓版本 api对应的安卓版本
App要适配的话主要通过设置下面的style:
以及使用此属性 ?android:attr/textColorPrimary
另外谷歌提供了一个 Force Dark开关
具体信息可查看 Q暗黑模式Google官方介绍
Android 10 可控制无需用户确认按键
setConfirmationRequired(false)
当用户的生物识别不可用时,可以设置 setDeviceCredentialAllowed() 允许用户使用PIN、手势密码、数字密码来通过认证。
(1) 适配分为2种
(2) 谷歌及各大应用市场对于适配的时间要求:
如果我们项目原本的api是25 ,要直接升到 api29,我们就需要进行:Andoird O、Android P、Android Q适配,三个适配阶段都需要。
下面会简要介绍下这几个api的适配:
创建通知前需要创建渠道,创建通知时需要传入 channelId。
2.1 什么是前台应用?(这里的前台应用指的是对于Service限制来说)
2.2 什么是后台服务限制?
2.3 解决方案:
设置了透明主题的Activity,再设置屏幕方向
抛出以下异常
推测是Google8.0手机的bug,在之后的版本已经修复。
3.2.1 webview数据目录变更
如果在api设置为28后,多进程使用同一个目录webView
抛出异常:
解决:为不同的进程设置不同的webview数据目录
3.2.2 Apache HTTP客户端弃用
在 Android 6.0 中,谷歌取消了对 Apache HTTP 客户端的支持。 从 Android 9 开始,默认情况下该内容库已从 bootclasspath 中移除且不可用于应用。要继续使用 Apache HTTP 客户端,以 Android 9 及更高版本为目标的应用可以向其 AndroidManifest.xml 添加以下内容:
3.2.3 非sdk接口管控
官方检查器veridex用来检测一个apk中哪里使用了非SDK接口。
扫描结果类似于下图(图片来自 Android P版本 (七)veridex工具扫描非 SDK 接口 ,veridex使用方法也可以参考此文):
3.2.4 前台服务
针对 Android 9 或更高版本并使用前台服务的应用需要请求 FOREGROUND_SERVICE 权限,系统会自动为请求权限的应用授予此权限。如果针对 Android 9 或更高版本的应用尝试创建一个前台服务且未请求 FOREGROUND_SERVICE ,则系统会引发 SecurityException 。
3.3.1应用存储空间变更
默认情况下,如果应用以 Android Q 为目标平台,则在访问外部存储设备中的文件时会进入过滤视图。应用可以使用· Context.getExternalFilesDir() ·将专用于自己的文件存储在特定于自己的目录中。具有过滤视图的应用对其创建的文件始终拥有读/写权限,无论文件位于特定于此应用的目录以内还是以外。应用无需声明任何存储权限即可访问这些文件。
只有在满足以下两个条件时,应用才能访问其他应用创建的文件:
Google Q版本应用兼容性整改指导
华为开发者联盟文档中心
Google Android-8.0-migration
搞了个android tv盒子,想修改默认的launcher桌面,网上搜了好几天,没有成功。即使设置了如下默认开机launcher在android tv系统中也不会出来选择开启哪个launcher的选择框,可能android tv 系统跟android 系统还不太一样啊。
于是乎就在网上到处搜方法,还真搜到了一个在模拟器上成功替换默认桌面的方法。
我的模拟器android 版本是 api level 26 应该是android tv 8.0
呃,要进行替换首先模拟器上要有root权限。但是因为android 7.0之后的模拟器都默认没有root权限了。需要这样再命令行启动模拟器。找到自己的模拟器目录:
模拟器起来后,执行adb shell,提示符是$,表示没有root权限,然后su,提示符变成#,获取到root权限。
执行 pm disable-user --user 0 com.google.android.tvlauncher ,禁用google默认的android tv 桌面。执行之前一定要先安装自己的有 android.intent.category.HOME android.intent.category.LAUNCHER android.intent.category.DEFAULT 的app 哦
之后冷重新启动模拟器,你就会发现开机后的桌面变成了自己的app啦。
有空试试我的android tv 机顶盒,看看行不行。
关于不同android tv 版本禁用 google默认 launcher的命令如下,自己多试试,版本对应不一定对,原帖地址是: Alternate Launcher (No Root) on Marshmallow, Nougat, Oreo, Pie Info ,为了方便我把内容转过来:
呃。。。。恢复原有桌面。。。。
Android 8.0不支持style里的windowIsTranslucent透明属性 和AndroidManifes清单文件里的锁定屏幕方向screenOrientation的属性。
解决方法:
1.删除AndroidManifes.xml里面的"android:screenOrientation=""全部去掉,然后在自己的BaseActivity的onCreate中加上
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//设置屏幕方向
2.如果要保持页面半透明的话,style可以单独针对不同的api来设置,api26(8.0)的可以单独设置一种style,
```
然后再设置一个比它高的(举个例子:style-v28),style是向下兼容,高版本的会先找到低api的style,前提是这些theme 同名 ;就像drawable不同分辨率一样命名。
在Android O原生桌面上,按照传统创建快捷方式的形式,是不会产生快捷方式的。
传统方式如下:
从Android 7.1(API 25)开始,新增了ShortcutManager,可以对桌面久按应用图标弹出的快捷方式进行管理。
但是,Android 7.1上直接往桌面上添加快捷方式依然是使用上面说到的这种旧方式,但是Android O上,Google应该是想通过比较统一的接口来管理桌面快捷方式了,所以摒弃了这种形式,转而使用ShortcutManager进行管理。所以API 26上,ShortcutManager进行管理。所以API 26上,ShortcutManager新增了对Pinned Shortcuts(固定快捷方式)的管理。
官文:
Apps can pin an existing shortcut (either static or dynamic) or an entirely new shortcut to a supported launcher programatically using requestPinShortcut(ShortcutInfo, IntentSender). You pass two arguments into this method:
A ShortcutInfo object – If the shortcut already exists, this object should contain only the shortcut’s ID. Otherwise, the new ShortcutInfo object must contain an ID, an intent, and a short label for the new shortcut.
A PendingIntent object – This intent represents the callback that your app receives if the shortcut is successfully pinned to the device’s launcher.
Note: If the user doesn’t allow the shortcut to be pinned to the launcher, the pinning process fails, and the Intent object that is passed into this PendingIntent object isn’t executed.
Note: Due to background execution limits introduced in Android O, it’s best to use a manifest-declared receiver to receive a callback.
Also, to prevent other apps from invoking the receiver, add the attribute assignment android:exported=”false” to the receiver’s manifest entry.
Note: As you add logic in your app to make requests to pin shortcuts, keep in mind that not all launchers support pinning of shortcuts. To determine whether your app can complete this process on a particular device, check the return value of isRequestPinShortcutSupported(). Based on this return value, you might decide to hide the option in your app that allows users to pin a shortcut.
Note: See also the support library APIs isRequestPinShortcutSupported(Context) and requestPinShortcut(Context, ShortcutInfoCompat, IntentSender), which works on Android versions lower than O by falling back to the deprecated private intent com.android.launcher.action.INSTALL_SHORTCUT.
译:
应用程序可以使用requestPinShortcut(ShortcutInfo,IntentSender)将现有的快捷方式(静态或动态)或全新的快捷方式固定到支持的启动器。你通过这个方法的两个参数:
ShortcutInfo对象 - 如果快捷方式已存在,则该对象应仅包含快捷方式的ID。否则,新的ShortcutInfo对象必须包含新快捷方式的ID,意图和短标签。
PendingIntent对象 - 此意图表示如果快捷方式成功固定到设备的启动器,您的应用程序将收到回调。
注意:如果用户不允许将快捷方式固定在启动器上,则固定进程将失败,并且未执行传入此PendingIntent对象的Intent对象。
注意:由于Android O中引入的后台执行限制,最好使用清单声明的接收器来接收回调。
另外,为了防止其他应用程序调用接收器,将属性赋值android:exported =“false”添加到接收者的清单条目中。
注意:当您在应用程序中添加逻辑以引导快捷方式时,请记住,并非所有启动器都支持固定快捷方式。 要确定您的应用程序是否可以在特定设备上完成此过程,请检查isRequestPinShortcutSupported()的返回值。 根据此返回值,您可以决定隐藏您应用程序中允许用户固定快捷方式的选项。
注意:另请参见支持库API isRequestPinShortcutSupported(Context)和requestPinShortcut(Context,ShortcutInfoCompat,IntentSender),它可以在低于O的Android版本上运行,因为它们回落到不推荐使用的私有意图com.android.launcher.action.INSTALL_SHORTCUT。
ShortcutManager类在API level 26上,增加了对isRequestPinShortcutSupported、requestPinShortcut、createShortcutResultIntent三个方法。说明如下:
1.isRequestPinShortcutSupported
官文:
Return TRUE if the app is running on a device whose default launcher supports requestPinShortcut(ShortcutInfo, IntentSender).
The return value may change in subsequent calls if the user changes the default launcher app.
Note: See also the support library counterpart isRequestPinShortcutSupported(Context), which supports Android versions lower than O using the legacy private intent com.android.launcher.action.INSTALL_SHORTCUT.
译:
如果默认桌面支持requestPinShortcut(ShortcutInfo,IntentSender)方法,则返回TRUE。
如果用户更改默认启动程序应用程序,返回值可能会在后续调用中更改。
注意:另请参见支持库对应的isRequestPinShortcutSupported(Context),在低于O的Android版本,它支持使用旧的私有意图com.android.launcher.action.INSTALL_SHORTCUT。
2.requestPinShortcut
官文:
Request to create a pinned shortcut. The default launcher will receive this request and ask the user for approval. If the user approves it, the shortcut will be created, and resultIntent will be sent. If a request is denied by the user, however, no response will be sent to the caller.
Only apps with a foreground activity or a foreground service can call this method. Otherwise, it’ll throw IllegalStateException.
It’s up to the launcher to decide how to handle previous pending requests when the same package calls this API multiple times in a row. One possible strategy is to ignore any previous requests.
Note: See also the support library counterpart requestPinShortcut(Context, ShortcutInfoCompat, IntentSender), which supports Android versions lower than O using the legacy private intent com.android.launcher.action.INSTALL_SHORTCUT.
译:
请求创建固定的快捷方式。默认启动器将收到该请求,并要求用户批准。如果用户批准,将创建快捷方式,并且将发送resultIntent。但是,如果请求被用户拒绝,则不会向呼叫者发送任何响应。
只有具有前台活动或前台服务的应用程序才能调用此方法。否则,它将抛出IllegalStateException。
当同一个软件包连续多次调用该API时,由开发人员决定如何处理以前的待处理请求。一个可能的策略是忽略任何先前的请求。
注意:另请参见支持库对应件requestPinShortcut(Context,ShortcutInfoCompat,IntentSender),在低于O的Android版本,它支持使用旧的私有意图com.android.launcher.action.INSTALL_SHORTCUT。
3.createShortcutResultIntent
官文:
Returns an Intent which can be used by the default launcher to pin a shortcut containing the given ShortcutInfo. This method should be used by an Activity to set a result in response to ACTION_CREATE_SHORTCUT.
译:
返回默认启动器可以使用的Intent来固定包含给定的ShortcutInfo的快捷方式。 Activity应该使用此方法来设置响应ACTION_CREATE_SHORTCUT的结果。
根据弹窗提示可以看出,可以通过拖动这个图标往桌面上添加快捷方式,可以通过点击自动添加按键,系统给你在桌面的默认位置上添加。
添加后,桌面上会出现如图所示的图标:
回调用到的Receiver:
打印log发现,onReceive如图官方文档所说,点击弹框自动添加按键后,会得到回调。但实践发现,如果桌面上已经添加了图标,当再次调用requestPinShortcut进行添加时,onReceive会在调用requestPinShortcut的时候,直接被回调,而且弹框也会弹出来。
在以上三个方法官方介绍中,官方提示我们,可以使用Android support库的ShortcutManagerCompat进行快捷方式的版本适配。于是,在build.gradle中添加依赖进行尝试: