Android 17 取色器 API:无需权限,一行 Intent 跨应用取色

在设计工具、图片编辑器、主题定制类应用中,跨应用取色一直是个刚需但又极其难搞的功能。

Android 17(API 37)带来了全新的 Eye Dropper API,用一行 Intent 就能调起系统取色器,无需任何权限申请。

以前有多麻烦?

想在 Android 上实现跨应用取色,传统方案需要借助 MediaProjection 截屏再取像素色值:

bash 复制代码
// 传统方案:复杂、侵入、吓人
val projectionManager = getSystemService(MediaProjectionManager::class.java)
val intent = projectionManager.createScreenCaptureIntent()
// → 弹出系统录屏警告对话框
// → 用户看到"将开始录制屏幕上显示的所有内容"
// → 大量用户直接拒绝退出

这个方案有三个致命问题:

1. 权限恐吓

需要 MEDIA_PROJECTION 权限,系统会弹出录屏警告对话框。用户看到"录制屏幕上显示的所有内容"这种措辞,转化率直接腰斩。

2. 实现复杂

拿到 MediaProjection 后,还要创建 VirtualDisplayImageReader,处理像素缓冲区,管理生命周期,代码量至少上百行。

3. 隐私过度

你只需要一个像素的颜色值,却要请求整个屏幕的录制权限,属于典型的"杀鸡用牛刀"。

Eye Dropper API:极简方案

Android 17 的 Eye Dropper API 把这一切简化到了极致。核心就两个常量:

Compose 完整实现

bash 复制代码
@Composable
fun EyeDropperScreen() {
    var pickedColor by remember { mutableStateOf(Color.Gray) }
    var colorHex by remember { mutableStateOf("#808080") }

    val launcher = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.StartActivityForResult()
    ) { result ->
        if (result.resultCode == Activity.RESULT_OK) {
            val colorInt = result.data?.getIntExtra(
                "android.intent.extra.COLOR",
                android.graphics.Color.BLACK
            ) ?: android.graphics.Color.BLACK

            pickedColor = Color(colorInt)
            colorHex = String.format("#%06X", 0xFFFFFF and colorInt)
        }
    }

    Column(
        modifier = Modifier.fillMaxSize().padding(32.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        // 颜色预览
        Box(
            modifier = Modifier
                .size(120.dp)
                .clip(CircleShape)
                .background(pickedColor)
                .border(2.dp, Color.White, CircleShape)
        )

        Spacer(modifier = Modifier.height(16.dp))

        Text(
            text = colorHex,
            style = MaterialTheme.typography.headlineMedium,
            fontFamily = FontFamily.Monospace
        )

        Spacer(modifier = Modifier.height(32.dp))

        // 取色按钮
        Button(
            onClick = {
                launcher.launch(
                    Intent("android.intent.action.OPEN_EYE_DROPPER")
                )
            },
            enabled = Build.VERSION.SDK_INT >= 37
        ) {
            Text("Pick a Color")
        }
    }
}

没看错,完整功能代码不到 50 行

它是怎么工作的?

Eye Dropper API 的设计哲学是最小化数据暴露

bash 复制代码
┌──────────────┐    Intent     ┌──────────────┐
│              │ ─────────────→│              │
│   你的 App   │               │  系统取色器   │
│              │←─────────────│              │
└──────────────┘  Color Int    └──────────────┘
                                     │
                                     │ 系统级
                                     │ 像素读取
                                     ↓
                              ┌──────────────┐
                              │   屏幕像素   │
                              └──────────────┘

关键点在于:

对比一下两种方案的差异:

版本兼容处理

由于该 API 要求 API 37,建议做好版本判断和降级处理:

bash 复制代码
fun isEyeDropperAvailable(): Boolean {
    return Build.VERSION.SDK_INT >= 37
}

// 在 UI 中
Button(
    onClick = { /* launch eye dropper */ },
    enabled = isEyeDropperAvailable()
) {
    Text(
        if (isEyeDropperAvailable()) "Pick a Color"
        else "Requires Android 17+"
    )
}

也可以用 Intent.resolveActivity() 做更精确的判断:

bash 复制代码
val intent = Intent("android.intent.action.OPEN_EYE_DROPPER")
val isAvailable = intent.resolveActivity(packageManager) != null

适合哪些场景?

  • 设计工具:从任意 App 中采集品牌色、UI 配色

  • 图片编辑器:从照片或其他应用中精准取色

  • 主题生成器:根据壁纸或任意界面自动提取主题色

  • 无障碍工具:帮助色觉异常用户识别屏幕颜色

  • 开发调试:快速获取任意界面元素的颜色值

总结

Android 17 的 Eye Dropper API 是一个小而美的 API 设计典范:

  • 零权限:不需要声明任何权限

  • 零隐私风险:App 只拿到一个颜色值,无法窥探屏幕内容

  • 零学习成本:一个 Intent 发出去,一个 Int 拿回来

如果你的应用有取色需求,这将是 Android 17 最值得适配的 API 之一。

相关推荐
therese_100865 分钟前
安卓-CeilingNestedScrollView
android
帅次5 分钟前
Android 高级工程师面试参考答案:语言基础与并发
android·面试·职场和发展
凤年徐17 分钟前
自动化构建工具:make 与 Makefile
android·java·linux·自动化
三少爷的鞋34 分钟前
从 Callback 到 Coroutines:Android 异步并发方案的演进
android
鹏程十八少37 分钟前
4. 2026金三银四 Android OkHttp 面试核心 45 问:从源码到架构深度解析
android·前端·面试
90后的晨仔10 小时前
Android Studio 项目模板完全指南
android
summerkissyou198710 小时前
Android-SurfaceView-投屏-常见问题
android·surfaceview
明天就是Friday10 小时前
Android实战项目④ OkHttp WebSocket开发即时通讯App 完整源码详解
android·websocket·okhttp
吉哥机顶盒刷机11 小时前
好物分享:DNA-Android-4.0.5安卓固件解包、打包工具
android·好物分享
三棱球11 小时前
App逆向学习笔记(三)——Android开发入门课
android·笔记