Issue
I would like an Android service (written in Kotlin) run in a Linux terminal to print out a message in the terminal it's running in. The main Kotlin class is in this file (I cloned that repo).
I'll want to modify that in various ways, but for now I just want to see if it's possible to print to the terminal. So I have tried adding statements like
print("message")
println("message")
Log.d(TAG, "message")
Log.i(TAG, "message")
etc. (see also this other SO question which suggested these, seemingly for a somewhat different purpose).
My problem:
While "message"
does appear in the Android
logs (viewed with adb logcat
), and the message types match the type of logging I asked for (e.g. for Log.i
it appears in the log as I <service-name>: message
), I would nevertheless like to see it directly in the terminal where I have run the adb
command that starts the service.
Is this possible?
Solution
I never did find out how to do this by calling an Android service via adb
, so I resorted to a broadcast receiver instead.
My manifest file now registers the receiver:
<?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>
(note that there's now no service at all for the app). In turn, the receiver class is defined in a Kotlin
file as follows:
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)
}
}
}
Now, with the Android device connected to a computer and the app running in the foreground, running
adb shell am broadcast -n com.grobber.cliprecv/.MyBroadcastReceiver -a get
will give me back the contents of the clipboard in my terminal as the data
section of the output:
$ 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>"
Reference
The solution was adapted from this older app that similarly uses a broadcast receiver to get/set the clipboard.
Answered By - grobber
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.