Skip to content

Commit

Permalink
enhance clipboard
Browse files Browse the repository at this point in the history
Signed-off-by: tobiasKaminsky <tobias@kaminsky.me>
  • Loading branch information
tobiasKaminsky authored and alperozturk96 committed Feb 24, 2025
1 parent 1013df7 commit 47ea22d
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 20 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Nextcloud - Android Client
*
* SPDX-FileCopyrightText: 2024 Alper Ozturk <alper.ozturk@nextcloud.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

package com.nextcloud.client.jobs.clipboard

import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.os.Build
import androidx.work.Worker
import androidx.work.WorkerParameters
import com.owncloud.android.lib.common.utils.Log_OC

class ClipboardClearWorker(
private val context: Context,
params: WorkerParameters
) : Worker(context, params) {
private val tag = ClipboardClearWorker::class.java.name

companion object {
const val CLIPBOARD_TEXT = "clipboard_text"
}

@Suppress("TooGenericExceptionCaught", "ReturnCount")
override fun doWork(): Result {
try {
val clipboardManager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val currentClip = clipboardManager.primaryClip ?: return Result.success()
val clipboardText = currentClip.getItemAt(0).text?.toString() ?: return Result.success()
val copiedText = inputData.getString(CLIPBOARD_TEXT)
if (copiedText != clipboardText) {
return Result.success()
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
clipboardManager.clearPrimaryClip()
} else {
val newEmptyClip = ClipData.newPlainText("EmptyClipContent", "")
clipboardManager.setPrimaryClip(newEmptyClip)
}

return Result.success()
} catch (e: Exception) {
Log_OC.e(tag, "Error in clipboard clear worker", e)
return Result.retry()
}
}
}
72 changes: 52 additions & 20 deletions app/src/main/java/com/owncloud/android/utils/ClipboardUtil.kt
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
/*
* Nextcloud - Android Client
*
* SPDX-FileCopyrightText: 2024 Alper Ozturk <alper.ozturk@nextcloud.com>
* SPDX-FileCopyrightText: 2018 Andy Scherzinger <info@andy-scherzinger.de>
* SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
*/
package com.owncloud.android.utils

import android.app.Activity
import android.content.ClipData
import android.content.ClipDescription
import android.content.ClipboardManager
import android.content.Context
import android.os.Build
import android.os.PersistableBundle
import android.text.TextUtils
import android.widget.Toast
import androidx.work.Data
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import com.nextcloud.client.jobs.clipboard.ClipboardClearWorker
import com.nextcloud.utils.mdm.MDMConfig
import com.owncloud.android.R
import com.owncloud.android.lib.common.utils.Log_OC
import java.util.concurrent.TimeUnit

/**
* Helper implementation to copy a string into the system clipboard.
*/
object ClipboardUtil {
private val TAG = ClipboardUtil::class.java.name
private const val WORKER_CLEAR_DELAY = 15L

@JvmStatic
@JvmOverloads
Expand All @@ -30,25 +37,50 @@ object ClipboardUtil {
return
}

if (!TextUtils.isEmpty(text)) {
try {
val clip = ClipData.newPlainText(
activity.getString(
R.string.clipboard_label,
activity.getString(R.string.app_name)
),
text
)
(activity.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager).setPrimaryClip(clip)
if (showToast) {
Toast.makeText(activity, R.string.clipboard_text_copied, Toast.LENGTH_SHORT).show()
if (TextUtils.isEmpty(text)) {
Toast.makeText(activity, R.string.clipboard_no_text_to_copy, Toast.LENGTH_SHORT).show()
return
}

try {
val clipboardLabel = activity.getString(R.string.clipboard_label, activity.getString(R.string.app_name))
val clip = getClipData(clipboardLabel, text)
val clipboardManager = (activity.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager)
clipboardManager.setPrimaryClip(clip)

if (showToast) {
Toast.makeText(activity, R.string.clipboard_text_copied, Toast.LENGTH_SHORT).show()
}

scheduleClipboardClearWorker(activity, text)
} catch (e: Exception) {
Toast.makeText(activity, R.string.clipboard_unexpected_error, Toast.LENGTH_SHORT).show()
Log_OC.e(TAG, "Exception caught while copying to clipboard", e)
}
}

private fun getClipData(clipboardLabel: String, text: String?): ClipData {
return ClipData.newPlainText(clipboardLabel, text).apply {
description.extras = PersistableBundle().apply {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
putBoolean(ClipDescription.EXTRA_IS_SENSITIVE, true)
} else {
putBoolean("android.content.extra.IS_SENSITIVE", true)
}
} catch (e: Exception) {
Toast.makeText(activity, R.string.clipboard_unexpected_error, Toast.LENGTH_SHORT).show()
Log_OC.e(TAG, "Exception caught while copying to clipboard", e)
}
} else {
Toast.makeText(activity, R.string.clipboard_no_text_to_copy, Toast.LENGTH_SHORT).show()
}
}

private fun scheduleClipboardClearWorker(context: Context, text: String?) {
val data = Data.Builder()
.putString(ClipboardClearWorker.CLIPBOARD_TEXT, text)
.build()

val clearWorkRequest = OneTimeWorkRequestBuilder<ClipboardClearWorker>()
.setInitialDelay(WORKER_CLEAR_DELAY, TimeUnit.SECONDS)
.setInputData(data)
.build()

WorkManager.getInstance(context).enqueue(clearWorkRequest)
}
}

0 comments on commit 47ea22d

Please sign in to comment.