蓝牙流程(aidl)

本文详细介绍了Android的AIDL(Android Interface Definition Language)在服务间通信中的应用,通过实际的C/S框架例子演示了如何在MainActivity中绑定和调用MyService的接口。同时,对比了AIDL与Linux BlueZ的相似之处,展示了如何通过服务启动与绑定实现后台操控。涉及蓝牙AIDL接口和配置,以及Service启动流程。
摘要由CSDN通过智能技术生成

说说aidl

Android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信。
为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用(Remote Procedure Call,RPC)方式来实现。与很多其他的基于RPC的解决方案一样,Android使用一种接口定义语言(Interface Definition Language,IDL)来公开服务的接口。我们知道4个Android应用程序组件中的3个(Activity、BroadcastReceiver和ContentProvider)都可以进行跨进程访问,另外一个Android应用程序组件Service同样可以。因此,可以将这种可以跨进程访问的服务称为AIDL(Android Interface Definition Language)服务。

一个C/S框架,后台跑应用,前端调接口,就像linux Bluez后台跑bluetoothd的proxy org.bluez.xxx,android还是bluez,后台跑应用,前端来操控,类似AMS,am start xxx

自己写个aidl实例试一下

Mainactivity

public class MainActivity extends AppCompatActivity {

    private IMyAidlInterface myAidlInterface;
    private String name1;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent(MainActivity.this,MyService.class);
        startService(intent);
        doBind();
    }



    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            myAidlInterface = IMyAidlInterface.Stub.asInterface(service);
            final TextView oneView=(TextView)findViewById(R.id.textView3);
            if(myAidlInterface != null)
            {
                try {
                    name1 = myAidlInterface.getname();
                    oneView.setText("get interface success");
                }catch (RemoteException e){
                    e.printStackTrace();
                    oneView.setText("get interface fail");
                }

            } else{
                oneView.setText("bind aidl success");
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    private boolean doBind(){
        Intent intent = new Intent(MainActivity.this,MyService.class);
        bindService(intent,conn,0);
        return true;
    }


    public void onbind(View view) {
        final TextView twoView = (TextView) findViewById(R.id.textView4);
        twoView.setText(name1);
    }
}

aidl interface

interface IMyAidlInterface {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);
    void setname(String name);
    String getname();

}

service

public class MyService extends Service {

    public String name = "interface getname print ok";

    Binder mBinder = new IMyAidlInterface.Stub() {
        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

        }

        @Override
        public void setname(String name) throws RemoteException {

        }

        @Override
        public String getname() throws RemoteException {
            return name;
        }
    };

    public MyService() {
    }

    public void onCreate(){

        super.onCreate();

    }
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.

        return mBinder;
    }


    public void setname(String name){


    }

    public String getname(){

        return name;

    }

}

测试效果

按按键可以调用service的接口,可以。

分析

测了一下, 一定要先startService(intent),才能Bind的到,这完全符合后台启动,前端再跑的玩法,就是这个意思,你不启动,接口不会实体化。

蓝牙aidl

framework==>aidl==>JNI==>BTIF==>BTM==>vendor(初始化和download fw)

package/app/Bluetooth的service后台部分,接口就是这个,放到GattService.java上去。 

那framework是谁来Bind,BluetoothManagerService.java,BluetoothManagerService.java是Bind的地方,其它上层java就不说了,都要找它拿接口,拿到aidl上的接口。

 还需要service启动

profile service 后台启动

 调到AdapterService,Adapter再去启动各个service.

 760     @SuppressWarnings("rawtypes")
 761     private void setGattProfileServiceState(Class[] services, int state) {
 762         if (state != BluetoothAdapter.STATE_ON && state != BluetoothAdapter.STATE_OFF) {
 763             Log.w(TAG,"setGattProfileServiceState(): invalid state...Leaving...");
 764             return;
 765         }
 766
 767         int expectedCurrentState= BluetoothAdapter.STATE_OFF;
 768         int pendingState = BluetoothAdapter.STATE_TURNING_ON;
 769
 770         if (state == BluetoothAdapter.STATE_OFF) {
 771             expectedCurrentState= BluetoothAdapter.STATE_ON;
 772             pendingState = BluetoothAdapter.STATE_TURNING_OFF;
 773         }
 774
 775         for (int i=0; i <services.length;i++) {
 776             String serviceName = services[i].getName();
 777             String simpleName = services[i].getSimpleName();
 778
 779             if (simpleName.equals("GattService")) {
 780                 Integer serviceState = mProfileServicesState.get(serviceName);
 781
 782                 if(serviceState != null && serviceState != expectedCurrentState) {
 783                     debugLog("setProfileServiceState() - Unable to "
 784                         + (state == BluetoothAdapter.STATE_OFF ? "start" : "stop" )
 785                         + " service " + serviceName
 786                         + ". Invalid state: " + serviceState);
 787                         continue;
 788                 }
 789                 debugLog("setProfileServiceState() - "
 790                     + (state == BluetoothAdapter.STATE_OFF ? "Stopping" : "Starting")
 791                     + " service " + serviceName);
 792
 793                 mProfileServicesState.put(serviceName,pendingState);
 794                 Intent intent = new Intent(this,services[i]);
 795                 intent.putExtra(EXTRA_ACTION,ACTION_SERVICE_STATE_CHANGED);
 796                 intent.putExtra(BluetoothAdapter.EXTRA_STATE,state);
 797                 startService(intent);
 798                 return;
 799             }
 800         }
 801     }
 802
 803
 804     @SuppressWarnings("rawtypes")
"packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java" 2555 lines --30%--  

 for (int i=0; i <services.length;i++) {

这里面有个for循环,就是一个一个打开service的,最后调用的是startService(intent);

profile service启动配置

Config.java去配置

 是这个config.xml,但是要注意overlay,device会覆盖掉

 最后就是在这里去配置打开运行的,很多时候,有些profile不想跑的时候,可以关闭

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值