如何限制特定包调用绑定服务
How to restrict bound service to be called by particular packages
我写了一个绑定服务,我希望这个服务只能从特定的应用程序调用。我不希望其他应用能够调用此服务。
目前我知道的选项是:
- 使用权限。似乎有 3 个安全许可,dangerous,signature 和 signatureOrSystem。不幸的是,这些权限中的 none 对我有用,因为我不希望用户接受此权限,而且这两个应用程序没有相同的签名,而且这些都不是系统应用程序。
- 在服务绑定或调用服务时获取应用名称。我在 Whosebug here 上查找了执行此操作的方法。不幸的是,这对我不起作用,因为它总是 returns 服务所在的应用程序 ID。
是否有任何其他选项适合我,或者我可以使用上述选项并进行一些更改以达到所需的要求。
绑定服务码
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
好的,我能够根据给定的答案解决这个问题here。 link中给出的答案显然是行不通的,但是你可以从用于绑定服务的Handler中获取app 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);
}
}
我使用的是 msg.sendingUid
而不是 Binder.getCallingUid()
,它对我来说效果很好。
我写了一个绑定服务,我希望这个服务只能从特定的应用程序调用。我不希望其他应用能够调用此服务。
目前我知道的选项是:
- 使用权限。似乎有 3 个安全许可,dangerous,signature 和 signatureOrSystem。不幸的是,这些权限中的 none 对我有用,因为我不希望用户接受此权限,而且这两个应用程序没有相同的签名,而且这些都不是系统应用程序。
- 在服务绑定或调用服务时获取应用名称。我在 Whosebug here 上查找了执行此操作的方法。不幸的是,这对我不起作用,因为它总是 returns 服务所在的应用程序 ID。
是否有任何其他选项适合我,或者我可以使用上述选项并进行一些更改以达到所需的要求。
绑定服务码
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
好的,我能够根据给定的答案解决这个问题here。 link中给出的答案显然是行不通的,但是你可以从用于绑定服务的Handler中获取app 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);
}
}
我使用的是 msg.sendingUid
而不是 Binder.getCallingUid()
,它对我来说效果很好。