蓝牙启动:
SystemServer.java
bluetooth = new BluetoothManagerService(context); ServiceManager.addService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, bluetooth);
在 BluetoothManagerService的构造函数里,调用getNameAndAddress(),在这个BluetoothHandler里,绑定了 IBluetooth.class.getName,通过aidl启动了远程 AdapterService服务, AdapterService.java里的静态块实现蓝牙的启动(上电?)
static {
classInitNative();
}
InitNativie
使能(Enable):
BluetoothEnabler.java / SettingsAppWidgetProvider.java (setBluetoothEnabled)
LocalBluetoothAdapter (setBluetoothEnabled)
BluetoothAdapter.java (enable)
IBluetooth.aidl (enable)
AdapterService.java (enable)
AdapterService.java (enableNative)
apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp(enableNative)
externel/bluedroid/btif/src/bluetooth.c (btif_enable_bluetooth)
扫描:
BluetoothSettings.java
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_ID_SCAN:
if (mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON) {
startScanning();
}
return true;
case MENU_ID_RENAME_DEVICE:
new BluetoothNameDialogFragment().show(
getFragmentManager(), "rename device");
return true;
case MENU_ID_VISIBILITY_TIMEOUT:
new BluetoothVisibilityTimeoutFragment().show(
getFragmentManager(), "visibility timeout");
return true;
case MENU_ID_SHOW_RECEIVED:
Intent intent = new Intent(BTOPP_ACTION_OPEN_RECEIVED_FILES);
getActivity().sendBroadcast(intent);
return true;
}
return super.onOptionsItemSelected(item);
}
DeviceListPreferenceFragment.java (startScanning)
LocalBluetoothAdapter (startScanning)
BluetoothAdapter.java (startDiscovery)
IBluetooth.aidl (startDiscovery)
apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java (startDiscovery)
AdapterService.java (startDiscoveryNative)
apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp(startDiscoveryNative)
externel/bluedroid/btif/src/bluetooth.c (static const bt_interface_t bluetoothInterface)
externel/bluedroid/btif/src/btif_dm.c(btif_bm_start_discovery)
下往上调用:
Bluetooth.c
com_android_bluetooth_btservice_AdapterService.cpp
JniCallbacks.java
RemoteDevices.java / AdapterProperties.java / AdapterState.java / BondStateMachine.java
底层调用JniCallbacks.java,分别调用到RemoteDevices.java / AdapterProperties.java / AdapterState.java / BondStateMachine.java里。
RemoteDevices.java通过 Intent,最终发一个广播,如发送BluetoothDevice.ACTION_FOUND这个广播被BluetoothEventManager.java里的广播收到,根据这个广播,然后分发给具体的 handler去处理。
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Handler handler = mHandlerMap.get(action);
if (handler != null) {
handler.onReceive(context, intent, device);
}
}
};
这里的 handler分发如下:
// Bluetooth on/off broadcasts
addHandler(BluetoothAdapter.ACTION_STATE_CHANGED, new AdapterStateChangedHandler());
// Discovery broadcasts
addHandler(BluetoothAdapter.ACTION_DISCOVERY_STARTED, new ScanningStateChangedHandler(true));
addHandler(BluetoothAdapter.ACTION_DISCOVERY_FINISHED, new ScanningStateChangedHandler(false));
addHandler(BluetoothDevice.ACTION_FOUND, new DeviceFoundHandler());
addHandler(BluetoothDevice.ACTION_DISAPPEARED, new DeviceDisappearedHandler());
addHandler(BluetoothDevice.ACTION_NAME_CHANGED, new NameChangedHandler());
// Pairing broadcasts
addHandler(BluetoothDevice.ACTION_BOND_STATE_CHANGED, new BondStateChangedHandler());
addHandler(BluetoothDevice.ACTION_PAIRING_CANCEL, new PairingCancelHandler());
// Fine-grained state broadcasts
addHandler(BluetoothDevice.ACTION_CLASS_CHANGED, new ClassChangedHandler());
addHandler(BluetoothDevice.ACTION_UUID, new UuidChangedHandler());
// Dock event broadcasts
addHandler(Intent.ACTION_DOCK_EVENT, new DockEventHandler());
界面的更新:
通过回调 BluetoothSettings.java里的回调函数(BluetoothSettings extends DeviceListPreferenceFragment implements BluetoothCallback)
onBluetoothStateChanged
onDeviceBondStateChanged
在这两个函数里,updateContent,来刷新界面上显示的设备。在updateContent里,调用addDeviceCategory对更新当前的界面节点。
private void addDeviceCategory(PreferenceGroup preferenceGroup, int titleId,
BluetoothDeviceFilter.Filter filter) {
preferenceGroup.setTitle(titleId);
getPreferenceScreen().addPreference(preferenceGroup);
setFilter(filter);
setDeviceListGroup(preferenceGroup);
addCachedDevices();
preferenceGroup.setEnabled(true);
}
所有C/C++往JAVA调用的文件:
packages/apps/Bluetooth/jni/com_android_bluetooth_hdp.cpp
packages/apps/Bluetooth/jni/com_android_bluetooth_a2dp.cpp
packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp
packages/apps/Bluetooth/jni/com_android_bluetooth_pan.cpp
packages/apps/Bluetooth/jni/com_android_bluetooth_hfp.cpp
packages/apps/Bluetooth/jni/com_android_bluetooth_hid.cpp
OPP:
opp发送文件详细过程
通过其他应用“分享”时,进入BluetoothOppLauncherActivity,这个Activity无界面,这个Activity会处理文件类型, URI,并将相关信息存起来:
if (stream != null && type != null) {
Log.v(TAG, "Get ACTION_SEND intent: Uri = " + stream + "; mimetype = " + type);
// Save type/stream, will be used when adding transfer
// session to DB.
BluetoothOppManager.getInstance(this).saveSendingFileInfo(type,
stream.toString(), false);
}
如果是飞行模式,则不允许进行文件传输,相关错误信息在 BluetoothOppBtErrorActivity界面显示。
if (!isBluetoothAllowed()) {
Intent in = new Intent(this, BluetoothOppBtErrorActivity.class);
in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
in.putExtra("title", this.getString(R.string.airplane_error_title));
in.putExtra("content", this.getString(R.string.airplane_error_msg));
this.startActivity(in);
finish();
return;
}
Ø 设备如果蓝牙还未enable,则需要先BluetoothOppBtEnableActivity界面。执行BluetoothOppBtEnableActivity的onClick方法,并在BluetoothOppBtEnablingActivity显示传输文件的进度;如果蓝牙已经enable了,则进入DeviceListPreferenceFragment(DevicePickerFragment),选择将要的设备;选完设备后,会发出一个BluetoothDevicePicker.ACTION_DEVICE_SELECTED的广播,广播会被BluetoothOppReceiver接收到,提示“正在向XXX发送XX文件”。同时执行startTransfer,会通过BluetoothOppManager里的InsertShareInfoThread线程,存储传送的文件的相关信息(URI,类型,时间,destination等)
Ø 在BluetoothOppProvider里的insert 方法中,会启动BluetoothOppService,后面就开始了文件的传输。
|->context.startService(new Intent(context, BluetoothOppService.class));
|->onStartCommand()
|-> updateFromProvider()
|->UpdateThread.start()
|->insertShare()
|->BluetoothOppTransfer.start()
Ø SD卡重新挂载时,MediaProvider会自动扫描SD卡上的媒体来更新媒体数据库的。谁更新了SD卡上的媒体,谁通知MediaProvider把更新了的媒体同步到MediaProvider的媒体数据库中。有两种方式,恰好蓝牙和下载器分别使用了这两种方式,这里就以它们两个程序来说明一下。
MediaScannerConnection,蓝牙传输文件时就是用的这种方式,每当接收到新的媒体文件,都会通过这种方式告诉MediaProvider同步媒体数据库。
l 建立连接
mConnection = new MediaScannerConnection(mContext, this);
因为建立连接是一个异步过程,所以,在建立连接时需要加入一个监听器。这样,连接建立后就可以得到通知,并进行下一步。
l 更新媒体数据库
mConnection.scanFile(mInfo.mFilename, mInfo.mMimetype);
这也是一个异步过程,更新完毕后,监听器中得到通知,并断开连接。
l 断开连接
mConnection.disconnect();
文件发送调用关系:
|――BluetoothOppProvider
|――BluetoothOppService
|――BluetoothOppTransfer
|――OBEX
BluetoothOppTransfer start()
|―>start()
|―outbound―>startConnectSession
|―handler发出RFCOMM_CONNECTED消息―>startObexSession
|―inbound―>startObexSession
|―>mSession.start(mSessionHandler)
|―>BluetoothOppObexClientSession.start()
|―>doSend()
|―发MSG_SHARE_COMPLETE给EventHandler―>mSession.stop()
接收文件流程:
1. 蓝牙开启后,蓝牙状态即是 BluetoothAdapter.STATE_ON
2. BluetoothOppService 里 Receiver接收到BluetoothAdapter.STATE_ON后,启动startSocketListener()。
3. 在mSocketListener.start(mHandler) 里通过handler 发送一个MSG_INCOMING_BTOPP_CONNECTION消息
4. 这个消息在BluetoothOppService的handler处理后创建一个 createServerSession(transport);
5. createServerSession 里 mServerSession.preStart(),进而new obexSesstion,接收文件
OPP接收文件进度的更新:
BluetoothOppService.java里调用mNotifier.updateNotification(),通过Handlder来实现没100ms来更新一次UI,更新UI是另起的一个线程
NotificationUpdateThread,在该线程里更新进度updateActiveNotification