android的蓝牙从哪里打开?那里就是我们的入手点;但是我比较喜欢完整来一遍,怎么是不是很任性?
在settings下 package/app/settings/src/com/android/settings/settings.java
有个蓝牙开关,看到这个开关,是不是忍不住想点它?去吧,孩子,点它看看会发生什么事?
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter(); if (btAdapter!=null && !btAdapter.isEnabled()) { btAdapter.enable(); }
点开关之后调用frameworksbase\core\java\android\bluetooth\BluetoothAdaper.java
public final class BluetoothAdapter { private final IBluetoothManager mManagerService;//这个是aidl文件保存蓝牙适配器的一个proxy private IBluetooth mService;//这个实例做什么呢? public boolean enable() { if (isEnabled() == true){ if (DBG) Log.d(TAG, "enable(): BT is already enabled..!"); return true; } try { return mManagerService.enable(); } catch (RemoteException e) {Log.e(TAG, "", e);} return false; } public boolean isEnabled() { try { synchronized(mManagerCallback) { if (mService != null) return mService.isEnabled(); } } catch (RemoteException e) {Log.e(TAG, "", e);} return false; } }
public static synchronized BluetoothAdapter getDefaultAdapter() {
if (sAdapter == null) {
IBinder b = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE);//获得servicemanager的一个service
if (b != null) {
IBluetoothManager managerService = IBluetoothManager.Stub.asInterface(b);//转换成IBluetoothManager的接口作为bluetooth_Mangager服务的一个代理
sAdapter = new BluetoothAdapter(managerService);
} else {
Log.e(TAG, "Bluetooth binder is null");
}
}
return sAdapter;
}
BluetoothAdapter(IBluetoothManager managerService) {
if (managerService == null) {
throw new IllegalArgumentException("bluetooth manager service is null");
}
try {
mService = managerService.registerAdapter(mManagerCallback);//初始化我们的IBluetooth
} catch (RemoteException e) {Log.e(TAG, "", e);}
mManagerService = managerService;
mLeScanClients = new HashMap<LeScanCallback, ScanCallback>();
}
bluetooth_manager服务是什么鬼,怎么突然给我来一下?幸亏哥早有打算,来我们返回第一章看systemserver里面做了什么
bluetooth = new BluetoothManagerService(context); ServiceManager.addService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, bluetooth);
再来看BluetoothManagerService
public boolean enable() { if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) { Log.w(TAG,"enable(): not allowed for non-active and non system user"); return false; } mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); if (DBG) { Log.d(TAG,"enable(): mBluetooth =" + mBluetooth + " mBinding = " + mBinding); } //这上面是权限的东西,从frameworks/base/data/etc/permission.xml里面读取吧 synchronized(mReceiver) { mQuietEnableExternal = false; mEnableExternal = true; // waive WRITE_SECURE_SETTINGS permission check long callingIdentity = Binder.clearCallingIdentity(); persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH); Binder.restoreCallingIdentity(callingIdentity); sendEnableMsg(false); } return true; } private void sendEnableMsg(boolean quietMode) { mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE, quietMode ? 1 : 0, 0)); } private class BluetoothHandler extends Handler { public BluetoothHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { if (DBG) Log.d (TAG, "Message: " + msg.what); switch (msg.what) { case MESSAGE_ENABLE: if (DBG) { Log.d(TAG, "MESSAGE_ENABLE: mBluetooth = " + mBluetooth); } mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE); mEnable = true; handleEnable(msg.arg1 == 1); break; } } }
private void handleEnable(boolean quietMode) {
mQuietEnable = quietMode;
synchronized(mConnection) {
if ((mBluetooth == null) && (!mBinding)) {
//Start bind timeout and bind
Message timeoutMsg=mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS);
mConnection.setGetNameAddressOnly(false);
Intent i = new Intent(IBluetooth.class.getName());
if (!doBind(i, mConnection,Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
UserHandle.CURRENT)) {
mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
} else {
mBinding = true;
}
} else if (mBluetooth != null) {
if (mConnection.isGetNameAddressOnly()) {
// if GetNameAddressOnly is set, we can clear this flag,
// so the service won‘t be unbind
// after name and address are saved
mConnection.setGetNameAddressOnly(false);
//Register callback object
try {
mBluetooth.registerCallback(mBluetoothCallback);
} catch (RemoteException re) {
Log.e(TAG, "Unable to register BluetoothCallback",re);
}
//Inform BluetoothAdapter instances that service is up
sendBluetoothServiceUpCallback();
}
//Enable bluetooth
try {
if (!mQuietEnable) {
if(!mBluetooth.enable()) {//这里又调回app
Log.e(TAG,"IBluetooth.enable() returned false");
}
}
else {
if(!mBluetooth.enableNoAutoConnect()) {
Log.e(TAG,"IBluetooth.enableNoAutoConnect() returned false");
}
}
} catch (RemoteException e) {
Log.e(TAG,"Unable to call enable()",e);
}
}
}
}
贴了一大推代码,我讲了什么?我讲的mService的嘛,现在mService出来的,这个mService可别小瞧哦,其他api调用可都靠它直接完成,别忽略这点,获得service我们接着就bindservice,bindservice是在bluetoothmanagerservice里面处理的,来看一下怎么处理的
case MESSAGE_GET_NAME_AND_ADDRESS: { if (DBG) Log.d(TAG,"MESSAGE_GET_NAME_AND_ADDRESS"); synchronized(mConnection) { //Start bind request if ((mBluetooth == null) && (!mBinding)) { if (DBG) Log.d(TAG, "Binding to service to get name and address"); mConnection.setGetNameAddressOnly(true); //Start bind timeout and bind Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND); mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS); Intent i = new Intent(IBluetooth.class.getName()); if (!doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.CURRENT)) { mHandler.removeMessages(MESSAGE_TIMEOUT_BIND); } else { mBinding = true; } } else { Message saveMsg= mHandler.obtainMessage(MESSAGE_SAVE_NAME_AND_ADDRESS); saveMsg.arg1 = 0; if (mBluetooth != null) { mHandler.sendMessage(saveMsg); } else { // if enable is also called to bind the service // wait for MESSAGE_BLUETOOTH_SERVICE_CONNECTED mHandler.sendMessageDelayed(saveMsg, TIMEOUT_SAVE_MS); } } } break; }
public synchronized boolean enable(boolean quietMode) {
enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH ADMIN permission");
debugLog("enable() - Enable called with quiet mode status = " + mQuietmode);
mQuietmode = quietMode;
Message m =
mAdapterStateMachine.obtainMessage(AdapterState.USER_TURN_ON);
mAdapterStateMachine.sendMessage(m);
return true;
}
原文:http://www.cnblogs.com/alanz/p/6439720.html