最近项目中遇到使用蓝牙传输数据的业务,本着学习态度记录下,个人理解,有错误或者补充的欢迎大家留言。废话不多说,开始正题
1.什么是蓝牙
Bluetooth是目前使用的最广泛的无线通讯协议之一
主要针对短距离设备通讯(10米)
常用于连接耳机、鼠标和移动通讯设备等
2.发现周围蓝牙设备
BluetoothAdapter:代表了本地的蓝牙适配器
BluetoothDevice:代表一个远程的蓝牙设备
扫描已配对的蓝牙设备方法:
1.在AndroidManifest.xml声明蓝牙权限
权限这里一定要注意,google在android6.0之后,为了更好的保护用户的数据安全,所有需要访问硬件唯一标识符的地方都需要申请位置权限,也就是需要申请位置权限
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION"/>
蓝牙的权限是normal级权限,只需要在Manifest里面申请即可,但是位置权限是dangerous级权限,除了需要在Manifest里申请之外,还需要在代码中进行动态申请,并跟踪用户对权限的确认结果!!(没有授权,你肯定是不能使用完整的功能的,不过好像不影响我们打开蓝牙,蓝牙的设备搜索功能是没有办法使用的)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
}
}
在授权结果回调函数中判断用户的授权结果:
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
boolean grantedLocation = true;
switch (requestCode) {
case PERMISSION_REQUEST_COARSE_LOCATION:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
grantedLocation = false;
}
if(!grantedLocation){
Toast.makeText(this,"Permission error !!!",Toast.LENGTH_SHORT).show();
finish();
}
break;
}
}
2.获得BluetoothAdapter对象
3.判断当前设备中是否拥有蓝牙设备
4.判断当前设备中蓝牙设备是否已经打开
// 初始化蓝牙设备
private void init() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// 检查设备是否支持蓝牙设备
if (mBluetoothAdapter == null) {
Log.d(TAG, "设备不支持蓝牙");
// 不支持蓝牙,退出。
return;
}
// 如果用户的设备没有开启蓝牙,则弹出开启蓝牙设备的对话框,让用户开启蓝牙
if (!mBluetoothAdapter.isEnabled()) {
Log.d(TAG, "请求用户打开蓝牙");
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
// 接下去,在onActivityResult回调判断
}
}
3.修改本机蓝牙设备的可见性
// 可选方法,非必需
// 此方法使自身的蓝牙设备可以被其他蓝牙设备扫描到,
// 注意时间阈值。0 - 3600 秒。
// 通常设置时间为120秒。
private void enable_discovery() {
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
// 第二个参数可设置的范围是0~3600秒,在此时间区间(窗口期)内可被发现
// 任何不在此区间的值都将被自动设置成120秒。
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 3600);
startActivity(discoverableIntent);
}
4.扫描周围可用的蓝牙设备
// 启动蓝牙发现...
private void discovery() {
if (mBluetoothAdapter == null) {
init();
}
mBluetoothAdapter.startDiscovery();
}
// 注册广播接收器。
// 接收蓝牙发现
IntentFilter filterFound = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filterFound);
IntentFilter filterStart = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
registerReceiver(mReceiver, filterStart);
IntentFilter filterFinish = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mReceiver, filterFinish);
// 广播接收发现蓝牙设备
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
ToastUtils.showMessage(mContext,"开始扫描...");
Log.d(TAG, "开始扫描...");
}
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
Log.d(TAG, "扫描结果.");
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device != null) {
// 添加到ListView的Adapter。
if(!TextUtils.isEmpty(device.getName())){
mAdapter.add(device.getName() + "\n" + device.getAddress());
mAdapter.notifyDataSetChanged();
}
devices.add(device);
}
}
if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
Log.d(TAG, "扫描结束.");
ToastUtils.showMessage(mContext,"扫描结束.");
}
}
};
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mReceiver);
}
到此,启动蓝牙,搜索周围蓝牙列表功能已实现,至于连接蓝牙传输数据的功能,为了不误导大家,待研究成功使用之后再来记录