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 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式