Android学习之AIDL添加Service权限

  • Post author:
  • Post category:其他


参考《Android开发艺术探索》,书中提供了两种方法

第一种方法:在onBind中验证

在服务端的AndroidManifest添加自定义权限

<permission android:name="com.example.maxiaolong.aidlserver.ACCESS_BOOK_SERVICE"
        android:description="@string/dangerous_description"
        android:icon="@mipmap/ic_launcher"
        android:protectionLevel="normal"/>

修改Service中的OnBind方法:

public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        int check = checkCallingOrSelfPermission("com.example.maxiaolong.aidlserver.ACCESS_BOOK_SERVICE");
        if(check == PackageManager.PERMISSION_DENIED){
            return null;
        }
        return mbinder;
    }

如果想要绑定到服务中,只需要在它的AndroidManifest配置文件中加入:

<uses-permission android:name="com.example.maxiaolong.aidlserver.ACCESS_BOOK_SERVICE"/>

这种方法只能使用在内部应用绑定服务,如果服务端和客户端是两个工程,则在Service中无法验证客户端的权限,因为onBinde方法不是一个binder调用的,它运行在服务端的UI线程,因此在onBind中只能验证服务端的权限。

第二种方法:在服务端的onTransact中进行验证

可以在服务中直接验证权限,重写IBookManager对象中的onTransact方法,在里面添加权限验证

public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
            int check = checkCallingPermission("com.example.maxiaolong.aidlserver.ACCESS_BOOK_SERVICE");
            if(check == PackageManager.PERMISSION_DENIED){
                return false;
            }
            return super.onTransact(code, data, reply, flags);
        }

注意:这里调用的是checkCallingPermission方法,该方法只能在AIDL时在IPC方法中调用

然后再客户端的AndroidManifest配置文件中加入:

<uses-permission android:name="com.example.maxiaolong.aidlserver.ACCESS_BOOK_SERVICE"/>

还可以用Uid和Pid来验证客户端包名,修改OnTransact方法添加如下内容:

public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
            int check = checkCallingPermission("com.example.maxiaolong.aidlserver.ACCESS_BOOK_SERVICE");
            if(check == PackageManager.PERMISSION_DENIED){
                return false;
            }
            String packageName = null;
            String[] packages = getPackageManager().getPackagesForUid(getCallingUid());
            if(packages != null && packages.length > 0){
                packageName = packages[0];
            }
            if(!packageName.startsWith("com.example.maxiaolong.aidlclient")){
                return false;
            }
            return super.onTransact(code, data, reply, flags);
        }

客户端的包名必须以“com.example.maxiaolong.aidlclient”开始,在该方法中既验证了权限,又验证了包名



版权声明:本文为u011893710原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。