news 2026/6/23 16:54:55

Android12 新特性与适配指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Android12 新特性与适配指南

Android 12(API 31)引入了多项重要特性和行为变更,本文从开发视角梳理核心适配点,结合 Kotlin 代码示例说明具体实现方式。

一、核心适配前提

  1. 升级开发环境:
    • Gradle 插件 ≥ 7.0.0
    • compileSdkVersion ≥ 31
    • targetSdkVersion 建议升级到 31(若暂不升级,部分特性仍需适配)
  2. 依赖库升级:确保 AppCompat、Material 等库版本 ≥ 1.4.0

二、关键特性适配

1. 前台服务(Foreground Service)限制

Android 12 收紧了前台服务权限,仅允许特定场景使用,且新增POST_NOTIFICATIONS权限。

适配要点:
  • 声明前台服务类型(必须在 Manifest 中指定)
  • 动态申请通知权限(Android 13+ 强制,12 建议提前适配)
  • 非允许场景使用 WorkManager 替代
代码示例:

1. Manifest 配置

<!-- 声明前台服务类型 --><serviceandroid:name=".MyForegroundService"android:foregroundServiceType="location|mediaPlayback|phoneCall"/><!-- 声明通知权限 --><uses-permissionandroid:name="android.permission.POST_NOTIFICATIONS"/>

2. 动态申请通知权限(Kotlin)

// 检查并申请通知权限privatefunrequestNotificationPermission(){if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.TIRAMISU){if(ContextCompat.checkSelfPermission(this,Manifest.permission.POST_NOTIFICATIONS)!=PackageManager.PERMISSION_GRANTED){ActivityResultContracts.RequestPermission()registerForActivityResult(ActivityResultContracts.RequestPermission()){isGranted->if(isGranted){// 权限已授予,启动前台服务startForegroundService()}else{// 引导用户手动开启权限showPermissionDialog()}}.launch(Manifest.permission.POST_NOTIFICATIONS)}else{startForegroundService()}}else{// Android 12 及以下直接启动startForegroundService()}}// 启动前台服务privatefunstartForegroundService(){valserviceIntent=Intent(this,MyForegroundService::class.java)if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){startForegroundService(serviceIntent)}else{startService(serviceIntent)}}

3. 前台服务实现(Kotlin)

