如何限制特定包调用绑定服务

时间:2018-02-01 23:04:52

标签: android android-service android-service-binding

我已经编写了一个绑定服务,我希望这个服务只能从特定应用程序调用。我不希望其他应用程序能够拨打此服务。

目前我所知道的选项是:

  1. 使用权限。似乎有3个安全权限,危险,签名和signatureOrSystem。不幸的是,这些权限都不适用于我,因为我不希望用户接受此权限,这两个应用程序都没有相同的签名,这些也不是系统应用程序。
  2. 获取服务绑定或拨打服务时的应用名称。我在stackoverflow here上查找了一种方法。遗憾的是,这对我不起作用,因为它总是返回服务所在的应用ID。
  3. 我还有其他选择,或者我可以使用上述选项进行一些更改以达到所需要求。

    绑定服务代码

    public class SampleCommsService extends Service {
    
        private static Messenger messanger;
    
        @Override
        public IBinder onBind(Intent intent) {
            Log.e("TEST", "package intent: " + intent.getPackage());
            String callingApp = MyApplication.getAppContext().getPackageManager().getNameForUid(Binder.getCallingUid());
            Log.e("TEST", "onBind - package name: " + callingApp);
            return getMyBinder();
        }
    
        private synchronized IBinder getMyBinder() {
            if (messanger == null) {
                messanger = new Messenger(new SettingsProcessor());
            }
            return messanger.getBinder();
        }
    
        class SettingsProcessor extends Handler {
    
            private static final int GET_SETTINGS_REQUEST = 1;
            private static final int UPDATE_SETTINGS_RESPONSE = 2;
            private static final String SETTINGS = "settings";
    
            @Override
            public void handleMessage(Message msg) {
                String callingApp = MyApplication.getAppContext().getPackageManager().getNameForUid(Binder.getCallingUid());
                Log.e("TEST", "handle message - package name: " + callingApp);
    
                switch (msg.what) {
                    case GET_SETTINGS_REQUEST:
                        sendSettingsValue(msg);
                        break;
                    default:
                        super.handleMessage(msg);
                }
            }
    
            private void sendSettingsValue(Message msg) {
                try {
                    Message resp = Message.obtain(null, UPDATE_SETTINGS_RESPONSE);
                    Bundle bundle = new Bundle();
                    bundle.putBoolean(SETTINGS, MyApplication.isSettingsEnabled());
                    resp.setData(bundle);
                    msg.replyTo.send(resp);
                } catch (RemoteException e) {
                    // ignore
                }
            }
        }
    }
    

    调用api时的输出:

    02-01 15:21:03.138 7704-7704/my.service.package E/TEST: package intent: null
    02-01 15:21:03.139 7704-7704/my.service.package E/TEST: onBind - package name: my.service.package
    02-01 15:21:12.429 7704-7704/my.service.package E/TEST: handle message - package name: my.service.package
    

1 个答案:

答案 0 :(得分:2)

好的,我能够根据给定的答案here解决这个问题。链接中给出的答案显然不起作用,但您可以从用于绑定服务的处理程序中获取应用程序ID。

class SettingsProcessor extends Handler {

        @Override
        public void handleMessage(Message msg) {
            String callingApp = MyApplication.getAppContext().getPackageManager().getNameForUid(msg.sendingUid);
            Log.e("TEST", "handle message - package name: " + callingApp);
        }
    }

而不是Binder.getCallingUid(),我使用的是msg.sendingUid,而且对我来说效果很好。