Android14 新特性与适配指南

Android 14(API 34)带来了多项行为变更和新特性。

一、核心适配前提

  1. 升级开发环境:
    • Gradle Plugin ≥ 8.0
    • Compile SDK ≥ 34
    • Target SDK ≥ 34(建议,若暂不升级需兼容行为变更)
  2. 依赖库升级:确保 AppCompat、Material、Jetpack 等库至最新版本,避免兼容性问题。

二、关键行为变更适配

1. 权限适配

(1)前台服务类型(Foreground Service Type)强制校验

Android 14 要求所有前台服务必须声明具体的 foregroundServiceType,且仅能使用声明的类型,否则会抛出 SecurityException

适配步骤

  • 步骤1:Manifest 声明前台服务类型
xml 复制代码
<service
    android:name=".MyForegroundService"
    android:foregroundServiceType="location|mediaPlayback"> <!-- 根据业务选择类型 -->
    <intent-filter>
        <action android:name="android.intent.action.FOREGROUND_SERVICE" />
    </intent-filter>
</service>
  • 步骤2:Kotlin 代码中指定类型启动前台服务
kotlin 复制代码
class MyForegroundService : Service() {
    private val NOTIFICATION_ID = 1001
    private val CHANNEL_ID = "foreground_service_channel"

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        createNotificationChannel()
        // 构建前台服务通知
        val notification = NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("前台服务标题")
            .setContentText("前台服务内容")
            .setSmallIcon(R.mipmap.ic_launcher)
            .build()
        
        // Android 14+ 必须指定前台服务类型
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
            startForeground(
                NOTIFICATION_ID,
                notification,
                ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION // 与Manifest声明一致
            )
        } else {
            startForeground(NOTIFICATION_ID, notification)
        }
        return START_STICKY
    }

    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                CHANNEL_ID,
                "前台服务通道",
                NotificationManager.IMPORTANCE_DEFAULT
            )
            val notificationManager = getSystemService(NotificationManager::class.java)
            notificationManager.createNotificationChannel(channel)
        }
    }

    override fun onBind(intent: Intent?): IBinder? = null
}
(2)新增权限:POST_NOTIFICATIONS 强制校验

Android 13 引入的通知权限,Android 14 强化了校验,未授权时无法发送通知(包括前台服务通知)。

适配代码

kotlin 复制代码
// 检查并请求通知权限
private fun requestNotificationPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        val notificationManager = getSystemService(NotificationManager::class.java)
        if (!notificationManager.areNotificationsEnabled()) {
            val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply {
                putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
            }
            startActivity(intent)
            // 或通过权限请求弹窗(Android 13+)
            /*
            ActivityResultContracts.RequestPermission().launch(Manifest.permission.POST_NOTIFICATIONS) { granted ->
                if (granted) {
                    // 权限已授予,启动前台服务
                } else {
                    // 引导用户手动开启
                }
            }
            */
        }
    }
}

2. 应用内安装权限适配

Android 14 要求安装 APK 时必须申请 REQUEST_INSTALL_PACKAGES 权限,且新增了 PackageInstaller 的安全校验。

适配代码

kotlin 复制代码
// 1. 检查安装权限
private fun checkInstallPermission(context: Context): Boolean {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        context.packageManager.canRequestPackageInstalls()
    } else {
        true // 低版本无需校验
    }
}

// 2. 请求安装权限
private fun requestInstallPermission(activity: Activity) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !checkInstallPermission(activity)) {
        val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES).apply {
            data = Uri.parse("package:${activity.packageName}")
        }
        activity.startActivityForResult(intent, REQUEST_INSTALL_PERMISSION)
    }
}

// 3. 使用PackageInstaller安装APK(Android 14推荐方式)
private fun installApkWithPackageInstaller(context: Context, apkPath: String) {
    val packageInstaller = context.packageManager.packageInstaller
    val params = PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL)
    val sessionId = packageInstaller.createSession(params)
    val session = packageInstaller.openSession(sessionId)

    // 写入APK文件
    val inputStream = FileInputStream(apkPath)
    val outputStream = session.openWrite("apk_install", 0, -1)
    inputStream.copyTo(outputStream)
    session.fsync(outputStream)
    inputStream.close()
    outputStream.close()

    // 提交安装
    val intent = Intent(context, InstallResultReceiver::class.java)
    val pendingIntent = PendingIntent.getBroadcast(
        context,
        0,
        intent,
        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE // Android 12+ 必须加FLAG_IMMUTABLE
    )
    session.commit(pendingIntent.intentSender)
    session.close()
}

// 接收安装结果的广播接收器
class InstallResultReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        val status = intent?.getIntExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_FAILURE)
        val message = intent?.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE)
        when (status) {
            PackageInstaller.STATUS_SUCCESS -> {
                // 安装成功
            }
            else -> {
                // 安装失败
            }
        }
    }
}

3. 后台弹出窗口权限适配

Android 14 限制了后台应用弹出窗口,需申请 SYSTEM_ALERT_WINDOW 权限,且仅前台应用可弹出窗口。

适配代码

kotlin 复制代码
// 检查悬浮窗权限
private fun checkOverlayPermission(context: Context): Boolean {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        Settings.canDrawOverlays(context)
    } else {
        true
    }
}

// 请求悬浮窗权限
private fun requestOverlayPermission(activity: Activity) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !checkOverlayPermission(activity)) {
        val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION).apply {
            data = Uri.parse("package:${activity.packageName}")
        }
        activity.startActivityForResult(intent, REQUEST_OVERLAY_PERMISSION)
    }
}

