其他分享
首页 > 其他分享> > Android 10 适配攻略,深度解析跳槽从开始到结束完整流程

Android 10 适配攻略,深度解析跳槽从开始到结束完整流程

作者:互联网

应用在卸载后,会将App-specific目录下的数据删除,如果在AndroidManifest.xml中声明:android:hasFragileUserData="true"用户可以选择是否保留。

对于SAF的使用,可以查看我之前写的SAF使用攻略,这里就不展开说了。

最后这里有一个介绍Scoped Storage的视频,推荐观看:

准备好使用分区存储 | ADS 中文字幕视频

准备好使用分区存储

2.权限变化

=================================================================

从6.0开始,基本每次都会有权限方面变动,这次也不例外。(前几天发布了Android 11的预览版,看来也有权限方面的变化。。。单次权限即将到来)

1.在后台运行时访问设备位置信息需要权限

Android 10 引入了 ACCESS_BACKGROUND_LOCATION 权限(危险权限)。

该权限允许应用程序在后台访问位置。如果请求此权限,则还必须请求ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION权限。只请求此权限无效果。

在Android 10的设备上,如果你的应用的 targetSdkVersion < 29,则在请求ACCESS_FINE_LOCATION 或ACCESS_COARSE_LOCATION权限时,系统会自动同时请求ACCESS_BACKGROUND_LOCATION。在请求弹框中,选择“始终允许”表示同意后台获取位置信息,选择“仅在应用使用过程中允许”或"拒绝"选项表示拒绝授权。

如果你的应用的 targetSdkVersion >= 29,则请求ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION权限表示在前台时拥有访问设备位置信息的权。在请求弹框中,选择“始终允许”表示前后台都可以获取位置信息,选择“仅在应用使用过程中允许”只表示拥有前台的权限。

总结一下就是下图:

在这里插入图片描述

其实官方不推荐你使用申请后台访问权的方式,因为这样的结果无非就是多请求一个权限,那么这像变更还有什么意义?申请过多的权限,也会造成用户的反感。所以官方推荐使用前台服务来实现,在前台服务中获取位置信息。

<service

android:name=“MyNavigationService”

android:foregroundServiceType=“location” … >

