问题
I am exposing some API through AIDL mechanism. Clients need to bind to the AIDL and call methods synchronously. Is there a way I can retrieve the client's Java package name?
For example, if I expose a method boolean isFooAvailable()
as AIDL API, from within the implementation of isFooAvalable, can I determine the Java package name of the app that binds to the AIDL service?
回答1:
Yes, you can find out the package name from within the implementation as follows :
IAidl.Stub mBinder = new IAidl.Stub() {
@Override
public boolean isFooAvailable() throws RemoteException {
String pkgName = "";
int pid = Binder.getCallingPid();
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> processes = am.getRunningAppProcesses();
for (ActivityManager.RunningAppProcessInfo proc : processes) {
if (proc.pid == pid) {
pkgName = proc.processName;
}
}
// package name of calling application package
Log.e("Package Name", pkgName);
return false;
}
}
Finding package name through PID is the best approach compared to UID.
回答2:
Expanding on the comment given by CommonsWare, inside your Service
you can use
PackageManager packageManager = context.getPackageManager();
String callingName = packageManager.getNameForUid(Binder.getCallingUid());
If you're trying to restrict access to of callers you should also check the certificates of the calling app.
PackageInfo callingPackageInfo = packageManager
.getPackageInfo(callingPackage, PackageManager.GET_SIGNATURES);
// Make sure to check there is only one signature, or you may run into a security
// vulnerability: https://androidvulnerabilities.org/vulnerabilities/Fake_ID
verify(callingPackageInfo.signatures);
来源:https://stackoverflow.com/questions/32208237/retrieving-java-package-name-of-aidl-consumer