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

如何用Kotlin将PNG图片数据复制到Android剪贴板?

在Kotlin中将PNG Data URI存入Android剪贴板的实现方案

一、核心实现步骤

1. 解码PNG Data URI

从Data URI字符串中提取base64编码的图片数据,解码为字节数组:

import android.util.Base64

fun decodePngDataUri(dataUri: String): ByteArray? {
    val base64Prefix = "data:image/png;base64,"
    if (!dataUri.startsWith(base64Prefix)) {
        return null
    }
    val base64Content = dataUri.substring(base64Prefix.length)
    return try {
        Base64.decode(base64Content, Base64.DEFAULT)
    } catch (e: IllegalArgumentException) {
        e.printStackTrace()
        null
    }
}

2. 将图片字节写入临时文件并获取安全Uri

Android剪贴板需要可被系统识别的安全Uri,这里使用FileProvider生成符合权限要求的Uri:

第一步:配置FileProvider

在AndroidManifest.xml中添加Provider配置:

<application>
    ...
    <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="${applicationId}.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>
</application>

在res/xml目录下创建file_paths.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <cache-path name="temp_images" path="images/" />
</paths>

第二步:写入文件并生成Uri

import androidx.core.content.FileProvider
import android.content.Context
import java.io.File
import java.io.FileOutputStream

fun getTempImageUri(context: Context, imageBytes: ByteArray): android.net.Uri? {
    val tempDir = File(context.cacheDir, "images")
    if (!tempDir.exists()) {
        tempDir.mkdirs()
    }
    val tempFile = File(tempDir, "clipboard_png_${System.currentTimeMillis()}.png")
    return try {
        FileOutputStream(tempFile).use { outputStream ->
            outputStream.write(imageBytes)
        }
        FileProvider.getUriForFile(
            context,
            "${context.packageName}.fileprovider",
            tempFile
        )
    } catch (e: Exception) {
        e.printStackTrace()
        tempFile.delete()
        null
    }
}

3. 将图片Uri存入剪贴板

适配不同Android版本的剪贴板操作逻辑:

import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.os.Build

fun copyPngToClipboard(context: Context, imageUri: android.net.Uri) {
    val clipboardManager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
    val clipData = ClipData.newUri(
        context.contentResolver,
        "PNG Image",
        imageUri
    ).apply {
        // 兼容Android 12及以下版本
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
            addItem(ClipData.Item(imageUri))
        }
    }
    clipboardManager.setPrimaryClip(clipData)
}

二、结合WebView的JavascriptInterface实现

在Activity/Fragment中给WebView添加JS接口,接收前端传递的Data URI:

import android.webkit.JavascriptInterface
import android.webkit.WebView

class WebAppInterface(private val context: Context) {

    @JavascriptInterface
    fun copyPngFromCanvas(dataUri: String) {
        val imageBytes = decodePngDataUri(dataUri) ?: return
        val imageUri = getTempImageUri(context, imageBytes) ?: return
        copyPngToClipboard(context, imageUri)
    }
}

// 初始化WebView时绑定接口
webView.addJavascriptInterface(WebAppInterface(this), "AndroidClipboard")

前端JS调用示例:

// 从canvas获取Data URI后调用Android接口
const dataUri = canvas.toDataURL('image/png');
AndroidClipboard.copyPngFromCanvas(dataUri);

三、注意事项

  • 无需额外存储权限:使用应用缓存目录,FileProvider自动处理权限授予
  • 临时文件清理:可在应用退出时清理cacheDir/images下的临时文件,避免占用空间
  • 版本兼容:已适配Android 12及以下版本的剪贴板识别逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 02:56:14