使用 adb 将文本检索到 Linux 终端以获取 Android 服务 运行

retrieve text to Linux terminal for Android service run with adb

我想要一个 Android 服务(用 Kotlin 编写)运行 在 Linux 终端中打印一条消息到它 运行 所在的终端。主要的 Kotlin class 在 this file 中(我克隆了那个 repo)。

我想以各种方式修改它,但现在我只想看看是否可以打印到终端。所以我尝试添加像

这样的语句
print("message")
println("message")
Log.d(TAG, "message")
Log.i(TAG, "message")

等(另请参阅 ,它提出了这些建议,似乎出于不同的目的)。

我的问题:

虽然 "message" 确实 出现在 Android 日志中(使用 adb logcat 查看),并且消息类型与日志记录类型匹配我要求(例如 Log.i 它在日志中显示为 I <service-name>: message),但我还是希望直接在我有 运行 adb 命令的终端中看到它启动服务。

这可能吗?

我从来没有通过调用 Android service via adb, so I resorted to a broadcast receiver 来找到如何做到这一点。

我的 manifest file 现在注册接收者:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.grobber.cliprecv">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".InfoScreenActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver android:name=".MyBroadcastReceiver"  android:exported="true" android:enabled="true">
          <intent-filter>            
            <action android:name="get" />
            <action android:name="set" />
          </intent-filter>
        </receiver>
    </application>
</manifest>

(请注意,该应用现在完全没有服务)。反过来,接收器 class 在 Kotlin 文件中定义如下:

private const val TAG = "MyBroadcastReceiver"

class MyBroadcastReceiver :
    BroadcastReceiver() {    
                             override fun onReceive(context: Context, intent: Intent) {
                                 val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
                                 if (intent.getAction().equals("get")) {
                                     val res: String
                                     if (clipboard.hasPrimaryClip()) {
                                         val cliptext = clipboard.getPrimaryClip()?.getItemAt(0)?.coerceToText(context)?: ""
                                         res=cliptext.toString()
                                     } else {
                                         res = ""
                                     }          
                                     setResultData(res)
                                 } else if (intent.getAction().equals("set")) {
                                     val str: String? = intent.getStringExtra("text")
                                     clipboard.primaryClip = ClipData.newPlainText(TAG, str)    
                                 }                               
                             }
    }

现在,Android 设备连接到计算机并且应用程序 运行 在前台,运行

 adb shell am broadcast -n com.grobber.cliprecv/.MyBroadcastReceiver -a get

将在我的终端中返回剪贴板的内容作为输出的 data 部分:

$ adb shell am broadcast -n com.grobber.cliprecv/.MyBroadcastReceiver -a get
---
Broadcasting: Intent { act=get flg=0x400000 cmp=com.grobber.cliprecv/.MyBroadcastReceiver }
Broadcast completed: result=0, data="<CLIPBOARD CONTENTS>"

参考

该解决方案改编自 this older app,它同样使用广播接收器来 get/set 剪贴板。