Android升级targetSdk到31

365 阅读2分钟
android {
    ...
    defaultConfig {
        targetSdkVersion = 31
    }
    ...
}

1 外置存储、分区存储与限制【29,30】


保障旧版本升级缓存数据AndroidManifest.xml

requestLegacyExternalStorage=true 

preserveLegacyExternalStorage=true

支持访问

  • /sdcard/DCIM、Pictures、Alarms, Music, Notifications,Podcasts, Ringtones、Movies、Download

  • /sdcard/Android/data/{packagename}

  • /data/data/{packagename}

  • /sdcard/Android/media/{packagename}

2 蓝牙权限及不同策略【29,30,31】


蓝牙扫描API(扫描和发现附近蓝牙设备)

BluetoothAdapter

BluetoothAdapter.LeScanCallback

BluetoothLeScanner

蓝牙连接API(蓝牙配对)

BluetoothAdapter

蓝牙广播API(附近蓝牙发现)

BluetoothLeAdvertiser

连接API

android.permission.BLUETOOTH  添加 android:maxSdkVersion="30"

android.permission.BLUETOOT_ADMIN  添加 android:maxSdkVersion="30"

扫描API

android.permission.ACCESS_COARSE_LOCATION 除非使用定位否则不声明

android.permission.ACCESS_FINE_LOCATION  除非使用定位否则不声明

如果android.os.Build.VERSION.SDK_INT >= 31 一次性申请下面三个

android.permission.BLUETOOTH_SCAN   扫描API  android:usesPermissionFlags="neverForLocation" 不基于蓝牙定位

android.permission.BLUETOOTH_CONNECT 连接API

android.permission.BLUETOOTH_ADVERTISE   蓝牙广播API

3 大致位置【31】


android.permission.ACCESS_FINE_LOCATION 涉及Wi-Fi感知和蓝牙扫描

4 在后台访问位置信息的权限【29,30】


android.permission.ACCESS_BACKGROUND_LOCATION 单独申请,建议引导用户到应用详情中设置

5 精准的闹钟权限【31】

android.permission.SCHEDULE_EXACT_ALARM

6 一些电话 API、蓝牙 API 和 WLAN API 需要精确位置权限【29】


使用Wi-Fi定位声明android.permission.ACCESS_FINE_LOCATION

TelephonyManager

TelephonyScanManager

TelephonyScanManager.NetworkScanCallback

PhoneStateListener

WifiManager

WifiAwareManager

WifiP2pManager

WifiRttManager

7 软件包可见性【30】


删除 android.permission.QUERY_ALL_PACKAGES

删除 com.android.permission.GET_INSTALLED_APPS

AndroidManifest.xml 添加

<queries>

    <package android:name="com.tencent.tim" />

    <package android:name="com.tencent.qq" />

</queries>

<queries>

    <intent>

        <action android:name="android.intent.action.SEND" />

        <data android:mimeType="image/*" />

    </intent>

</queries>

检查API

  • queryIntentActivities

  • getPackageInfo

  • getInstalledApplications

  • getInstalledPackages

可访问activity名单

  • 您自己的应用,即自身应用

  • 实现 Android 核心功能的某些系统软件包,如媒体提供程序。

  • 通过 startActivityForResult(注意 startActivity 无效)打开自身应用时的应用(仅当次有效)

  • 安装了您应用的应用(如当时安装自身应用时的应用市场)

  • 通过 bindService/startService/Provider 打开自身应用时的应用(仅当次有效)

  • 自己在 Manifest 中声明的包名/签名/IntentFilter/ProviderAuthorities 清单(见“建议”)

8 更安全的组件导出【31】


AndroidManifest.xml中

activity、activity-alias、service、provider、receiver 添加 android:exported="false"  

需要注意 intent-filter 和 SDK 中的声明

9 前台服务启动限制【31】


createScreenCaptureIntent

Context#startForegroundService

Service#startForeground 


10 前台服务访问摄像头、麦克风需声明【30】


https://developer.android.google.cn/guide/components/fg-service-types?hl=zh-cn

android.permission.FOREGROUND_SERVICE

android.permission.FOREGROUND_SERVICE_CAMERA

android.permission.FOREGROUND_SERVICE_LOCATION

android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION

service补充android:foregroundServiceType="xxx" 可多种类型组合

mediaPlayback 后台继续播放音频或视频

camera 视频聊天

location 导航和位置共享

mediaProjection 媒体投影、录屏

替换为 ServiceCompat#startForeground 

同时需要通知权限  android.permission.POST_NOTIFICATIONS 前台服务结束时调用stopForeground

11 待处理 intent 可变性【31】

PendingIntent添加FLAG_IMMUTABLE或者FLAG_MUTABLE

12 更新后的非 SDK 限制【29,30,31】


https://developer.android.com/guide/app-compatibility/restrictions-non-sdk-interfaces?hl=zh-cn#list-names

非 SDK 接口获取方法method或字段field

使用反射或 JNI 来获取其句柄

13 监听ApplicationExitInfo

**

https://developer.android.google.cn/reference/android/app/ApplicationExitInfo#REASON_USER_REQUESTED

**