I am new to Android development. I Read that Android 10+ limits clipboard access to only focused apps Is there any other option? I saw it in Clipt Application that when we click the button in the notification bar the app can access the clipboard content how can I recreate that any example?
Here is what I have tried Sorry for the messy code :(
package com.srilakshmikanthanp.clipbirdroid.ui.gui
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.IBinder
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import com.srilakshmikanthanp.clipbirdroid.R
class MyService : Service() {
override fun onBind(intent: Intent?): IBinder? {
return null
}
private fun showNotification(context: Context) {
val channelId = "clipbird"
// create channel
val notificationChannel = NotificationChannel(
channelId,
"Clipboard",
NotificationManager.IMPORTANCE_DEFAULT
)
val notificationBuilder = NotificationCompat.Builder(context, channelId)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("Notification Title")
.setContentText("Click the button to Copy!")
.addAction(R.drawable.ic_launcher_foreground, "Copy", getHelloPendingIntent(context))
.setOngoing(true)
val notificationManager = NotificationManagerCompat.from(context)
notificationManager.createNotificationChannel(notificationChannel)
notificationManager.notify(1, notificationBuilder.build())
Log.d("MyService", "showNotification")
}
private fun getHelloPendingIntent(context: Context): PendingIntent {
val helloIntent = Intent(context, SendHandler::class.java)
return PendingIntent.getActivity(context, 100, helloIntent, PendingIntent.FLAG_UPDATE_CURRENT)
}
override fun onCreate() {
super.onCreate()
showNotification(this)
}
}
class SendHandler : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
// on focus
override fun onResume() {
super.onResume()
Log.d("SendHandler", "onResume")
// print the clipboard content
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = clipboard.primaryClip
if (clip != null) {
val item = clip.getItemAt(0)
val text = item.text
Log.d("SendHandler", "text: $text")
}
}
}
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MaterialTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Greeting("Android")
}
}
}
// start the service
val intent = Intent(this, MyService::class.java)
startService(intent)
}
}
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Text(
text = "Hello $name!",
modifier = modifier
)
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
MaterialTheme {
Greeting("Android")
}
}
This doesn't work and says Denying clipboard access to com.srilakshmikanthanp.clipbirdroid, application is not in focus nor is it a system service for user
Also I do not want any Interruption to the user like the New Activity. I want all tasks should be in the background is that possible? Thanks in advance :)
I found a solution like Launching an Activity with a transparent background Now when the Activity gets focused get the clipboard content and then close it, example would be,
class SendHandler : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
// on focus
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
if(!hasFocus) return;
Log.d("SendHandler", "onWindowFocusChanged")
// print the clipboard content
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = clipboard.primaryClip
if (clip != null) {
val item = clip.getItemAt(0)
val text = item.text
Log.d("SendHandler", "text: $text")
}
// finished
finish()
}
}
In AndroidManifest.xml
<activity
android:name=".ui.gui.SendHandler"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:parentActivityName=".ui.gui.MainActivity" />
This is as far as I Know If Anyone Has a better solution Please Give another Answer :)