记录一下从targetSdkVersion从29 升级到31 来适配Android12项目中遇到的比较严重的问题及解决方法
1、 android:exported
属性
只要你清单文件的Activity、Service、BroadcastReceiver 含有<intent-filter> 标签的话,就需要显示声明android:exported
属性,若是未显式声明 android:exported
的值,您的应用将无法在搭载 Android 12 或更高版本的设备上进行安装。
<activity android:name=".SplashActivity" android:exported="true" android:theme="@style/LanuchTheme"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
2、PendingIntent 可变性
必须为应用中的每个PendingIntent对象指定可变性 android 12 必须使用 PendingIntent.FLAG_MUTABLE 模式,比如说app升级通知广播,和nfc交互等地方
适配前
PendingIntent intent = PendingIntent.getActivity(
this,
0,
Intent(this, javaClass),
PendingIntent.FLAG_ONE_SHOT
);
适配12后
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
//android 12 必须使用 PendingIntent.FLAG_MUTABLE 模式
intent = PendingIntent.getActivity(
this, 0,
Intent(this, javaClass), PendingIntent.FLAG_MUTABLE
)
} else {
intent = PendingIntent.getActivity(
this,
0,
Intent(this, javaClass),
PendingIntent.FLAG_ONE_SHOT
);
}
3、READ_PHONE_STATE权限问题
在使用华为的扫码服务的时候发现,在调用相机扫码的时候若是没有获取READ_PHONE_STATE权限的话而导致crash,所以再使用扫码服务的时候需要动态申请此权限
4、图片储存图库不显示问题
由于Android 10 之后 对文件系统的权限控制开始进行收紧,很多老的API已经不适用了,下面的是替换这个问题的最简单的方法
// String storageDir = Environment.getExternalStorageDirectory().getAbsolutePath() + "/ryathon";
//适配targetVersion == 31 使用下面的路径拍照之后才会回显照片
String storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath() + "/ryathon";
5、 友盟第三方登录显示没有安装应用的问题
从Android 11开始,需要在AndroidManifest.xml清单文件中加入query权限申请,才能检测到手机上安装的三方应用包安装状态
<queries>
<package android:name="com.tencent.mm" />
<package android:name="com.tencent.mobileqq" />
...
</queries>
6、自定义toast 的问题
从android 11(R) 以上 自定义toast 相应的api 已经被禁止使用,所以,Toast.getView()会返回null,建议使用官网原生的版本,原生Toast在android12 及以上显示带icon的toas
7、获取精确定位的问题
在 Android 12(API 级别 31)或更高版本中,用户仍可以请求该应用只检索大致位置信息,即使该应用请求 ACCESS_FINE_LOCATION 运行时权限也是如此。 要处理这种可能会出现的用户行为,请勿单独请求 ACCESS_FINE_LOCATION 权限,而应在单个运行时请求中同时请求 ACCESS_FINE_LOCATION 权限和 ACCESS_COARSE_LOCATION 权限