packages\apps\Settings\src\com\android\settings\bluetooth\BluetoothPairingDetail.java
@Override
void onDevicePreferenceClick(BluetoothDevicePreference btPreference) {
disableScanning();
super.onDevicePreferenceClick(btPreference);
} packages\apps\Settings\src\com\android\settings\bluetooth\DeviceListPreferenceFragment.java
void onDevicePreferenceClick(BluetoothDevicePreference btPreference) {
btPreference.onClicked();
} packages\apps\Settings\src\com\android\settings\bluetooth\BluetoothDevicePreference.java
void onClicked() {
Context context = getContext();
// 获取连接状态
int bondState = mCachedDevice.getBondState(); final MetricsFeatureProvider metricsFeatureProvider =
FeatureFactory.getFactory(context).getMetricsFeatureProvider();
// 已经连接
if (mCachedDevice.isConnected()) {
// 断开连接
metricsFeatureProvider.action(context,
MetricsEvent.ACTION_SETTINGS_BLUETOOTH_DISCONNECT);
askDisconnect();
// 以前连接过,不需要再配对,直接进行连接
} else if (bondState == BluetoothDevice.BOND_BONDED) {
metricsFeatureProvider.action(context,
MetricsEvent.ACTION_SETTINGS_BLUETOOTH_CONNECT);
mCachedDevice.connect(true);
// 没连接过,进行配对,需要连接的双方都同意之后才能连接
} else if (bondState == BluetoothDevice.BOND_NONE) {
metricsFeatureProvider.action(context,
MetricsEvent.ACTION_SETTINGS_BLUETOOTH_PAIR);
if (!mCachedDevice.hasHumanReadableName()) {
metricsFeatureProvider.action(context,
MetricsEvent.ACTION_SETTINGS_BLUETOOTH_PAIR_DEVICES_WITHOUT_NAMES);
}
pair();
}
} 1. 已经连接过的设备,直接断开
// Show disconnect confirmation dialog for a device.
private void askDisconnect() {
Context context = getContext();
String name = mCachedDevice.getName();
if (TextUtils.isEmpty(name)) {
name = context.getString(R.string.bluetooth_device);
}
String message = context.getString(R.string.bluetooth_disconnect_all_profiles, name);
String title = context.getString(R.string.bluetooth_disconnect_title);
// 对话框的listener
DialogInterface.OnClickListener disconnectListener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mCachedDevice.disconnect();
}
};
// 显示断开对话框
mDisconnectDialog = Utils.showDisconnectDialog(context,
mDisconnectDialog, disconnectListener, title, Html.fromHtml(message));
} 2. 匹配过的设别,进行连接
frameworks\base\packages\SettingsLib\src\com\android\settingslib\bluetooth\CachedBluetoothDevice.java
public void connect(boolean connectAllProfiles) {
// 是否配对过
if (!ensurePaired()) {
return;
} mConnectAttempted = SystemClock.elapsedRealtime();
connectWithoutResettingTimer(connectAllProfiles);
} private void connectWithoutResettingTimer(boolean connectAllProfiles) {
// Try to initialize the profiles if they were not.
if (mProfiles.isEmpty()) {
// if mProfiles is empty, then do not invoke updateProfiles. This causes a race
// condition with carkits during pairing, wherein RemoteDevice.UUIDs have been updated
// from bluetooth stack but ACTION.uuid is not sent yet.
// Eventually ACTION.uuid will be received which shall trigger the connection of the
// various profiles
// If UUIDs are not available yet, connect will be happen
// upon arrival of the ACTION_UUID intent.
Log.d(TAG, "No profiles. Maybe we will connect later");
return;
} // Reset the only-show-one-error-dialog tracking variable
mIsConnectingErrorPossible = true; int preferredProfiles = 0;
for (LocalBluetoothProfile profile : mProfiles) {
// connectAllProfile传进来的是true
if (connectAllProfiles ? profile.isConnectable() : profile.isAutoConnectable()) {
if (profile.isPreferred(mDevice)) {
++preferredProfiles;
connectInt(profile); // 连接对应的profile
}
}
}
if (DEBUG) Log.d(TAG, "Preferred profiles = " + preferredProfiles); if (preferredProfiles == 0) {
connectAutoConnectableProfiles();
}
} private void connectAutoConnectableProfiles() {
if (!ensurePaired()) {
return;
}
// Reset the only-show-one-error-dialog tracking variable
mIsConnectingErrorPossible = true; for (LocalBluetoothProfile profile : mProfiles) {
if (profile.isAutoConnectable()) {
profile.setPreferred(mDevice, true);
connectInt(profile);
}
}
} 3. 没有配对的设备,先进行配对
private void pair() {
if (!mCachedDevice.startPairing()) {
Utils.showError(getContext(), mCachedDevice.getName(),
R.string.bluetooth_pairing_error_message);
}
} 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;
} return true;
} frameworks\base\core\java\android\bluetooth\BluetoothDevice.java
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean createBond() {
final IBluetooth service = sService;
if (service == 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 service.createBond(this, TRANSPORT_AUTO);
} catch (RemoteException e) {
Log.e(TAG, "", e);
}
return false;
} packages\apps\Bluetooth\src\com\android\bluetooth\btservice\AdapterService.java
private static class AdapterServiceBinder extends IBluetooth.Stub {
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); // bond
} // 建立bond
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;
}
// 在多播的时候不要进行bond,不明白这个multicast是什么意思
// 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;
} mRemoteDevices.setBondingInitiatedLocally(Utils.getByteAddress(device)); // Pairing is unreliable while scanning, so cancel discovery
// Note, remove this when native stack improves
if (!mAdapterProperties.isDiscovering()) {
Log.i(TAG,"discovery not active, no need to send cancelDiscovery");
} else {
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;
} 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 synchronized 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;
case REMOVE_BOND:
removeBond(dev, true);
break;
case BONDING_STATE_CHANGE:
int newState = msg.arg1;
/* if incoming pairing, transition to pending state */
if (newState == BluetoothDevice.BOND_BONDING)
{
if(!mDevices.contains(dev)) {
mDevices.add(dev);
}
sendIntent(dev, newState, 0);
transitionTo(mPendingCommandState);
}
else if (newState == BluetoothDevice.BOND_NONE)
{
/* if the link key was deleted by the stack */
sendIntent(dev, newState, 0);
}
else
{
Log.e(TAG, "In stable state, received invalid newState: " + newState);
}
break; case CANCEL_BOND:
default:
Log.e(TAG, "Received unhandled state: " + msg.what);
return false;
}
return true;
}
} 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;
// 调用JNI
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;
}

