1、升级项目的build.gradle的gradle插件版本,升级到版本7.2.1
2、升级所需的gradle的版本升级到7.4.2
可以看我往期博客,如何配gradle的版本问题:
gradle各版本下载地址_唯我独黑wang的博客-优快云博客x
修改
3、升级android studio到最新的版本2021.2.1 Patch1
android studio的help、check for updates去检查更新即可
4、添加 android:exported的设置
凡是在androidmanifest中声明了 <intent-filter> 过滤器的组件必须显式设置 android:exported 属性
所有设置了intent-filters的activity、services、broadcast、receivers都需要设置 android:exported为false
,否则会导致编译异常,App 将会无法安装
在四大组件的根标签下添加
android:exported="false"
另外的是在启动的activity中将此值设为
android:exported="true"
5、将 所有的http的请求改为https(补android11留下的坑)
去掉androidmanifest中application跟标签下的这2行代码:
android:networkSecurityConfig="@xml/network_security_config"
android:usesCleartextTraffic="true"
并去掉network_security_config这个文件
6、关于蓝牙功能的修改
6.1 添加权限 android12添加了3个新的运行时权限,并根据自己的情况选择加的权限。
<!--请求旧设备上的传统蓝牙权限-->
<uses-permission android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" />
<!--Android12的蓝牙权限 查找蓝牙设备,需要动态获取权限,下面加的一行代码表示不提供蓝牙设备推导你的位置-->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation"/>
<!--Android12的蓝牙权限 使当前设备可被其他蓝牙设备检测到-->
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<!--Android12蓝牙权限 与已配对的蓝牙设备通信或者获取当前手机蓝牙是否打开-->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
6.2 动态申请权限
private List<String> mPermissionList = new ArrayList<>();
// 动态申请权限
private void initNewPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
// Android 版本大于等于 Android12 时,需要加入以下蓝牙权限,不需要被别人搜到可以不索要这个权限
mPermissionList.add(Manifest.permission.BLUETOOTH_ADVERTISE);
mPermissionList.add(Manifest.permission.BLUETOOTH_SCAN);
mPermissionList.add(Manifest.permission.BLUETOOTH_CONNECT);
} else {
// Android 版本小于Android12及以下版本,加以下的权限
mPermissionList.add(Manifest.permission.ACCESS_FINE_LOCATION);
mPermissionList.add(Manifest.permission.ACCESS_COARSE_LOCATION);
}
if (mPermissionList.size() > 0) {
ActivityCompat.requestPermissions(this, mPermissionList.toArray(new String[0]), 10000);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// 有权限没有允许
boolean hasPermissionDismiss = false;
if (10000 == requestCode) {
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] == -1) {
hasPermissionDismiss = true;
break;
}
}
}
if (hasPermissionDismiss) {
// 有权限未全部允许,再次请求权限
initNewPermission();
Util.showSingleToast(getResources().getString(R.string.permission_not_allow));
} else {
//权限全部允许
}
}
6.3 加 @SuppressLint("MissingPermission"),去掉错误提示
在scanDevice、getName等蓝牙的读取、连接、扫描等方法前面加注解
@SuppressLint("MissingPermission")
7、关闭备份限制
为了安全考虑,android 12的设置中需要将 android:allowBackup设置为false,或者直接删掉这一行。默认值即为false。
<application
android:name=".App"
android:allowBackup="false"
....../>
8、webview访问文件assets之外的文件(后期完善部分)
8.1 webview访问data下的文件
设置setAllowFileAccess为true,就可以 使用file://加载文件。这是所有file协议的总开关。
websetting.setAllowFileAccess(false);
webView.loadUrl("file:///data/data/com.xxx/files/index.html");
8.2、setAllowContentAccess
当设置为true,就可以 使用content://加载文件。
webView.loadUrl("content://com.xxx.test_provider/my_files_path/index.html");
其中 com.xxx.test_provider 为FileProvider authorities,在AndroidManifest.xml声明如下:
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.xxx.test_provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
xml/filepaths 声明如下:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<root-path name="my_root" path="."/>
<external-path name="my_external" path="."/>
<files-path name="my_files_path" path="."/>
<cache-path name="my_cache_path" path="."/>
</paths>
8.3、setAllowFileAccessFromFileURLs
设置 是否允许运行在一个URL环境(the context of a file scheme URL)中的JavaScript访问来自其他URL环境的内容
比如:你 加载了一个http://www.xx.com/index.html ,index.html里的js 使用file://访问你设备里的文件。
不过,我在测试中,发现需要把这个 index.html先下载,然后loadUrl,index.html里的js 才能 使用file://访问你设备里的文件
当然,push 到 /data/local/tmp 里也可以加载。如:
webView.loadUrl("file:///data/local/tmp/index.html");
8.4、setAllowUniversalAccessFromFileURLs
设置 是否允许运行在一个file schema URL环境下的JavaScript访问来自其他任何来源的内容,包括其他file schema URLs。通过此API可以设置是否允许通过file url加载的Javascript可以访问其他的源,包括其他的文件和http,https等其他的源。
这个 和上一个功能类似。测试中发现 setAllowFileAccessFromFileURLs 或者setAllowUniversalAccessFromFileURLs 任意一个设置为true 都可以 实现3中的效果。
此处参考的是:https://blog.youkuaiyun.com/tabactivity/article/details/116603978
9、最后,检查其他SDK是否新版本
检查依赖的SDK中是否有新的版本,如下图依次找到1、2、3(此处打上勾)、4,完成设置。
到build.gradle里找到dependencies的地方,找到下面依赖第三方SDK的地方,发现有黄色部分的,鼠标悬停在上面会提示更新,点击切换最新版就好了。(此时我已全部更新完,没有实际演示了)
以上就是我的应用适配android 12的思路,很多的功能都没有用到,所以相对简单一些。