如何获取试图从onBind函数绑定我的服务的应用程序包名称或UID?

umi*_*n84 19 android

我在应用程序中有一个服务,我可以从不同的应用程序中获得此服务.当尝试绑定此服务的应用程序时,我想知道哪个应用程序试图在onBind函数中绑定我的服务,但我无法在onBind函数中获取此应用程序的包名称或UID.

是否可以获取试图在onBind函数中绑定我的服务的应用程序名称或UID?

Dur*_*amy 22

您可以使用以下内容来确定调用应用程序.

 String callingApp = context.getPackageManager().getNameForUid(Binder.getCallingUid());
Run Code Online (Sandbox Code Playgroud)

重要的是要注意JavaDoc,getCallingUid()其中说:

返回分配给发送当前正在处理的事务的进程的Linux uid.此uid可与更高级别的系统服务一起使用,以确定其身份并检查权限.如果当前线程当前没有执行传入事务,则返回其自己的uid.

  • 如果我在onBind函数中调用你提供的代码,它会返回apk的packageName的名称,该服务保留在.我的意思是它不返回另一个apk的调用者packageName,它只返回服务所在的相同packageName. (5认同)
  • 从Android文档中,public static final int getCallingUid()返回分配给发送当前正在处理的事务的进程的用户的ID.此uid可与更高级别的系统服务一起使用,以确定其身份并检查权限.如果当前线程当前没有执行传入事务,则返回其自己的uid. (2认同)
  • 关于此答案的两个评论都是正确的-但是,如果您在AIDL文件公开的方法中调用此方法,则它似乎可以正确报告。对我来说是一个非常有用的答案。 (2认同)

小智 5

你不能这样做。

onBind() 是从 Android 的“生命周期管理器”(组成一个有用的名称)调用的,并且只会为每个 Intent 调用一次(因此它可以了解应该为该 Intent 返回哪个 Binder)。

然后对您的服务的调用通过该 Binder 传入,您可以在这些方法中的任何一种中执行 Binder.getCallingUid()。


cod*_*zjx 5

接受的答案不太正确!为什么?如果两个或多个应用程序使用相同的android:sharedUserId,该方法Binder.getCallingUid()将返回相同的uidgetPackageManager().getNameForUid(uid)返回相同的字符串,看起来像:com.codezjx.demo:10058,但不是包名!

正确的方法是使用pid

int pid = Binder.getCallingPid();
Run Code Online (Sandbox Code Playgroud)

然后通过 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;
}
Run Code Online (Sandbox Code Playgroud)

警告:使用方法时Binder.getCallingPid(),如果当前线程当前未执行传入事务,则返回其自己的 pid。这意味着您需要在 AIDL 公开的接口方法中调用此方法。

  • 这不适用于最近的 Android 版本。getRunningAppProcesses() 已更改为仅返回调用进程。更多信息:http://stackoverflow.com/questions/30619349/android-5-1-1-and-above-getrunningappprocesses-returns-my-application-packag (2认同)

ABS*_*ABS 5

上面接受的答案对我不起作用。但是一个小的修改就成功了。这对于基于Messenger的通信非常有效。

public class BoundService extends Service {

    public static final int TEST = 100;
    private final Messenger messenger = new Messenger(new MessageHandler());

    class MessageHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {

            String callerId = getApplicationContext().getPackageManager().getNameForUid(msg.sendingUid);
            Toast.makeText(getApplicationContext(), "Calling App: " + callerId, Toast.LENGTH_SHORT).show();

            switch (msg.what) {
                case TEST:
                    Log.e("BoundService", "Test message successfully received.")
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return messenger.getBinder();
    }
}
Run Code Online (Sandbox Code Playgroud)

从上面的答案,你只需要从Binder.getCallingUid()改为msg.sendingUid