17

API レベル 11 より前では、次のserviceプログラムを使用してクリップボードの内容を設定できました。adb shell

service call SERVICE CODE [i32 INT | s16 STR] ...
Options:
    i32: Write the integer INT into the send parcel.
    s16: Write the UTF-16 string STR into the send parcel.

メソッドを定義するための 3 つの整数コードがありました。

1 TRANSACTION_getClipboardText
2 TRANSACTION_setClipboardText
3 TRANSACTION_hasClipboardText

たとえば、このコマンド

$ adb shell service call clipboard 2 i32 1 i32 1 s16 "Hello Android!"

クリップボードの内容を に設定し"Hello Android!"ます。API レベル 11 の時点で、リストされているメソッドは非推奨になり、新しいメソッドは引数としてClipDataを取ります。を介してクリップボードのコンテンツをどのように設定しますadb shellか?

4

2 に答える 2

10

ここで 2 つの異なる質問をしました。サービスコールは API 関数とは関係ありません。

Android は一般に、API を非推奨としてマークすることに積極的です。この場合、より多くの機能を備えた新しい機能があることを意味するだけです。getText()hasText()、およびの機能setText()は引き続き存在し、これらの関数は引き続き機能しますが、新しい関数の簡単なラッパーとして実装されるようになりました。

サービス呼び出しに関する限り、これらは内部実装の詳細であり、お気付きのように、Android バージョン間で動作することが保証されていません。Androidソース コードを詳しく調べると、次のトランザクションが現在定義されていることがわかります。

TRANSACTION_setPrimaryClip = 1
TRANSACTION_getPrimaryClip = 2
TRANSACTION_getPrimaryClipDescription = 3
TRANSACTION_hasPrimaryClip = 4
TRANSACTION_addPrimaryClipChangedListener = 5
TRANSACTION_removePrimaryClipChangedListener = 6
TRANSACTION_hasClipboardText = 7

ソース コードには、これらのトランザクションに必要なパラメータも示されています。残念ながら、TRANSACTION_setPrimaryClip には が必要ClipDataです。これは i32 でも s16 でもなく、したがって と互換性がありませんservice call。しかし、それよりも大きな問題があります。これらのトランザクションには、パラメーターとして呼び出し元のパッケージ名が必要であり、クリップボード サービスは、指定されたパッケージ名が呼び出し元の uid と一致することを検証します。adb シェルを使用する場合、呼び出し元の uid は UID_ROOT または UID_SHELL のいずれかであり、どちらもパッケージを所有していないため、そのチェックに合格する方法はありません。簡単に言えば、新しいクリップボード サービスはこの方法では使用できません。

このすべてについて何ができますか?コマンドラインからクリップボードを操作する独自のサービスを作成し、デバイスにインストールできます。を拡張する方法があるかどうかはわかりませんが、適切な代替品としてservice call使用できます。am startserviceそのカスタム クリップボード サービスを作成してインストールした場合は、次のように呼び出すことができます。

am startservice -a MySetClipboard -e text "clipboard text"

このサービスを実装するコードは次のようになります。

public MyService extends Service {
    public int onStartCommand(Intent intent, int flags, int startId) {
        String text = intent.getStringExtra("text");
        ClipboardManager.setText(text);
        stopSelf();
        return START_NOT_STICKY;
    }
}

MySetClipboardサービスには、インテント アクションを処理できることを宣言するインテント フィルターが必要です。

于 2013-09-03T00:52:49.893 に答える