Liu Tao

2019-3-27

Android 8 蓝牙 连接过程的更多相关文章

  1. Android使用蓝牙连接adb调试App

    使用WiFi连接Android设备调试APP的教程非常多,可是项目中须要使用蓝牙进行通信.所以牵扯使用蓝牙调用adb. 1.   将电脑蓝牙与手机进行配对(控制面板->设备和打印机->加入 ...

  2. Android 8 蓝牙打开过程

    packages\apps\Settings\src\com\android\settings\bluetooth\BluetoothEnabler.java @Override public boo ...

  3. Android实现蓝牙耳机连接

    代码地址如下:http://www.demodashi.com/demo/13259.html 前言 讲讲android对于蓝牙耳机连接技术的实现 今天涉及的内容有: 流程讲解 新建广播Bluetoo ...

  4. 基于swift语言iOS8的蓝牙连接(初步)

    看过一些蓝牙App的事例,大体上对蓝牙的连接过程进行了了解.但是开始真正自己写一个小的BLE程序的时候就举步维艰了.那些模棱两可的概念在头脑中瞬间就蒸发了,所以还是决定从最基本的蓝牙连接过程进行.这里 ...

  5. ZT Android 4.2 BT系统之蓝牙关闭过程全跟踪

    Android 4.2 BT系统之蓝牙关闭过程全跟踪 分类: android 2013-08-03 00:34 2252人阅读 评论(10) 收藏 举报 代码位置:       frameworks/ ...

  6. Android蓝牙连接自动测试工具

    蓝牙连接自动测试工具 1.需求产生 开发不按着需求走都是耍流氓且浪费时间.此工具的需求产生是研发人员在开发产品时涉及到蓝牙驱动和安卓蓝牙两个东西.但是呢,蓝牙不太稳定,那么工作来了.就需要研发人员一边 ...

  7. ubuntu16.04连接android手机蓝牙共享网络热点

    最近的想要用android手机蓝牙共享wifi网络给ubuntu16.04系统用,查了好多资料,发现网上很少有有用的.自己实践后分享如下. 第一步:手机与电脑配对:         该步骤比较简单,网 ...

  8. Android Multimedia框架总结(十九)Camera2框架C/S模型之CameraService启动及与Client连接过程

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/53150322 Agenda: 一 ...

  9. Android一对多蓝牙连接示例APP

    一对多蓝牙连接示例,基于Google BluetoothChat修改,实现一对多聊天(一个服务端.多个客户端),类似聊天室. 主要功能: 客户端的发出的消息所有终端都能收到(由服务端转发) 客户端之间 ...

随机推荐

  1. LeetCode(509. 斐波那数)

    问题描述: 斐波那契数,通常用 F(n) 表示,形成的序列称为斐波那契数列.该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和.也就是: F(0) = 0, F(1) = 1 F(N) ...

  2. [ZJOI2012]波浪

    Description: L = | P2 – P1 | + | P3 – P2 | + - + | PN – PN-1 | 给你一个N和M,问:随机一个1-N的排列,它的波动强度(L)不小于M的概率 ...

  3. (转)我是一个java class

    前言:本文主要想讲一下Java虚拟机的故事, 可能有点偏门,不妥之处欢迎留言交流. 第一回 陌生警察 我出生在C盘下面一个很深层次的目录下, 也不知道是谁把我放到这里的. 我一直在睡觉,外边的日出日落 ...

  4. IDEA的安装

    https://blog.csdn.net/when_to_return/article/details/81590356

  5. list(列表) python

    1.list(列表): list是处理一组有序项目的数据结构 list(列表)是python中使用最频繁的数据类型 list中什么类型的数据都可以存放(如:类.自己.函数......): list(列 ...

  6. C/JS_实现选择排序

    1.js var arr = prompt("请输入一个数组(以“,”隔开):").split(",").map(function(data){ return ...

  7. DPI技术简介

    匹配模式 根据规则的特点,可以分为两种 特征字符串模式:特征字符串模式实现方法简单,将流量的特征字符串提取出来即可进行流识别,不过此种方式描述性较差,需要将流量特征进行遍历,才可以将流量全部识别出来, ...

  8. JSAP106

    JSAP106 一.clientX.clientY 点击位置距离当前body可视区域的x,y坐标 二.pageX.pageY 对于整个页面来说,包括了被卷去的body部分的长度 三.screenX.s ...

  9. .NET的前世今生与将来

    笔者注 谨以此文纪念我敬重的2016年9月17日去世的 装配脑袋 逝世两周年 让大家久等了,前后花了1年的时间,几经改版,终于完成撰写了一万字长文,回顾和展望.NET这16年来的成功与失败.最终能成文 ...

  10. 阿里云安装nodejs和mongodb

    1) 安装nodejs wget https://nodejs.org/dist/v8.11.3/node-v8.11.3-linux-x64.tar.xz tar -xf node-v8.11.3- ...