Android 13适配
Posted 凌云志 !
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 13适配相关的知识,希望对你有一定的参考价值。
目录
1.读写SD卡权限的调整
一. 创建安卓13模拟器或使用安卓13系统真机调试.
1.下载 android 13 SDK:
- 依次点击 Tools > SDK Manager。
- 在“SDK Platforms”标签页中,选择 Android 13 (Android API 33)。
- 在 SDK Tools 标签页中,选择 Android SDK Build-Tools 33。
点击OK安装 SDK。
2. 设置模拟器
- 依次点击 Tools > AVD Manager > "+ Create Virtual Device".
- 选择"Phone" > "Next" > 选择 API Level 33 创建模拟器即可.
二.功能变化概览及适配方案
1.读写SD卡权限的调整
Android13之前,读取SD卡只需要申请一个权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
但Android13之后,这个权限被细化成了三个,这三个权限需要分别单独去申请。
Manifest.permission.READ_MEDIA_IMAGES
Manifest.permission.READ_MEDIA_VIDEO
Manifest.permission.READ_MEDIA_AUDIO
适配方案:
如果是升级Android13之前就已经具有读写SDK的权限,那么升级到13之后,自动就会有上述三个权限。
如果是升级Android13之后新装的应用,且targetSDK小于33,申请READ_EXTERNAL_STORAGE权限时,会自动转化为对上述三个权限的申请,申请框只一个.
如果是升级Android13之后新装的应用,且targetSDK大于等于33,则申请READ_EXTERNAL_STORAGE权限时会自动拒绝(同理WRITE_EXTERNAL_STORAGE也是一样)。必须申请上面三个权限才可以。下午就是安卓13新安装APP,直接申请读写权限被拒绝.
安卓13动态权限兼容处理,打开相册不需要权限,但选择相片之后的操作需要自行测试是否正常.
1.在AndroidManifest.xml文件中添加权限,根据自己需要添加.
<!--安卓13之后读取图片权限-->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<!--安卓13之后读取视频权限-->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<!--安卓13之后读取音频权限-->
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
2.发起动态权限申请,根据自身需要添加.
String[] list = new String[10];
if (Build.VERSION.SDK_INT >=33)
list[0] = "android.permission.READ_MEDIA_IMAGES"; //图片
list[1] = "android.permission.READ_MEDIA_VIDEO"; //视频
list[2] = "android.permission.READ_MEDIA_AUDIO"; //音频
else
list[0] = Manifest.permission.READ_EXTERNAL_STORAGE;
ActivityCompat.requestPermissions(MainActivity.this, list, 000);
下面是只申请图片权限的效果:
3.打开相册方法兼容
public static void openPhotoAlbum(Activity activity)
Intent intent;
if (Build.VERSION.SDK_INT >= 33)
//安卓13以上打开相册.
intent = new Intent("android.provider.action.PICK_IMAGES");
intent.setType("images/*");//设置只显示图片
/**
* 设置选择照片的个数,默认1张时可不添加该属性,大于1的时候再设置.
* 可指定图片数量上限为最大数字,调用 MediaStore.getPickImagesMaxLimit().
*/
//intent.putExtra("android.provider.extra.PICK_IMAGES_MAX", MediaStore.getPickImagesMaxLimit());
else
intent = new Intent(Intent.ACTION_PICK);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
activity.startActivityForResult(intent, 888);
2.撤销权限
对不需要使用的权限进行撤销.
现在这张图片是申请了所有读取权限的.
1.在AndroidManifest.xml中删除准备撤销的视频和音频权限. 2.在代码中把需要撤销的权限保存到List集合,然后调用API接口即可.
if (Build.VERSION.SDK_INT >= 33)
ArrayList<String> permissions = new ArrayList<>();
permissions.add("android.permission.READ_MEDIA_VIDEO");
permissions.add("android.permission.READ_MEDIA_AUDIO");
revokeSelfPermissionsOnKill(permissions);
3.撤销完权限之后再看app的权限,如下图已删除视频和音频权限.
3.通知权限的调整
Android13中,notifcation权限改成危险权限,需要动态申请。
简单来说,就是把权限级别升级了,申请方式不变,流程也不变,但是需要申请新的权限,老的已申请的通知权限在13版本上无法使用,即使 targetSDK < 33 也不行。
总结下来,分为三种场景:
1.应用在系统升级到13之前已经有通知权限,则自动授予新的通知权 POST_NOTIFICATIONS。
2.应用在13上新装,targetSDK<33,则申请该权限时只会弹一次,如果拒绝则此应用失去申请该权限的权利。
3.应用在13上新装,targetSDK>=33,每次申请该权限时都会弹。如果用户拒绝,下一次还可以继续申请。
适配方案:
首先,targetSdkVersion改为33。
其次,manifest中声明相关权限
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
最后代码中判断版本进行相关申请,如下:
private void checkAndSendNotification()
if (Build.VERSION.SDK_INT >= 33)
//检查是否有通知权限
NotificationManager manager = getSystemService(NotificationManager.class);
boolean enabled = manager.areNotificationsEnabled();
if (!enabled)
String[] strings = "android.permission.POST_NOTIFICATIONS";
requestPermissions(strings, 002);
return;
sendNotification();
return;
else
//继续执行老版本逻辑
sendNotification();
private void sendNotification()
4.后台运行限制
安卓13之前,应用的service是可以后台正常执行的。在13之后,某些情况下(比如低电量),会限制service的一些后台行为,比如限制网络的访问等等。用户进行前台互动操作后,则APP可以从受限分区移除。
主要分为三个级别,代码和描述如下:
private void handleAction()
UsageStatsManager systemService = getSystemService(UsageStatsManager.class);
int appStandbyBucket = systemService.getAppStandbyBucket();
//1.没有任何限制
if (appStandbyBucket <= UsageStatsManager.STANDBY_BUCKET_ACTIVE)
return;
//2.应用最近几个小时内使用过,受到一定限制,限制程度较低。此时定时任务会被禁止执行
if (appStandbyBucket <= UsageStatsManager.STANDBY_BUCKET_WORKING_SET)
return;
//3.和上面一样,只不过是几天内使用过。
if (appStandbyBucket <= UsageStatsManager.STANDBY_BUCKET_FREQUENT)
return;
//4.限制访问网络
三.新功能使用及使用样例
1.可降级权限
之前权限只有申请,没有降级。这次,新增了权限降级功能,开发者如果之前申请了某个权限,但是后续版本不需要了,可以主动调用API进行相关的降级处理。
//activity or fragment
List<String> checkPermission = new ArrayList<>();
checkPermission.add(Manifest.permission.READ_MEDIA_AUDIO);
checkPermission.add(Manifest.permission.READ_MEDIA_IMAGES);
checkPermission.add(Manifest.permission.READ_MEDIA_VIDEO);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
this.revokeSelfPermissionsOnKill(checkPermission);
2.无需申请权限的相册选择器
我们通过新的API,可以直接访问相册,而无需申请任何权限,并且支持多选功能。
选择单张:
Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES);
startActivityForResult(intent, PHOTO_PICKER_REQUEST_CODE);
选择多张:
final int maxNumPhotosAndVideos = 10;
Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES);
intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, maxNumPhotosAndVideos);
startActivityForResult(intent, PHOTO_PICKER_MULTI_SELECT_REQUEST_CODE);
还可以通过type区分视频还是图片,这样以后就不用自己去搞
intent.setType("video/*");
其实和原来的使用方式差别不大,但是多了一个选择数量的功能,以及不需要申请权限。
3.APP单独设置语言偏好
13之前,APP的语言设置都是跟随系统的,系统如果设置的是默认应用,那么APP也会自动的切换成英语模式。13开始,支持应用单独设置优先语言,不需要跟着系统语言设定走了。
首先,创建支持语言配置文件:
然后,在AndroidManifest.xml中进行使用配置。
要注意的时,locales_config.xml配置中文的话,是zh,而不是zh-rCH。具体大陆/香港/台湾省语言,是没办法选择的。
4.带主题的应用图标
其实就是让桌面快捷图标支持白天黑夜模式,但是实际上这个功能有可能不是我们本来设想的那样。这个功能是让某一张单色应用图标支持白天/黑夜模式的切换,而不是支持两张不同的图片分别在白天黑夜模式下进行显示,所以实际效果并没有那么的理想。
首先,我们需要创建一张VectorDrawable类型的资源图片,battery.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<group
android:name="rotationGroup"
android:pivotX="10.0"
android:pivotY="10.0"
android:rotation="15.0">
<path
android:name="vect"
android:fillAlpha=".3"
android:fillColor="#FF000000"
android:pathData="M15.67,4H14V2h-4v2H8.33C7.6,4 7,4.6 7,5.33V9h4.93L13,7v2h4V5.33C17,4.6 16.4,4 15.67,4z" />
<path
android:name="draw"
android:fillColor="#FF000000"
android:pathData="M13,12.5h2L11,20v-5.5H9L11.93,9H7v11.67C7,21.4 7.6,22 8.33,22h7.33c0.74,0 1.34,-0.6 1.34,-1.33V9h-4v3.5z" />
</group>
</vector>
然后配置主题图标:launcher.xml
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/icon_background" />
<foreground android:drawable="@drawable/icon_light" />
<monochrome android:drawable="@drawable/battery" />
</adaptive-icon>
其中monochrome就是那张主题图标,最终变化的也是这一张图片。
最后AndroidManifest.xml中进行配置:
最终效果图如下:
白天模式/黑夜模式:
原本图标效果:
需要注意的是,必须在设置中打开才可以使用该功能:
3.附近WI-FI设备的新运行时权限
介绍:
扫描附近WI-FI设备时,之前需要申请的权限时ACCESS_FINE_LOCATION定位权限,这其实是不合适的。Android13修正了这个问题,新添加NEARBY_WIFI_DEVICES权限来解决这问题。
这项新权限会影响几个不同的 Wi-Fi 用例,包括以下用例:
查找或连接到附近的设备,如打印机或媒体投射设备。通过该工作流,您的应用可以完成以下类型的任务:
通过带外方式(例如通过 BLE)接收 AP 信息。
使用仅限本地使用的热点,通过 Wi-Fi 感知和连接功能发现并连接到设备。
通过 Wi-Fi 直连发现和连接到设备。
发起与已知 SSID(例如汽车或智能家居设备)的连接。
开启仅限本地使用的热点。
连接到附近的 Wi-Fi 感知设备。
使用案例:
manifest中进行申明:
<manifest ...>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
android:maxSdkVersion="32" />
<application ...>
...
</application>
</manifest>
代码中进行版本判断:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
checkPermission.add(Manifest.permission.NEARBY_WIFI_DEVICES);
else
checkPermission.add(Manifest.permission.ACCESS_FINE_LOCATION);
Android 12.0 适配——应用启动动画
参考技术A 应用启动时如果在Application中做了很多事务,会导致启动时有个白屏的时间,体验十分不好。通常的做法是给Application或者第一个启动的Activity的主题添加上android:windowBackground属性来优化体验。到了Android 12,官方新增了SplashScreen Api,可为所有应用添加新的启动动画,显示速度十分实时,所以到了Android 12,我们就不必自己添加android:windowBackground属性,最重要的是它是能向下兼容的。
在Android 12上已经默认使用了SplashScreen,如果不考虑向下兼容的问题,不需要任何配置,系统就会自动使用App的图标作为SplashScreen的图标。
这个时候就需要一些适配操作
注意的是必须是在第一个启动的Activity同目录的build.gradle中添加依赖
在Style.xml新建一个主题,parent必须为Theme.SplashScreen
windowSplashScreenBackground:启动动画的背景
windowSplashScreenAnimatedIcon:启动动画的图标
windowSplashScreenAnimationDuration:启动动画的时间
postSplashScreenTheme:启动动画退出后的启动页的主题
在setContentView()之前添加上installSplashScreen()即可
这里我用的是一台11的机器,可以看到效果基本上和12.0差不多,如果不去适配的话11的机器是看不到这个页面的(请忽略我自己做的图标)
可以看到适配很简单,另外可以看到installSplashScreen()是有返回值的,我们可以利用这个值去做一些更强大的事情,例如延长启动页面停留时间、设置动画效果等,这些大家自己去研究。
以上是关于Android 13适配的主要内容,如果未能解决你的问题,请参考以下文章
android gridview 怎么在适配器中设置不可选择项