问题点20: Android Bluetooth如何选择文件并选择蓝牙进行发送?
----核心类:BluetoothOppLauncherActivity:其他APP 需要调用BT 发送文件时的入口类,其虽是Activity却没有自身界面,但其会基于当前实际触发别的带界面Activity。目前看到其唯一的调用是在BluetoothManagerService.java的方法updateOppLauncherComponentState中;
具体Tracing flow是:
-->BluetoothOppLauncherActivity被创建,当广播内容为:Intent.ACTION_SEND时,获取需要发送的文件名称;
-->执行到方法sendFileInfo;
-->核心跳转在方法launchDevicePicker中,核心功能在于:如果蓝牙还没打开,先打开蓝牙;如果蓝牙已打开,则跳转到选择蓝牙配对列表画面;
BluetoothOppReceiver中接收了BluetoothDevicePicker.ACTION_DEVICE_SELECTED广播;
-->执行类BluetoothOppManager的方法startTransfer;
在方法内部创建InsertShareInfoThread ,启动线程;
-->执行到InsertShareInfoThread的内部run 方法;
如果是发送单一文件的话,执行方法insertSingleShare;多文件执行insertMultipleShare;
-->当前假设发送的是单一文件,执行方法insertSingleShare;
这里有几个步骤省略;
-->执行类BluetoothOppService中方法insertShare,里面执行BluetoothOppTransfer中start方法;
-->执行类BluetoothOppTransfer中start方法;
这里需要理解的是:OPP的发送基于每次先连接再发送,发送完成再断开的flow;
-->执行方法startConnectSession,这里分两种case处理:
当SDP成功时,需等待广播消息“luetoothDevice.ACTION_SDP_RECORD”后进行
SocketConnectThread创建;
当SDP失败时,则直接进行SocketConnectThread创建;
-->在类的内部线程中执行connectRfcommSocket;
-->(case1)方法connectRfcommSocket中调用的BluetoothSocket的 connect 方法;
-->当连接上时,BluetoothSocket将收到
“BluetoothSocket: waitSocketSignal read 20 bytes signal ret: 20”,
当OPPC 连接上时,出现的log是:“Rfcomm socket connection attempt took”;
其在“btSocket.connect();”后出现,原因是BluetoothSocket的connect是阻塞态,将一直阻塞到收到连接结果;
-->发出内部 Message TRANSPORT_CONNECTED;
-->执行到方法startObexSession中;
-->执行类BluetoothOppObexClientSession的方法start,里面将启动内部线程ClientThread;
-->在内部线程中执行类BluetoothOppObexClientSession的方法connect
-->执行方法“private void connect(int numShares)”,对应的log是“Create ClientSession with transport”;
-->执行类ClientSession的方法connect;其是Obex在framework层的接口类;
Attention,需理解的是:当执行到此,并不是说OPP才开始连接,而是在此基于底层已经连接的rf 或l2cap channel,发出“ObexHelper.OBEX_OPCODE_CONNECT”command;
-->此时通过方法sendRequest发出Obex command ,其内部通过socket实现;
后续的具体发送在类BluetoothOppObexClientSession的方法doSend 和sendFile中;