classMyForegroundService:Service(){privatevalNOTIFICATION_ID=1001privatevalCHANNEL_ID="FOREGROUND_CHANNEL"overridefunonStartCommand(intent:Intent?,flags:Int,startId:Int):Int{createNotificationChannel()valnotification=NotificationCompat.Builder(this,CHANNEL_ID).setContentTitle("前台服务").setContentText("服务运行中").setSmallIcon(R.mipmap.ic_launcher).build()// Android 12 必须指定服务类型if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.S){startForeground(NOTIFICATION_ID,notification,ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION// 匹配Manifest声明的类型)}else{startForeground(NOTIFICATION_ID,notification)}// 业务逻辑...returnSTART_STICKY}privatefuncreateNotificationChannel(){if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){valchannel=NotificationChannel(CHANNEL_ID,"前台服务通道",NotificationManager.IMPORTANCE_LOW)valmanager=getSystemService(NotificationManager::class.java)manager.createNotificationChannel(channel)}}overridefunonBind(intent:Intent?):IBinder?=null}

2. 精确闹钟权限(SCHEDULE_EXACT_ALARM)

Android 12 要求使用精确闹钟(setExact()/setExactAndAllowWhileIdle())必须申请SCHEDULE_EXACT_ALARM权限。

适配要点:
  • Manifest 声明权限
  • 运行时检查并申请权限
  • 处理权限被拒绝的场景
代码示例:

1. Manifest 配置

<uses-permissionandroid:name="android.permission.SCHEDULE_EXACT_ALARM"/><uses-permissionandroid:name="android.permission.USE_EXACT_ALARM"/><!-- 备用权限 -->

2. 检查并申请精确闹钟权限(Kotlin)

privatefuncheckExactAlarmPermission(){valalarmManager=getSystemService(AlarmManager::class.java)if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.S){// 检查权限是否开启if(!alarmManager.canScheduleExactAlarms()){// 跳转到应用权限设置页面valintent=Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM,Uri.parse("package:$packageName"))startActivityForResult(intent,REQUEST_EXACT_ALARM)}else{// 权限已开启,设置精确闹钟setExactAlarm()}}else{setExactAlarm()}}// 设置精确闹钟privatefunsetExactAlarm(){valalarmManager=getSystemService(AlarmManager::class.java)valintent=Intent(this,AlarmReceiver::class.java)valpendingIntent=PendingIntent.getBroadcast(this,0,intent,PendingIntent.FLAG_UPDATE_CURRENTorPendingIntent.FLAG_IMMUTABLE// Android 12 要求 FLAG_IMMUTABLE)valtriggerTime=System.currentTimeMillis()+60*1000// 1分钟后if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,triggerTime,pendingIntent)}else{alarmManager.setExact(AlarmManager.RTC_WAKEUP,triggerTime,pendingIntent)}}

3. PendingIntent 行为变更

Android 12 要求创建PendingIntent时必须指定FLAG_IMMUTABLEFLAG_MUTABLE,否则会抛出异常。

适配要点:
  • 所有 PendingIntent 创建时添加FLAG_IMMUTABLE(默认推荐)
  • 仅当需要修改 PendingIntent 内容时使用FLAG_MUTABLE
代码示例:
// 正确写法(Android 12+)valpendingIntent=PendingIntent.getActivity(this,0,intent,// 组合 FLAG_UPDATE_CURRENT 和 FLAG_IMMUTABLEPendingIntent.FLAG_UPDATE_CURRENTorPendingIntent.FLAG_IMMUTABLE)// 若需要修改 PendingIntent 内容(慎用)valmutablePendingIntent=PendingIntent.getBroadcast(this,1,intent,PendingIntent.FLAG_UPDATE_CURRENTorPendingIntent.FLAG_MUTABLE)

4. 应用启动画面(Splash Screen)

Android 12 引入了标准化的启动画面 API,替代传统的 SplashActivity 方案。

适配要点:
  • 使用 SplashScreen 库适配
  • 配置启动画面样式
  • 控制启动画面消失时机
代码示例:

1. 依赖引入(build.gradle)

dependencies { implementation "androidx.core:core-splashscreen:1.0.1" }

2. 样式配置(res/values/styles.xml)

<stylename="Theme.App.SplashScreen"parent="Theme.SplashScreen"><!-- 启动画面背景色 --> <item name="windowSplashScreenBackground">@color/white</item> <!-- 应用图标 --> <item name="windowSplashScreenAnimatedIcon">@mipmap/ic_launcher</item> <!-- 图标动画时长(可选) --> <item name="windowSplashScreenAnimationDuration">1000</item> <!-- 启动画面结束后跳转的主题 --> <item name="postSplashScreenTheme">@style/Theme.App</item></style>

3. Manifest 配置

<activityandroid:name=".MainActivity"android:theme="@style/Theme.App.SplashScreen"><intent-filter><actionandroid:name="android.intent.action.MAIN"/><categoryandroid:name="android.intent.category.LAUNCHER"/></intent-filter></activity>

4. 代码控制(MainActivity.kt)

classMainActivity:AppCompatActivity(){overridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)// 安装启动画面installSplashScreen()// 模拟初始化耗时操作CoroutineScope(Dispatchers.Main).launch{delay(2000)// 2秒后消失setContentView(R.layout.activity_main)}}}

5. 触摸反馈和滚动行为优化

Android 12 增强了触摸反馈和滚动效果,可通过 Material Design 3 适配。

适配要点:
  • 升级到 Material Design 3
  • 配置触摸反馈样式
代码示例:

1. 依赖引入

implementation "com.google.android.material:material:1.8.0"

2. 样式配置(res/values/styles.xml)

<stylename="Theme.App"parent="Theme.Material3.DayNight.NoActionBar"><!-- 触摸反馈颜色 --> <item name="android:colorControlHighlight">@color/touch_feedback</item> <!-- 滚动条样式 --> <item name="android:scrollbarStyle">insideOverlay</item></style>

三、其他重要适配点

特性适配要点
应用兼容性禁用android:hardwareAccelerated="false"(部分设备会导致崩溃)
剪贴板访问访问剪贴板时会弹出系统提示,避免后台频繁访问
网络权限NETWORK_WIFI等权限需配合ACCESS_NETWORK_STATE使用
后台启动限制进一步收紧后台启动 Activity,优先使用通知引导用户手动打开

四、测试建议

  1. 使用 Android 12 真机或模拟器测试
  2. 重点测试权限申请流程、前台服务、闹钟功能
  3. 检查第三方库是否适配 Android 12(如推送、统计SDK)
  4. 使用 Lint 工具检测适配问题:./gradlew lint

五、总结

Android 12 的适配核心围绕权限收紧PendingIntent 标记前台服务限制新 API 适配展开。建议分阶段适配:

  1. 优先修复崩溃类问题(如 PendingIntent 缺少标记)
  2. 适配核心功能权限(前台服务、精确闹钟)
  3. 接入新特性(启动画面、Material Design 3)
  4. 全面测试并优化用户体验

六、参考资源

  • 安卓12官方文档
  • 安卓12行为变更

通过以上适配,可确保应用在 Android 12 设备上稳定运行,并充分利用新特性提升用户体验。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/22 23:42:31

高端成果与需求端断层如何破局?区域科技创新体系可借助知识产权智能运营平台实现闭环的体系化竞争壁垒。

观点作者&#xff1a;科易网AI技术转移研究院在科技创新日益成为国家核心竞争力的今天&#xff0c;高校院所作为科技成果的重要源头&#xff0c;其成果转化效率直接影响着创新链与产业链的深度融合。然而&#xff0c;长期以来&#xff0c;“高端成果与需求端断层”问题一直是制…

作者头像 李华
网站建设 2026/6/23 23:33:52

技术转移机构如何借助生成式AI赋能工具重塑差异化服务优势?

观点作者&#xff1a;科易网AI技术转移研究院在当前科技成果转化领域&#xff0c;高校已成为创新成果的重要源头&#xff0c;但“不能转”“不敢转”“不会转”等问题依然制约着转化效率。为破除这些障碍&#xff0c;高校积极探索有组织科技成果转化路径&#xff0c;通过政策环…

作者头像 李华
网站建设 2026/6/23 15:54:15

57、SQL 网络与分布式数据库全解析

SQL 网络与分布式数据库全解析 1. 分布式数据库面临的挑战 在构建和管理分布式数据库时,会遇到一系列棘手的问题,这些问题涉及到数据兼容性、系统目录、混合供应商环境、分布式死锁以及恢复等多个方面。 - 数据兼容性 :不同的计算机系统支持不同的数据类型,即便提供相…

作者头像 李华
网站建设 2026/6/23 15:55:07

MeshLabelImageColor 读取医学标签图像数据(MetaImage 格式)

一&#xff1a;主要的知识点 1、说明 本文只是教程内容的一小段&#xff0c;因博客字数限制&#xff0c;故进行拆分。主教程链接&#xff1a;vtk教程——逐行解析官网所有Python示例-CSDN博客 2、知识点纪要 本段代码主要涉及的有①vtkColorTransferFunction颜色映射&#…

作者头像 李华
网站建设 2026/6/23 17:56:26

61、SQL 中的抽象数据类型与继承机制

SQL 中的抽象数据类型与继承机制 1. 操作 LOB 数据 在处理包含文档文本的大对象(LOB)数据时,我们可能需要检索包含 LOB 的行,并更新 LOB 数据中间的部分内容。以下是一个示例代码,展示了如何实现这一操作: declare lob CLOB; textbuf varchar(255); begin /* Put…

作者头像 李华
网站建设 2026/6/23 19:36:23

69、SQL 的现状与未来:专业数据库与市场趋势洞察

SQL 的现状与未来:专业数据库与市场趋势洞察 1. 事件处理与数据库连接 在当今的数据处理领域,企业数据库管理系统(DBMS)起着关键作用。企业 DBMS 链接能够让事件处理引擎将来自数据馈送的数据与从传统企业数据库中检索的数据进行合并。目前,所有主流产品都支持通过 JDBC…

作者头像 李华