关于安卓中android:exported="true",以及AIDL跨进程访问时,绑定服务遇到的SecurityException: Not allowed to bind to service I...

在AIDL中我们经常会遇到绑定外部服务的时候。现在项目用到管理蓝牙的服务,需要手机所有应用全部用一个service。aidl便给与了很大的方便。


先总结一下:cilent绑定服务时通过自己项目中的 .aidl找到 对应实现service中的 .aidl。然后拿到对应service的stub实体,调用对应service的stub中的实现方法。


1、创建  .aidl 文件,并在需要调用的应用中也添加(所有文件下的包名,内容必须一致,否则会报错)。


package com.example.aidlservice.aidl; 
interface IPerson { 
        String greet(String someone); 



此时在gen目录下会自动生成aidl对应的java文件:



期中Stub需要留意。接下来会用到


2、在service中实现stub

IPerson.Stub stub = new IPerson.Stub() {
        @Override
        public String greet(String someone) throws RemoteException {
            Log.i(TAG, "greet:"+someone);

            return " greet!!!"+someone ;
        }
    };

并在onbind时返回:

@Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, "onBind");
        return stub;
    }
   
    @Override
    public boolean onUnbind(Intent intent) {
        Log.i(TAG, "onUnbind");
        return true;
    }


3、接下里在minifest中声明:



4、cilent 客户端使用:先实现  ServiceConnection方法。复写 onServiceConnected

private IPerson person;
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
              Log.i("ServiceConnection", "DDD   onServiceDisconnected() called"); 
           
        }
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
           
            Log.i("ServiceConnection", "CCC   onServiceConnected() called"); 
            person = IPerson.Stub.asInterface(service);
           
        }
    };

5、绑定及调用

case R.id.bt1:
            Log.i(TAG, "绑定!BT1  "); 
             Intent intent = new Intent("android.intent.action.AIDLService"); 
             bindService(intent, conn, Context.BIND_AUTO_CREATE); 
           
            break;
        case R.id.bt2:
            Log.i(TAG, "服务!BT2  "); 
            try {
                String putin = "hahaha";
                String   result = person.greet(putin);               
                Log.i(TAG, "绑定!输入:"+putin+"   结果:"+result);                 
            } catch (RemoteException e) {
                e.printStackTrace();
            }           
            break;





6、如果多个应用全部都实现了service。那么调用时会调用第一个安装过的。第一个卸载后会调用第二个安装的,以此类推。

接下来我们今天想分享的是,SecurityException: Not allowed to bind to service Intent崩溃错误。
我们在使用:

                                Intent intent = new Intent();
ComponentName mComponentName= new ComponentName(packageName,serviceName);
intent.setComponent(mComponentName);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

时,安卓只是正常绑定,不应该绑定导致 Not allowed to bind to service Intent,更甚至崩溃。
结果排查了很久 ,发现service在静态注册时,忽视了一个重要的属性:android:exported="true"
这个属性默认为false。false时,会禁止外部其它应用 绑定或者启动此服务。
因此问题很明显了,加上这句android:exported="true",解决问题。(建议绑定service和启动service时,都得try 一下:SecurityException异常)

对于android:exported="true"的定义是:android:exported 是Android中的四大组件 Activity,Service,Provider,Receiver 四大组件中都会有的一个属性。

总体来说它的主要作用是:是否支持其它应用调用当前组件。 
默认值:如果包含有intent-filter 默认值为true; 没有intent-filter默认值为false。

那么你在遇到此类崩溃时,是否是忘记加了这条属性了呢? 呲牙 

 

 

转载于:https://www.cnblogs.com/haihu2/p/8194632.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值