4. PendingIntent 兼容性适配

Android 14 要求 PendingIntent 必须指定 FLAG_IMMUTABLEFLAG_MUTABLE,否则会抛出异常。

适配代码

kotlin 复制代码
// 正确创建PendingIntent(Android 12+ 适配)
private fun createPendingIntent(context: Context): PendingIntent {
    val intent = Intent(context, MyReceiver::class.java)
    val flags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
    } else {
        PendingIntent.FLAG_UPDATE_CURRENT
    }
    return PendingIntent.getBroadcast(context, 0, intent, flags)
}

三、Android 14 新特性接入

1. 实时文本(Live Text)支持

Android 14 新增实时文本 API,可提取图片中的文本,支持中文等多语言。

适配代码

kotlin 复制代码
// 提取图片中的文本
private suspend fun extractTextFromImage(context: Context, bitmap: Bitmap): String {
    return withContext(Dispatchers.IO) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
            val liveTextManager = context.getSystemService(LiveTextManager::class.java)
            val result = liveTextManager.processImage(bitmap)
            result.text ?: ""
        } else {
            "" // 低版本降级处理
        }
    }
}

2. 锁屏小组件(Lock Screen Widgets)

Android 14 支持锁屏添加小组件,需适配小组件的尺寸和交互。

适配代码

kotlin 复制代码
// 定义锁屏小组件(继承AppWidgetProvider)
class LockScreenWidget : AppWidgetProvider() {
    override fun onUpdate(
        context: Context,
        appWidgetManager: AppWidgetManager,
        appWidgetIds: IntArray
    ) {
        appWidgetIds.forEach { widgetId ->
            val views = RemoteViews(context.packageName, R.layout.widget_lock_screen)
            // 设置小组件内容
            views.setTextViewText(R.id.widget_text, "锁屏小组件示例")
            // 适配锁屏尺寸(Android 14新增尺寸)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
                views.setInt(R.id.widget_root, "setMinimumWidth", 300)
                views.setInt(R.id.widget_root, "setMinimumHeight", 150)
            }
            appWidgetManager.updateAppWidget(widgetId, views)
        }
    }
}

// Manifest声明锁屏小组件
<receiver
    android:name=".LockScreenWidget"
    android:label="锁屏小组件">
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>
    <meta-data
        android:name="android.appwidget.provider"
        android:resource="@xml/widget_lock_screen_info" />
</receiver>

3. 拍照/录像 API 增强

Android 14 新增 CameraManager.AvailabilityCallback 回调,优化相机设备状态监听。

适配代码

kotlin 复制代码
// 监听相机可用性
private fun monitorCameraAvailability(context: Context) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
        val cameraManager = context.getSystemService(CameraManager::class.java)
        cameraManager.registerAvailabilityCallback(object : CameraManager.AvailabilityCallback() {
            override fun onCameraAvailable(cameraId: String) {
                // 相机可用
            }

            override fun onCameraUnavailable(cameraId: String) {
                // 相机不可用
            }
        }, Handler(Looper.getMainLooper()))
    }
}

四、适配注意事项

  1. 分区适配 :使用 Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE 做版本判断,避免低版本崩溃。
  2. 权限申请时机:权限申请需在用户交互时触发(如点击按钮),否则系统会拒绝。
  3. FLAG_IMMUTABLE :所有 PendingIntent 必须指定 FLAG_IMMUTABLE(非交互场景)或 FLAG_MUTABLE(交互场景)。
  4. 测试覆盖
    • 测试 Target SDK 34 下的行为;
    • 测试未授予权限时的降级逻辑;
    • 测试后台启动、弹窗、安装等场景的权限校验。
  5. 隐私合规:新增权限需在隐私政策中说明用途,符合应用商店审核要求。

五、参考资源

六、总结

Android 14 的适配核心围绕权限强化安全校验新 API 接入展开,重点关注前台服务、安装权限、PendingIntent 等关键变更。通过版本判断做分区适配,确保低版本兼容,同时接入实时文本、锁屏小组件等新特性,提升应用体验。

所有代码均基于 Kotlin 编写,适配了 Android 14 的核心变更,可直接集成到项目中,建议根据业务场景调整细节。

相关推荐
踏雪羽翼5 小时前
android TextView实现文字字符不同方向显示
android·自定义view·textview方向·文字方向·textview文字显示方向·文字旋转·textview文字旋转
lxysbly5 小时前
安卓玩MRP冒泡游戏:模拟器下载与使用方法
android·游戏
夏沫琅琊8 小时前
Android 各类日志全面解析(含特点、分析方法、实战案例)
android
程序员JerrySUN8 小时前
OP-TEE + YOLOv8:从“加密权重”到“内存中解密并推理”的完整实战记录
android·java·开发语言·redis·yolo·架构
TeleostNaCl9 小时前
Android | 启用 TextView 跑马灯效果的方法
android·经验分享·android runtime
TheNextByte110 小时前
Android USB文件传输无法使用?5种解决方法
android
quanyechacsdn11 小时前
Android Studio创建库文件用jitpack构建后使用implementation方式引用
android·ide·kotlin·android studio·implementation·android 库文件·使用jitpack
程序员陆业聪12 小时前
聊聊2026年Android开发会是什么样
android
编程大师哥12 小时前
Android分层
android
极客小云14 小时前
【深入理解 Android 中的 build.gradle 文件】
android·安卓·安全架构·安全性测试