静默安装系统app

309 阅读1分钟

在Android 10及以上版本中,由于安全限制的加强,静默安装系统应用程序的方法已经发生了变化。现在需要使用设备策略管理器来实现静默安装。下面是一个Kotlin示例代码,用于使用设备策略管理器来静默安装系统应用程序:

/**
 * 安装系统应用程序
 * @param context 应用程序上下文
 * @param packageName 应用程序包名
 */
@RequiresApi(Build.VERSION_CODES.Q)
fun installSystemApp(context: Context, packageName: String) {
    val devicePolicyManager = context.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
    val componentName = ComponentName(context, MyDeviceAdminReceiver::class.java)
    if (devicePolicyManager.isAdminActive(componentName)) {
        val installerPackageName = devicePolicyManager.getProfileOwnerAsUser(UserHandle.myUserId())?.packageName
        if (installerPackageName != null) {
            val packageInfo = getSystemPackageInfo(context.packageManager, packageName)
            if (packageInfo != null) {
                val apkFile = File(packageInfo.applicationInfo.publicSourceDir)
                val packageInstaller = context.packageManager.packageInstaller
                val sessionParams = PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL)
                sessionParams.setAppPackageName(packageName)
                val sessionId = packageInstaller.createSession(sessionParams)
                val session = packageInstaller.openSession(sessionId)
                val outputStream = session.openWrite(apkFile.name, 0, -1)
                val inputStream = FileInputStream(apkFile)
                val buffer = ByteArray(8192)
                var length: Int
                while (inputStream.read(buffer).also { length = it } > 0) {
                    outputStream.write(buffer, 0, length)
                }
                session.fsync(outputStream)
                outputStream.close()
                inputStream.close()
                session.commit(PendingIntent.getBroadcast(context, sessionId, Intent("android.intent.action.INSTALL_COMPLETED"), 0).intentSender)
            } else {
                // 应用程序包名不正确或应用程序未安装
            }
        } else {
            // 未获得设备所有者权限
        }
    } else {
        // 未激活设备管理器
    }
}

/**
 * 获取系统应用程序信息
 * @param packageManager 包管理器
 * @param packageName 应用程序包名
 * @return 应用程序信息
 */
fun getSystemPackageInfo(packageManager: PackageManager, packageName: String): PackageInfo? {
    try {
        val applicationInfo = packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA)
        if (applicationInfo != null && (applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM) != 0) {
            return packageManager.getPackageArchiveInfo(applicationInfo.publicSourceDir, PackageManager.GET_ACTIVITIES or PackageManager.GET_SERVICES)
        }
    } catch (e: PackageManager.NameNotFoundException) {
        e.printStackTrace()
    }
    return null
}