アプリケーションにサービスがあり、さまざまなアプリケーションからこのサービスにアクセスできます。また、アプリケーションがこのサービスをバインドしようとすると、どのアプリケーションが onBind 関数でサービスをバインドしようとしているのか知りたいのですが、onBind 関数でこのアプリケーションのパッケージ名または UID を取得できません。
onBind 関数でサービスをバインドしようとしているアプリケーション名または UID を取得することはできますか?
アプリケーションにサービスがあり、さまざまなアプリケーションからこのサービスにアクセスできます。また、アプリケーションがこのサービスをバインドしようとすると、どのアプリケーションが onBind 関数でサービスをバインドしようとしているのか知りたいのですが、onBind 関数でこのアプリケーションのパッケージ名または UID を取得できません。
onBind 関数でサービスをバインドしようとしているアプリケーション名または UID を取得することはできますか?
以下を使用して、呼び出し元のアプリケーションを判別できます。
String callingApp = context.getPackageManager().getNameForUid(Binder.getCallingUid());
JavaDoc にgetCallingUid()
次のように記載されていることに注意することが重要です。
処理中の現在のトランザクションを送信したプロセスに割り当てられた Linux uid を返します。この uid を高レベルのシステム サービスで使用して、その ID を特定し、アクセス許可を確認できます。現在のスレッドが着信トランザクションを現在実行していない場合は、独自の uid が返されます。
これはできません。
onBind() は、Android の「ライフサイクル マネージャー」から呼び出され (わかりやすい名前を構成します)、インテントごとに 1 回だけ呼び出されます (そのため、そのインテントに対してどの Binder を返す必要があるかを学習できます)。
サービスへの呼び出しはその Binder を介して行われ、これらのメソッドのいずれかで Binder.getCallingUid() を実行できます。
受け入れられた答えは完全に正しくありませんでした! なんで?2 つ以上のアプリケーションが同じ を使用する場合android:sharedUserId
、メソッドBinder.getCallingUid()
は同じuidをgetPackageManager().getNameForUid(uid)
返し、同じ文字列を返します。これはcom.codezjx.demo:10058のようになりますが、パッケージ名ではありません!
正しい方法はpidを使用することです:
int pid = Binder.getCallingPid();
そして、 pid を使用して でパッケージ名を取得しますActivityManager
。各プロセスは複数のパッケージを保持できるため、次のようになります。
private String[] getPackageNames(Context context, int pid) {
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningAppProcessInfo> infos = am.getRunningAppProcesses();
if (infos != null && infos.size() > 0) {
for(RunningAppProcessInfo info : infos) {
if(info.pid == pid) {
return info.pkgList;
}
}
}
return null;
}
警告: methodBinder.getCallingPid()
を使用していて、現在のスレッドが着信トランザクションを現在実行していない場合は、独自の pid が返されます。つまり、AIDL 公開インターフェイス メソッドでこのメソッドを呼び出す必要があります。