A.I, Data and Software Engineering

Don’t copy and paste sensitive information – here is why

D

Clipboard was created for productivity purposes but developers can easily exploit this for malicious purposes. This article will demonstrates how to access Android/iOS clipboard from an activity or background service.

Clipboard access

Android provides a powerful clipboard-based framework for copying and pasting. It supports both simple and complex data types, including text strings, complex data structures, text and binary stream data, and even application assets. Simple text data is stored directly in the clipboard, while complex data is stored as a reference that the pasting application resolves with a content provider. 

A block diagram of the copy and paste framework
The Android clipboard framework

To copy data, an application puts a ClipData object on the ClipboardManager global clipboard. The ClipData contains one or more ClipData.Item objects and one ClipDescription object. To paste data, an application gets the ClipData, gets its MIME type from the ClipDescription, and gets the data either from the ClipData.Item or from the content provider referred to by ClipData.Item.

To get the data from the clipboard is rather easy.

var clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
var pasteData: String = clipboard.primaryClip?.getItemAt(0)?.text.toString()

Nevertheless, it is only available in App (from Android 10+), and when the activity has the focus. So you can implement the code in the onWindowFocusChanged method.

Access from a background service.

Although it is now not possible to access clipboard outside of the current app context, sometimes, you may want it to run from the background (without UI). We can follow these steps:

  • Create a service
  • Implement onStartCommand

The code for the service can be as simple as this:

package com.petamind.myclipboard
import android.app.Service
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.os.Handler
import android.os.IBinder
import android.os.Looper
import android.os.Message
import android.widget.Toast
class ClipboardService: Service(), Runnable {
    lateinit var context: Context
    val handler = object :Handler(Looper.getMainLooper()){
        override fun handleMessage(msg: Message) {
            val cb = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
            val text = cb?.primaryClip?.getItemAt(0)?.text.toString()
            Toast.makeText(context, text, Toast.LENGTH_SHORT).show()
        }
    }
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        context = this
        //Monitor the clipboard using a thread
        Thread(this).start()
        return super.onStartCommand(intent, flags, startId)
    }
    override fun onBind(p0: Intent?): IBinder? {
        return null
    }
    override fun run() {
        while(true) {
            Thread.sleep(5000)
            handler.sendEmptyMessage(0)
        }
    }
}

iOS: copy text to the clipboard (SWIFT)

You can write to and read from the iOS clipboard by using the UIPasteboard class, which has a generalPasteboard() method that returns the shared system method of copying and pasting data between apps. Using this you can write text to the clipboard just like this:

let pasteboard = UIPasteboard.general
pasteboard.string = "Hello, world!"

To read text back from the clipboard, you should unwrap its optional value like this:

if let string = pasteboard.string {
    // text was found and placed in the "string" constant
}

Video tutorial

Useful links

  • Subscribe to Petamind youtube channel
  • For other projects using Kotlin, please click here.

Add comment

A.I, Data and Software Engineering

PetaMinds focuses on developing the coolest topics in data science, A.I, and programming, and make them so digestible for everyone to learn and create amazing applications in a short time.

Categories