# Android6到Android 15重点适配 站点:答源(https://www.dandroid.cn/) 原文:https://www.dandroid.cn/archives/22742 Canonical:https://www.dandroid.cn/archives/22742 作者:技术信源组 发布日期:2024-10-21 最后更新:2026-11-06 18:51 分类:技术方案 内容类型:post 说明:本页是原文的纯文本镜像,供大模型与检索器完整读取;不含导航、广告、付费框。引用请以上方「原文」链接为准。 ## 正文 1、安卓6到安卓15适配主要内容:①②③④⑤⑥⑦⑧⑨ Android 6: 新增运行时权限,区分普通权限和危险权限,比如相机、电话、定位、存储。 Android 7: 要在应用间共享文件,您应发送一项 content:// URI,并授予 URI 临时访问权限。进行此授权的最简单方式是使用 FileProvider 类。 Android 8:作用域目录访问 ①、通知渠道id Android 8.0 引入了通知渠道,其允许您为要显示的每种通知类型创建用户可自定义的渠道。用户界面将通知渠道称之为通知类别。targeSdk升级到26之后,所有的通知的实现都需要提供通知渠道,如果不提供通知渠道的话,所有通知在8.0系统上面都不能正常展示。 需要有渠道id 、渠道name ②、后台执行限制 应用在后台运行,需要调用 Context.startForegroundService()启动服务。且应用必须在创建服务后的五秒内调用该服务的 startForeground() 函数。 ③、允许安装未知来源应用 8.0 的应用需要在 AndroidManifest.xml 中声明 REQUEST_INSTALL_PACKAGES 权限,否则将无法进行应用内升级。 ④、 取消隐式广播 移除掉了所有的隐式广播(即清单文件中注册的广播),所以请使用显示广播进行注册(即代码注册)。 ⑤、权限 之前对于隐私权限只要申请一个就会将其在的权限组全部通过,android 8.0以后申请单个只给单个; Android 9: ①、限制非 Activity 环境中启动 Activity 不能从非 Activity 环境中启动 Activity,除非您传递 Intent 标志 FLAG_ACTIVITY_NEW_TASK。 ②、HTTP接口请求限制 Android 9.0 限制了明文流量(即HTTP接口)的网络请求,非加密的流量请求都会被系统禁止,或者直接使用HTTPS接口。在 res 目录下新建xml文件夹,添加network_security_config.xml文件或者在Application属性中添加如下配置 android:usesCleartextTraffic="true" ③、对非 SDK 接口的限制 现已禁止访问特定的非 SDK 接口,无论是直接访问,还是通过 JNI 或反射进行间接访问。尝试访问受限制的接口时,会生成 NoSuchFieldException 和 NoSuchMethodException 之类的错误。 ④、限制后台对传感器的访问 App后台运行时,以下行为受限: 麦克风、摄像头、陀螺仪、加速度计等传感器。 ⑤、前台服务 Android 8.0 增加startForegroundService()来创建一个前台服务,在Android 9.0 调用该函数时,还需要额外添加FOREGROUND_SERVICE权限,这是普通权限,否则会发生 SecurityException 异常。 ⑥、 硬件序列号 在 Android 9 中,Build.SERIAL 始终设置为 “UNKNOWN” 以保护用户的隐私。 如果您的应用需要访问设备的硬件序列号,您应改为请求 READ_PHONE_STATE 权限,然后调用 getSerial()。 Android 10: ①、后台运行时访问设备位置信息需要权限 Android 10 引入了 ACCESS_BACKGROUND_LOCATION 权限(危险权限)。该权限允许应用程序在后台访问位置。如果请求此权限,则还必须请求ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION权限。只请求此权限无效果。 ②、限制了对剪贴板数据的访问权限 除非您的应用是默认输入法 (IME) 或是目前处于焦点的应用,否则它无法访问 Android 10 或更高版本平台上的剪贴板数据。 ③、分区存储 分区存储将外部存储分成两部分: (1)App-specific directory (沙盒目录) APP只能在Context.getExternalFilesDir()目录下通过File的方式创建文件,APP卸载的时候,这个目录下的文件会被删除;无法通过File的方式在其他路径创建文件。etExternalFilesDir (2)Public Directory 公共目录 公共目录包括:多媒体公共目录(Photos, Images, Videos, Audio)和下载文件目录(Downloads)。 APP可以通过MediaStore 或者 SAF(System Access Framework)的方式访问其中的文件。APP卸载后,文件不会被删除。 Android Q以上移除了WRITE_EXTERNAL_STORAGE权限,应用不需要这个权限就可以向沙盒内存储文件,也可以通过媒体数据库的方式保存媒体数据至特定位置。 requestLegacyExternalStorage的作用是允许应用访问外部存储的所有文件,而不需要遵循Android 10及以上版本对外部存储访问的限制。 App卸载后,对应的沙盒目录也会被删除,如果APP想要在卸载时保留沙盒目录下的数据,要在 AndroidManifest.xml 中声明 android:hasFragileUserData=“true”,这样在 APP卸载时就会有弹出框提示用户是否保留应用数据。 ④、标识符和数据 Build.getSerial() TelephonyManager.getImei() getDeviceId()、getMeid()、getSimSerialNumber()、getSubscriberId() 从 Android 10 开始,应用必须具有 READ_PRIVILEGED_PHONE_STATE 特许权限才能正常使用以上这些方法。 Android11: ①、强制执行分区存储 将应用更新为以 Android 11 为目标平台后,您将无法使用requestLegacyExternalStorage,而且也没有其他标记可以提供停用分区存储。所有文件访问权限 MANAGE_EXTERNAL_STORAGE,用来获取所有文件的管理权限。 ②、电话号码相关权限 如果应用以 Android 11 或更高版本为目标平台,并且需要访问以下列表中显示的电话号码 API,则必须请求 READ_PHONE_NUMBERS 权限,而不是 READ_PHONE_STATE 权限。 ③、前台位置信息访问权限 当有前台服务在运行时,系统会显示一条常驻通知来提醒用户注意。当应用被置于后台时(例如当用户按设备上的主屏幕按钮或关闭设备的显示屏时),其位置信息访问权限会得到保留。你必须声明此前台服务类型。 android:foregroundServiceType="location" ④、后台位置信息访问权限 在搭载 Android 11 的设备上,当应用中的某项功能请求在后台访问位置信息时,用户看到的系统对话框不再包含用于启用后台位置信息访问权限的按钮。如需启用后台位置信息访问权限,用户必须在设置页面上针对应用的位置权限设置一律允许选项。 ⑤、单次授权 从 Android 11.0(API 级别 30)开始,每当你的应用请求与位置、麦克风或相机相关的权限时,面向用户的权限对话框都会包含仅限这一次选项,如果用户在对话框中选择此选项,系统会向应用授予临时的单次授权。 Android 12: ①、定位权限:大概位置 在搭载 Android 12.0 或更高版本的设备上,用户可以要求你的应用只能访问大致位置信息。 如果你的应用请求 ACCESS_COARSE_LOCATION 但未请求 ACCESS_FINE_LOCATION,则此变更不会影响你的应用。 如果你的应用请求 ACCESS_FINE_LOCATION 运行时权限,你还应请求 ACCESS_COARSE_LOCATION 权限,以便处理用户授予应用大致位置访问权限的情形。你应该在单个运行时请求中包含这两项权限。 粗略位置: 精确到2平方公里的位置值,请求 ACCESS_COARSE_LOCATION 权限可以获得。 精确位置: 精确到50米以内的位置值,请求 ACCESS_FINE_LOCATION 权限可以获得。 ②、PendingIntent可变性 如果您的应用程序以Android 12为目标平台,您必须为应用创建的每个 PendingIntent 对象指定可变性。这项额外的要求可提高应用的安全性。因为三方app可以通过劫持PendingIntent,然后改写里面的action、category、data等,造成重定向攻击。 适配的具体就是在创建 PendingIntent时,使用 PendingIntent.FLAG_MUTABLE (可变的) 或 PendingIntent.FLAG_IMMUTABLE(不可变的) 标志。否则运行时会报 IllegalArgumentException。 ③、蓝牙权限 如果您的应用程序面向Android 12或更高版本,使用蓝牙功能时请在应用程序的清单文件中声明以下权限: BLUETOOTH_SCAN:允许蓝牙设备扫描。 BLUETOOTH_CONNECT:允许蓝牙设备连接。 BLUETOOTH_ADVERTISE:允许当前蓝牙设备可以被其他蓝牙设备发现。 ④、更安全的组件导出 以Android 12.0 为目标平台的App,如果其包含的四大组件中使用到了 intent 过滤器(intent-filter),则必须显示声明 android:exported 属性,否则App将无法在 Android 12.0 及更高系统版本的设备上安装。 Android 13: ①、细化的媒体权限 需要访问其他应用已经创建的媒体文件,必须请求以下一项或多项细化的媒体权限,而不是 READ_EXTERNAL_STORAGE 或者 WRITE_EXTERNAL_STORAGE 权限。 图片和照片:READ_MEDIA_IAMGES 视频:READ_MEDIA_VIDEO 音频:READ_MEDIA_AUDIO 如果用户之前向您的应用授予了 READ_EXTERNAL_STORAGE 权限,系统会自动向您的应用授予细化的媒体权限。否则,当应用请求上表中显示的任何权限时,系统会显示面向用户的对话框。 ②、通知运行时权限 Android13则引入了新的运行时通知权限:android.permission.POST_NOTIFICATIONS。 ③、广告 ID 需要权限 使用 Google Play 服务广告 ID 且以 Android 13(API 级别 33)及更高版本为目标平台的应用必须在其清单文件中声明常规 AD_ID权限。如果你的应用以 Android 13.0 或更高版本为目标平台且未声明此权限,系统会自动移除广告 ID 并将其替换为一串零。 ④、BroadcastReceiver变更 从Android 13开始,以Android13(API 33+)为目标平台的应用,注册静态广播时,需设置对其他应用的可见性: 若对其他应用可见,广播注册时设置:Context.RECEIVER_EXPORTED 若仅应用内使用,广播注册时设置:Context.RECEIVER_NOT_EXPORTED Android 14: ①、 应用只能终止自己的后台进程 从 Android 14 开始,当您的应用调用 killBackgroundProcesses() 时,该 API 只能终止您自己应用的后台进程。 ②、最低可安装的目标 API 级别 从 Android 14 开始,targetSdkVersion 低于 23 (Android 6.0)的应用无法安装。 ③、对隐式 intent 和待处理 intent 的限制 对于以 Android 14 为目标平台的应用,Android 会通过以下方式限制应用向内部应用组件发送隐式 intent: 隐式 intent 只能传送到android:exported="true"组件。应用必须使用显式 intent 传送到android:exported="false"的组件,或将该组件标记为android:exported="true"。 如果应用通过未指定组件或软件包的 intent 创建可变待处理 intent,系统现在会抛出异常。 ④、支持JDK17 Gradle版本最低需要升级至7.4.2,建议升级到8.0.1,如果Gradle升级到8.0以上,jdk需要升级至17以上 ⑤、 前台服务类型 targetSdkVersion 34 的情况下,必须为应用内的每个前台服务(foreground-services) 指定至少一种[前台服务] 前台服务类型是在 Android 10 引入的,通过 android:foregroundServiceType 可以指定 的服务类型,可供选择的前台服务类型有: camera、location、health、mediaplayback、phoncall Android 15:①②③④⑤⑥⑦⑧⑨ ①、 处理最低sdk适配 最低可安装TargetSDK级别为24!(Android 7.0) ②、 支持 16 KB 页面大小 Android 15 增加了对使用较大页面大小的设备的支持,除了标准 4 KB 页面之外,还支持 16 KB 页面,含有so库的应用需要重新构建支持 16KB 设备的应用,否则在16KB设备上很可能会crash。 ③、 私人空间 私人空间允许用户在其设备上创建一个单独的空间,在额外的身份验证层下,可以让敏感应用得到隔离。 私人空间使用单独的用户配置文件,当用户锁定私人空间时,配置文件将处于暂停,同时 App 耶不再活动,用户可以选择使用设备锁或单独的锁定来保护私人空间。 私人空间应用显示在启动器的单独容器中,并且在私人空间锁定时从最近的视图、通知、设置和其他应用中隐藏。 用户生成和下载的内容(媒体、文件)和帐户在私人空间和主空间之间分开,当私人空间解锁时,系统共享表和照片选择器可用于让应用访问跨空间的内容。 一、Android 14——34 适配[详细地址]https://juejin.cn/post/7231835495557890106 1、对隐式 intent 和待处理 intent 的限制 隐式 intent 只能传送到导出的组件。应用必须使用显式 intent 传送到未导出的组件 带包名的去跳转,或将该组件标记为已导出。如果应用通过未指定组件或软件包的 intent 创建可变待处理 intent,系统现在会抛出异常。 //false 不可导出 true可导出 Intent explicitIntent =new Intent("com.example.action.APP_ACTION") //跳转不可导出,需要设置包名 explicitIntent.setPackage(context.getPackageName()); context.startActivity(explicitIntent); 2、在运行时注册的广播接收器必须指定导出行为 在 Android 14 上,运行时通过 Context#registerReceiver() 动态注册广播接收器,需要设置标记 RECEIVER_EXPORTED 或 RECEIVER_NOT_EXPORTED ,标识是否导出该广播,避免应用程序出现安全漏洞,如果注册的是系统广播,则不需要指定标记。 三方SDK兼容修改方式: 如果三方SDK适配困难可以先在Activity或者Application中复写广播注册方法,如果有未添加是否可导出标记可以手动添加上 @Override public Intent registerReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter) { return registerReceiver(receiver, filter, Context.RECEIVER_EXPORTED或者Context.RECEIVER_NOT_EXPORTED); } @Override public Intent registerReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter, int flags) { Intent intent=null; try { boolean flagExported = (flags & Context.RECEIVER_EXPORTED) != 0; boolean flagNotExported = (flags & Context.RECEIVER_NOT_EXPORTED) != 0; if(!flagExported && !flagNotExported){ intent = super.registerReceiver(receiver, filter, flags|Context.RECEIVER_EXPORTED或者Context.RECEIVER_NOT_EXPORTED); return intent; } intent = super.registerReceiver(receiver, filter,flag); } catch (Throwable e) { } return intent; } 3、启动前台服务必须设置前台服务类型 如果有使用[startForeground()] 在清单文件中必须要指定服务的前台类型,例如音频播放类的可以使用mediaPlayback 为了帮助开发者更有目的地定义面向用户的[前台服务]Android 10 在 []元素内引入了 android:foregroundServiceType 属性。 二、Android 13——33 适配[详细地址]https://blog.csdn.net/as425017946/article/details/127530660 1、细分媒体权限 图片、视频、音频 从Android 13开始,以Android13(API 33+)为目标平台的应用,系统新增运行时权限READ_MEDIA_IAMGES、READ_MEDIA_VIDEO、READ_MEDIA_AUDIO 替代原有的READ_EXTERNAL_STORAGE权限。 2、静态广播注册 从Android 13开始,以Android13(API 33+)为目标平台的应用,注册静态广播时,需设置对其他应用的可见性: 若对其他应用可见,广播注册时设置:Context.RECEIVER_EXPORTED 若仅应用内使用,广播注册时设置:Context.RECEIVER_NOT_EXPORTED private void registerTestReceiver() { IntentFilter filter = new IntentFilter(); filter.addAction("com.xiaxl.test.action"); // api >= 33 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { // 跨应用间使用 MainActivity.this.registerReceiver(mTestReceiver, filter, Context.RECEIVER_EXPORTED); // 应用内使用 //MainActivity.this.registerReceiver(mTestReceiver, filter, Context.RECEIVER_EXPORTED); } // api <= 32 else { MainActivity.this.registerReceiver(mTestReceiver, filter); } } 3、剪切板内容隐藏 从Android 13(API 33)开始,Android剪切板新增了一项新API: Android 13(API 33)开始,用户可以选择使用API PersistableBundle#(ClipDescription.EXTRA_IS_SENSITIVE, true)隐藏要复制到剪切板的用户账户、密码登敏感信息。 private void addData2Clipboard() { ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); ClipData clipData = ClipData.newPlainText("111111", "我是密码"); ClipDescription description = clipData.getDescription(); // 隐私内容:剪切板加密 PersistableBundle persistableBundle = new PersistableBundle(); if (Build.VERSION.SDK_INT >= 33) { persistableBundle.putBoolean(ClipDescription.EXTRA_IS_SENSITIVE, true); } else { persistableBundle.putBoolean("android.content.extra.IS_SENSITIVE", true); } description.setExtras(persistableBundle); // 剪切板添加加密内容 clipboardManager.setPrimaryClip(clipData); } 三、Android 12——31 适配[详细地址]https://www.jianshu.com/p/60e061165667 四、Android 11——30 适配[详细地址]https://blog.csdn.net/JasonXu94/article/details/129290096 五、Android 10——29 适配[详细地址]https://blog.csdn.net/qq_33979657/article/details/106919681 --- 由 答源 DAN 底座 1.4.1 生成 · 2026-11-11T03:45:03+00:00