Android 复制文本到系统剪切板

更新日期: 2022-11-06 阅读次数: 2347 字数: 542 分类: Android

需求

我正在开发的一个 Android App,其主要功能就是将扫描出来的蓝牙设备信息,自动复制到手机剪切板。 然后复制到其他需要配置的地方。

例如,点击蓝牙设备的 Mac 地址,自动写入剪切板。

复杂的实现

看了官方文档,发现要实现这么个简单的功能,远比想象中复杂。

https://developer.android.com/develop/ui/views/touch-and-input/copy-paste

  • 操作反馈。Android 13 之后,在写入剪切板之后,会有自动的提示。而低版本就需要自己去实现提示,Toasts 或者 Snackbars。
  • fragment 与 activity 中实现的差异
  • 敏感信息的处理方式。因为 Android 13 在写入剪切板之后,会在屏幕底部预览已复制的内容,容易泄露密码等敏感信息。
  • 为啥会有 setPrimaryClip 难道还有 Secondary ?
  • 除了复制纯文本,还能复制二进制内容,及更复杂的场景。看起来可以实现一些多 app 间的自动化流程。

kotlin 实现代码

在 activity 中调用:

fun copyText(text:String) {
    val clipboardManager = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
    // When setting the clip board text.
    clipboardManager.setPrimaryClip(ClipData.newPlainText("", text))
    // Only show a toast for Android 12 and lower.
    if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2)
        Toast.makeText(context, "Copied", Toast.LENGTH_SHORT).show()
}

在 fragment 中调用

fun copyText(text:String) {
    val clipboardManager = activity?.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
    // When setting the clip board text.
    clipboardManager.setPrimaryClip(ClipData.newPlainText("", text))
    // Only show a toast for Android 12 and lower.
    if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2)
        Toast.makeText(activity, "Copied", Toast.LENGTH_SHORT).show()
}

在 recycler view adapter 的 view holder 中调用。 其中增加了一个参数 view,这里传入随便一个 text view 或者 button 都可以。

private fun copyText(text: String, view: View) {
	val clipboardManager =
		view.context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
	// When setting the clip board text.
	clipboardManager.setPrimaryClip(ClipData.newPlainText("", text))
	// Only show a toast for Android 12 and lower.
	if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2)
		Toast.makeText(view.context, "Copied", Toast.LENGTH_SHORT).show()
}

封装

由于 app 中,多处要用到剪切板功能,还是封装在一个 object 比较方便代码更新。

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

object Utils {
    fun copyText(text: String, context: Context) {
        val clipboardManager =
            context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
        // When setting the clip board text.
        clipboardManager.setPrimaryClip(ClipData.newPlainText("", text))
        // Only show a toast for Android 12 and lower.
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2)
            Toast.makeText(context, "Copied", Toast.LENGTH_SHORT).show()
    }
}

例如,在 recycler view adapter 的 view holder 中调用。

address.setOnClickListener {
    Utils.copyText(address.text as String, address.context)
}

参考

  • 官方文档 https://developer.android.com/develop/ui/views/touch-and-input/copy-paste
  • https://stackoverflow.com/questions/57646508/kotlin-android-copy-to-clipboard-from-fragment

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式