版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/sxj159753/article/details/86361445
显示列表
packages/apps/Settings/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java
DeviceListPreferenceFragment
初始化操作
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLocalManager = Utils.getLocalBtManager(getActivity());
if (mLocalManager == null) {
Log.e(TAG, "Bluetooth is not supported on this device");
return;
}
mLocalAdapter = mLocalManager.getBluetoothAdapter();
//1.加载列表,父类抽象,子类(BluetoothSettings)实现
addPreferencesForActivity();
mDeviceListGroup = (PreferenceCategory) findPreference(KEY_BT_DEVICE_LIST);
}
看一下1
父类抽象,子类(BluetoothSettings)实现
code/8953_7120/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothSettings.java
@Override
void addPreferencesForActivity() {
addPreferencesFromResource(R.xml.bluetooth_settings);
mPairedDevicesCategory = new PreferenceCategory(getPrefContext());
mPairedDevicesCategory.setKey(KEY_PAIRED_DEVICES);
mPairedDevicesCategory.setOrder(1);
getPreferenceScreen().addPreference(mPairedDevicesCategory);
mAvailableDevicesCategory = new BluetoothProgressCategory(getActivity());
mAvailableDevicesCategory.setSelectable(false);
mAvailableDevicesCategory.setOrder(2);
getPreferenceScreen().addPreference(mAvailableDevicesCategory);
mMyDevicePreference = new Preference(getPrefContext());
mMyDevicePreference.setSelectable(false);
mMyDevicePreference.setOrder(3);
getPreferenceScreen().addPreference(mMyDevicePreference);
setHasOptionsMenu(true);
}
点击选项列表配对
/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothSettings.java
private final View.OnClickListener mDeviceProfilesListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
// User clicked on advanced options icon for a device in the list
if (!(v.getTag() instanceof CachedBluetoothDevice)) {
Log.w(TAG, "onClick() called for other View: " + v);
return;
}
final CachedBluetoothDevice device = (CachedBluetoothDevice) v.getTag();
Bundle args = new Bundle();
args.putString(DeviceProfilesSettings.ARG_DEVICE_ADDRESS,
device.getDevice().getAddress());
//2.1
DeviceProfilesSettings profileSettings = new DeviceProfilesSettings();
profileSettings.setArguments(args);
profileSettings.show(getFragmentManager(),
DeviceProfilesSettings.class.getSimpleName());
}
};
https://blog.csdn.net/lwnlwn1/article/details/48023785
2.1 创建对话框
/home/songxijun/code/8953_7120/packages/apps/Settings/src/com/android/settings/bluetooth/DeviceProfilesSettings.java
DeviceProfilesSettings extends DialogFragment
// /8953_7120/packages/apps/Settings/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java
void onDevicePreferenceClick(BluetoothDevicePreference btPreference) {
btPreference.onClicked();
}
进入 btPreference.onClicked();
void onClicked() {
int bondState = mCachedDevice.getBondState();
if (mCachedDevice.isConnected()) {
askDisconnect();
} else if (bondState == BluetoothDevice.BOND_BONDED) {
mCachedDevice.connect(true);
} else if (bondState == BluetoothDevice.BOND_NONE) {
//配对
pair();
}
}
进入pair();
private void pair() {
if (!mCachedDevice.startPairing()) {
Utils.showError(getContext(), mCachedDevice.getName(),
R.string.bluetooth_pairing_error_message);
} else {
final Context context = getContext();
SearchIndexableRaw data = new SearchIndexableRaw(context);
data.className = BluetoothSettings.class.getName();
data.title = mCachedDevice.getName();
data.screenTitle = context.getResources().getString(R.string.bluetooth_settings);
data.iconResId = R.drawable.ic_settings_bluetooth;
data.enabled = true;
Index.getInstance(context).updateFromSearchIndexableData(data);
}
}
mCachedDevice.startPairing()
/frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
public boolean startPairing() {
// Pairing is unreliable while scanning, so cancel discovery
if (mLocalAdapter.isDiscovering()) {
mLocalAdapter.cancelDiscovery();
}
if (!mDevice.createBond()) {
return false;
}
mConnectAfterPairing = true; // auto-connect after pairing
return true;
}
mDevice.createBond()
8953_7120/frameworks/base/core/java/android/bluetooth/BluetoothDevice.java
public boolean createBond() {
if (sService == null) {
Log.e(TAG, "BT not enabled. Cannot create bond to Remote Device");
return false;
}
try {
Log.i(TAG, "createBond() for device " + getAddress() +
" called by pid: " + Process.myPid() +
" tid: " + Process.myTid());
return sService.createBond(this, TRANSPORT_AUTO);
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false;
}
通过aidl调用到package/app目录中
packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java
public boolean createBond(BluetoothDevice device, int transport) {
if (!Utils.checkCallerAllowManagedProfiles(mService)) {
Log.w(TAG, "createBond() - Not allowed for non-active user");
return false;
}
AdapterService service = getService();
if (service == null) return false;
return service.createBond(device, transport, null);
}
service.createBond(device, transport, null);
boolean createBond(BluetoothDevice device, int transport, OobData oobData) {
enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH ADMIN permission");
DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
if (deviceProp != null && deviceProp.getBondState() != BluetoothDevice.BOND_NONE) {
return false;
}
// Multicast: Do not allow bonding while multcast
A2dpService a2dpService = A2dpService.getA2dpService();
if (a2dpService != null &&
a2dpService.isMulticastFeatureEnabled() &&
a2dpService.isMulticastOngoing(null)) {
Log.i(TAG,"A2dp Multicast is ongoing, ignore bonding");
return false;
}
// Pairing is unreliable while scanning, so cancel discovery
// Note, remove this when native stack improves
cancelDiscoveryNative();
Message msg = mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND);
msg.obj = device;
msg.arg1 = transport;
if (oobData != null) {
Bundle oobDataBundle = new Bundle();
oobDataBundle.putParcelable(BondStateMachine.OOBDATA, oobData);
msg.setData(oobDataBundle);
}
mBondStateMachine.sendMessage(msg);
return true;
}
mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND);
这个状态机处理蓝牙适配器状态。
packages/apps/Bluetooth/src/com/android/bluetooth/btservice/BondStateMachine.java
private class StableState extends State {
@Override
public void enter() {
infoLog("StableState(): Entering Off State");
}
@Override
public boolean processMessage(Message msg) {
BluetoothDevice dev = (BluetoothDevice)msg.obj;
switch(msg.what) {
case CREATE_BOND:
OobData oobData = null;
if (msg.getData() != null)
oobData = msg.getData().getParcelable(OOBDATA);
//建立连接
createBond(dev, msg.arg1, oobData, true);
break;
...
}
return true;
}
}
createBond
private boolean createBond(BluetoothDevice dev, int transport, OobData oobData,
boolean transition) {
if(mAdapterService == null) return false;
if (dev.getBondState() == BluetoothDevice.BOND_NONE) {
infoLog("Bond address is:" + dev);
byte[] addr = Utils.getBytesFromAddress(dev.getAddress());
boolean result;
if (oobData != null) {
result = mAdapterService.createBondOutOfBandNative(addr, transport, oobData);
} else {
result = mAdapterService.createBondNative(addr, transport);
}
if (!result) {
sendIntent(dev, BluetoothDevice.BOND_NONE,
BluetoothDevice.UNBOND_REASON_REMOVED);
return false;
} else if (transition) {
transitionTo(mPendingCommandState);
}
return true;
}
return false;
}
result = mAdapterService.createBondNative(addr, transport);
packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp
static jboolean createBondNative(JNIEnv* env, jobject obj, jbyteArray address, jint transport) {
ALOGV("%s:",__FUNCTION__);
jbyte *addr;
jboolean result = JNI_FALSE;
if (!sBluetoothInterface) return result;
addr = env->GetByteArrayElements(address, NULL);
if (addr == NULL) {
jniThrowIOException(env, EINVAL);
return result;
}
int ret = sBluetoothInterface->create_bond((bt_bdaddr_t *)addr, transport);
env->ReleaseByteArrayElements(address, addr, 0);
result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
return result;
}
int ret = sBluetoothInterface->create_bond((bt_bdaddr_t *)addr, transport);
/hardware/libhardware/include/hardware/bluetooth.h
int (*create_bond)(const bt_bdaddr_t *bd_addr, int transport);