You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 12及以上版本录屏权限重复请求问题求助

Android 12+ 录屏权限仅请求一次的实现方案

核心逻辑

Android 12及以上版本中,MEDIA_PROJECTION录屏权限默认是单次会话权限,但系统允许开发者保存用户授权后的权限令牌(即授权返回的Intent),后续启动录屏时复用该令牌,无需再次弹出授权弹窗。注意:设备重启后令牌会失效,此时必须重新请求权限,这是系统硬性限制,所有应用都无法绕过。

具体实现步骤

1. 首次授权后保存令牌

当用户首次同意录屏权限后,将授权返回的Intent持久化存储(推荐用SharedPreferences):

Kotlin 代码示例

private const val REQUEST_CODE_SCREEN_CAPTURE = 1001

// 初始化MediaProjectionManager
val mediaProjectionManager = getSystemService(MEDIA_PROJECTION_SERVICE) as MediaProjectionManager

// 启动权限请求
startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), REQUEST_CODE_SCREEN_CAPTURE)

// 处理授权结果
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == REQUEST_CODE_SCREEN_CAPTURE && resultCode == RESULT_OK) {
        data?.let {
            // 保存Intent到SharedPreferences
            val sharedPref = getSharedPreferences("ScreenCapturePrefs", MODE_PRIVATE)
            sharedPref.edit().putParcelable("media_projection_token", it).apply()
            
            // 初始化MediaProjection并启动录屏
            val mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, it)
            startScreenRecording(mediaProjection)
        }
    }
}

Java 代码示例

private static final int REQUEST_CODE_SCREEN_CAPTURE = 1001;

// 初始化MediaProjectionManager
MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);

// 启动权限请求
startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), REQUEST_CODE_SCREEN_CAPTURE);

// 处理授权结果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE_SCREEN_CAPTURE && resultCode == RESULT_OK) {
        if (data != null) {
            // 保存Intent到SharedPreferences
            SharedPreferences sharedPref = getSharedPreferences("ScreenCapturePrefs", MODE_PRIVATE);
            SharedPreferences.Editor editor = sharedPref.edit();
            editor.putParcelable("media_projection_token", data);
            editor.apply();
            
            // 初始化MediaProjection并启动录屏
            MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);
            startScreenRecording(mediaProjection);
        }
    }
}

2. 后续启动复用令牌

每次启动录屏前,先读取保存的令牌,若有效则直接复用:

Kotlin 代码示例

val sharedPref = getSharedPreferences("ScreenCapturePrefs", MODE_PRIVATE)
val savedToken = sharedPref.getParcelable<Intent>("media_projection_token")

if (savedToken != null) {
    try {
        val mediaProjection = mediaProjectionManager.getMediaProjection(RESULT_OK, savedToken)
        mediaProjection?.let {
            startScreenRecording(it)
            return
        }
    } catch (e: Exception) {
        // 令牌失效,清除存储并重新请求权限
        sharedPref.edit().remove("media_projection_token").apply()
    }
}

// 无有效令牌,重新请求权限
startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), REQUEST_CODE_SCREEN_CAPTURE)

Java 代码示例

SharedPreferences sharedPref = getSharedPreferences("ScreenCapturePrefs", MODE_PRIVATE);
Intent savedToken = sharedPref.getParcelable("media_projection_token");

if (savedToken != null) {
    try {
        MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(RESULT_OK, savedToken);
        if (mediaProjection != null) {
            startScreenRecording(mediaProjection);
            return;
        }
    } catch (Exception e) {
        // 令牌失效,清除存储并重新请求权限
        SharedPreferences.Editor editor = sharedPref.edit();
        editor.remove("media_projection_token");
        editor.apply();
    }
}

// 无有效令牌,重新请求权限
startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), REQUEST_CODE_SCREEN_CAPTURE);

3. 处理令牌失效场景

以下情况令牌会失效,需重新请求权限:

  • 设备重启后
  • 用户在系统设置中手动撤销了应用的录屏权限
  • 应用被清除数据

此时getMediaProjection()会返回null或抛出异常,需捕获并重新引导授权。

关键注意事项

  • 必须确保用户明确同意长期使用录屏权限,避免违反Google Play隐私政策。
  • 不要尝试绕过系统限制(比如重启后仍免授权),这是Android安全机制的一部分,无法实现。

内容的提问来源于stack exchange,提问作者Kitty Kagaya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 10:36:59