Android 10+中如何从后台服务获取剪贴板内容?

问题描述 投票:0回答:1

我是 Android 开发新手。我读到 Android 10+ 限制剪贴板访问仅限于重点应用程序 还有其他选择吗?我在 Clipt 应用程序中看到,当我们单击通知栏中的按钮时,应用程序可以访问剪贴板内容,我如何重新创建该示例?

这是我尝试过的,抱歉代码混乱:(


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")
  }
}

这不起作用,并说

Denying clipboard access to com.srilakshmikanthanp.clipbirdroid, application is not in focus nor is it a system service for user
另外,我不希望像新活动那样对用户造成任何干扰。我希望所有任务都应该在后台进行,这可能吗?预先感谢:)

android kotlin android-service clipboard
1个回答
0
投票

我找到了一个解决方案,例如启动具有透明背景的活动,当它获得焦点时,只需复制并关闭活动示例即可,

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()
  }
}

在AndroidManifest.xml中

<activity
  android:name=".ui.gui.SendHandler"
  android:theme="@android:style/Theme.Translucent.NoTitleBar"
  android:parentActivityName=".ui.gui.MainActivity" />

据我所知,如果有人有更好的解决方案,请给出另一个答案:)

© www.soinside.com 2019 - 2024. All rights reserved.