boolean permissionApproved = ActivityCompat.checkSelfPermission(this,

Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;

if (permissionApproved) {

// 启动前台服务

} else {

// 请求前台访问位置权限

}

如此一来就可以在Service中获取位置信息。

2.一些电话、蓝牙和WLAN的API需要精确位置权限

下面列举了Android 10中必须具有 ACCESS_FINE_LOCATION 权限才能使用类和方法:

TelephonyManager

getCellLocation()

getAllCellInfo()

requestNetworkScan()

requestCellInfoUpdate()

getAvailableNetworks()

getServiceState()

TelephonyScanManager

requestNetworkScan()

TelephonyScanManager.NetworkScanCallback

onResults()

PhoneStateListener

onCellLocationChanged()

onCellInfoChanged()

onServiceStateChanged()

WifiManager

startScan()

getScanResults()

getConnectionInfo()

getConfiguredNetworks()

WifiAwareManager

WifiP2pManager

WifiRttManager

BluetoothAdapter

startDiscovery()

startLeScan()

BluetoothAdapter.LeScanCallback

BluetoothLeScanner

startScan()

我们可以根据上面提供的具体类和方法,在适配项目中检查是否有使用到并及时处理。

3.ACCESS_MEDIA_LOCATION

Android 10新增权限,上面有提到,不赘述了。

4.PROCESS_OUTGOING_CALLS

Android 10上该权限已废弃。

3.后台启动 Activity 的限制

==============================================================================

简单解释就是应用处于后台时,无法启动Activity。比如点开一个应用会进入启动页或者广告页,一般会有几秒的延时再跳转至首页。如果这期间你退到后台,那么你将无法看到跳转过程。而在之前的版本中,会强制弹出页面至前台。

既然是限制,那么肯定有不受限的情况,主要有以下几点:

因为此项行为变更适用于在 Android 10 上运行的所有应用,所以这一限制导致最明显的问题就是点击推送信息时,有些应用无法进行正常的跳转(具体的实现问题导致)。所以针对这类问题,可以采取PendingIntent的方式,发送通知时使用setContentIntent方法。

当然你也可以申请相应权限或者白名单:

在这里插入图片描述

不过申请白名单这种方法受各种手机厂商所限,很麻烦。感觉还不如引导用户手动开启权限。。。

对于全屏 intent,注意设置最高优先级和添加USE_FULL_SCREEN_INTENT权限,这是一个普通权限。比如微信来语音或者视频通话时,弹出的接听页面就是使用这一功能。

Intent fullScreenIntent = new Intent(this, CallActivity.class);

PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(this, 0,

fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);

NotificationCompat.Builder notificationBuilder =

new NotificationCompat.Builder(this, CHANNEL_ID)

.setSmallIcon(R.drawable.notification_icon)

.setContentTitle(“Incoming call”)

.setContentText("(919) 555-1234")

.setPriority(NotificationCompat.PRIORITY_HIGH) // <— 高优先级

.setCategory(NotificationCompat.CATEGORY_CALL)

// Use a full-screen intent only for the highest-priority alerts where you

// have an associated activity that you would like to launch after the user

// interacts with the notification. Also, if your app targets Android 10

// or higher, you need to request the USE_FULL_SCREEN_INTENT permission in

// order for the platform to invoke this notification.

.setFullScreenIntent(fullScreenPendingIntent, true); // <— 全屏 intent

Notification incomingCallNotification = notificationBuilder.build();

注意:在部分手机上,直接设置setPriority无效(或者说以渠道优先级为准)。所以需要创建通知渠道时将重要性设置为IMPORTANCE_HIGH。

NotificationChannel channel = new NotificationChannel(channelId, “xxx”, NotificationManager.IMPORTANCE_HIGH);

后台启动 Activity 的限制的目的是为了减少对用户操作的中断。如果你有要弹出的页面,推荐你先弹出通知,让用户自己选择接下来的操作,而不是一股脑的强制弹出。(如果你的全屏intent都让用户反感,那他也可以关掉你的通知,不至于任你摆布。)

4.深色主题

=================================================================

Android 10 新增了一个系统级的深色主题(在系统设置中开启)。虽然深色主题并不是强制适配项,但是它可以带给用户更好的体验:

适配方法有两种:

1.手动适配(资源替换)

官方文档中提到的继承Theme.AppCompat.DayNight 或者 Theme.MaterialComponents.DayNight的方法,但这只是将我们使用的各种View的默认样式进行了适配,并不太适用于实际项目的适配。因为具体的项目中的View都按照设计的风格进行了重定义。

其实适配的方法很简单,类似屏幕适配、国际化的操作,并不需要继承上面的主题。比如你要修改颜色,就在res 下新建 values-night目录,创建对应的colors.xml文件。将具体要修改的色值定义在里面。图标之类的也是一个思路,创建对应的 drawable-night目录。

只要你之前的代码不是硬编码且代码规范,那么适配起来还是很轻松。

2.自动适配(Force Dark)

Android 10 提供 Force Dark 功能。一如其名,此功能可让开发者快速实现深色主题背景,而无需明确设置 DayNight 主题背景。

如果您的应用采用浅色主题背景,则 Force Dark 会分析应用的每个视图,并在相应视图在屏幕上显示之前,自动应用深色主题背景。有些开发者会混合使用 Force Dark 和本机实现,以缩短实现深色主题背景所需的时间。

应用必须选择启用 Force Dark,方法是在其主题背景中设置 android:forceDarkAllowed=“true”。此属性会在所有系统及 AndroidX 提供的浅色主题背景(例如 Theme.Material.Light)上设置。使用 Force Dark 时,您应确保全面测试应用,并根据需要排除视图。

如果您的应用使用Dark Theme主题(例如Theme.Material),则系统不会应用 Force Dark。同样,如果应用的主题背景继承自 DayNight 主题(例如Theme.AppCompat.DayNight),则系统不会应用 Force Dark,因为会自动切换主题背景。

您可以通过 android:forceDarkAllowed 布局属性或 setForceDarkAllowed(boolean) 在特定视图上控制 Force Dark。

上述内容我直接照搬文档的说明。总结一下,使用Force Dark需要注意几点:

这里说说我实际使用此方法的感受:整体还是不错的,设置的色值会自动取反。但也因此颜色不受控制,能否达到预期效果是个需要注意的问题。追求快速适配可以采取此方案。

手动切换主题

使用 AppCompatDelegate.setDefaultNightMode(@NightMode int mode)方法,其中参数mode有以下几种:

下面的代码是官方Demo中的使用示例:

public class ThemeHelper {

public static final String LIGHT_MODE = “light”;

public static final String DARK_MODE = “dark”;

public static final String DEFAULT_MODE = “default”;

public static void applyTheme(@NonNull String themePref) {

switch (themePref) {

case LIGHT_MODE: {

AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);

break;

}

case DARK_MODE: {

AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);

break;

}

default: {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {

AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);

} else {

AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY);

}

break;

}

}

}

}

通过AppCompatDelegate.getDefaultNightMode()方法,可以获取到当前的模式,这样便于代码中去适配。

监听深色主题是否开启

首先在清单文件中给对应的Activity配置 android:configChanges=“uiMode”:

<activity

android:name=".MyActivity"

android:configChanges=“uiMode” />

这样在onConfigurationChanged方法中就可以获取:

@Override

public void onConfigurationChanged(@NonNull Configuration newConfig) {

super.onConfigurationChanged(newConfig);

int currentNightMode = newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK;

switch (currentNightMode) {

case Configuration.UI_MODE_NIGHT_NO:

// 关闭

break;

case Configuration.UI_MODE_NIGHT_YES:

// 开启

break;

default:

break;

}

}

详细的内容你可以参看官方文档和官方Demo。

判断深色主题是否开启

其实和上面onConfigurationChanged方法同理:

public static boolean isNightMode(Context context) {

int currentNightMode = context.getResources().getConfiguration().uiMode &

Configuration.UI_MODE_NIGHT_MASK;

return currentNightMode == Configuration.UI_MODE_NIGHT_YES;

}

5.标识符和数据

===================================================================

对不可重置的设备标识符实施了限制

受影响的方法包括:

getSerial()

作者2013年从java开发,转做Android开发,在小厂待过,也去过华为,OPPO等大厂待过,18年四月份进了阿里一直到现在。

参与过不少面试,也当面试官 面试过很多人。深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长,而且极易碰到天花板技术停滞不前!

我整理了一份阿里P7级别的最系统的Android开发主流技术,特别适合有3-5年以上经验的小伙伴深入学习提升。

主要包括阿里,以及字节跳动,腾讯,华为,小米,等一线互联网公司主流架构技术。如果你想深入系统学习Android开发,成为一名合格的高级工程师,可以收藏一下这些Android进阶技术选型

我搜集整理过这几年阿里,以及腾讯,字节跳动,华为,小米等公司的面试题,把面试的要求和技术点梳理成一份大而全的“ Android架构师”面试 Xmind(实际上比预期多花了不少精力),包含知识脉络 + 分支细节。

Java语言与原理;
大厂,小厂。Android面试先看你熟不熟悉Java语言

高级UI与自定义view;
自定义view,Android开发的基本功。

性能调优;
数据结构算法,设计模式。都是这里面的关键基础和重点需要熟练的。

NDK开发;
未来的方向,高薪必会。

前沿技术;
组件化,热升级,热修复,框架设计

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

我在搭建这些技术框架的时候,还整理了系统的高级进阶教程,会比自己碎片化学习效果强太多,CodeChina上可见;

当然,想要深入学习并掌握这些能力,并不简单。关于如何学习,做程序员这一行什么工作强度大家都懂,但是不管工作多忙,每周也要雷打不动的抽出 2 小时用来学习。

不出半年,你就能看出变化!

Java语言与原理;*
大厂,小厂。Android面试先看你熟不熟悉Java语言

[外链图片转存中…(img-WExg4tx6-1643518291431)]

高级UI与自定义view;
自定义view,Android开发的基本功。

[外链图片转存中…(img-6HlOD06u-1643518291431)]

性能调优;
数据结构算法,设计模式。都是这里面的关键基础和重点需要熟练的。

[外链图片转存中…(img-AJ7c2lRd-1643518291432)]

NDK开发;
未来的方向,高薪必会。

[外链图片转存中…(img-00R3TlGc-1643518291432)]

前沿技术;
组件化,热升级,热修复,框架设计

[外链图片转存中…(img-pNO0jW1a-1643518291432)]

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

我在搭建这些技术框架的时候,还整理了系统的高级进阶教程,会比自己碎片化学习效果强太多,CodeChina上可见;

当然,想要深入学习并掌握这些能力,并不简单。关于如何学习,做程序员这一行什么工作强度大家都懂,但是不管工作多忙,每周也要雷打不动的抽出 2 小时用来学习。

不出半年,你就能看出变化!

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

标签:10,适配,MODE,应用,NIGHT,Android,权限
来源: https://blog.csdn.net/m0_66144910/article/details/122751970