android5.0 BLE 蓝牙4.0+浅析demo搜索(一)
2017-02-20 14:04
246 查看
作者:Bgwan
链接:https://zhuanlan.zhihu.com/p/23341414
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
作者:Bgwan 莳萝花
链接:android BLE 蓝牙4.0+浅析(一) - Android开发 - 知乎专栏
来源:知乎
著作权归作者所有,转载请联系作者获得授权。
android BLE 蓝牙4.0+浅析(一)
Android 4.3 (API Level 18) introduces built-in platform support for Bluetooth Low Energy in the central roleand provides APIs that apps can use to discover devices, query for services, and read/write characteristics.
+代表蓝牙更高版本,
本文介绍Android ble 蓝牙4.0,也就是说API level >= 18,且支持蓝牙4.0的手机才可以使用,如果手机系统版本API level < 18,是用不了蓝牙4.0的,我们通常可以加一个判断。
首先:操作蓝牙,我们需要在AndroidMainfest.xml中配置,如下权限,
说明:hardware是,在底判断是否支持,蓝牙,admin是超级权限,根据用户需求不同加入不同的权限,
蓝牙SDK版本判断,如下代码:
1,打开蓝牙,蓝牙状态等操作,以及是否支持蓝牙BLE
2,如果蓝牙没有打开,我们需要打开蓝牙,打开蓝牙有两种方式,但是建议给用户显示的方式打开,因为用户需要知道这些权限,不然你这个就是牛氓行为。隐式打开为:
,下面的代码为显示的打开方式。
3,搜索蓝牙操作。
如果蓝牙都已经打开正常,则可以进行搜索周围蓝牙设备的操作,这里记住,不只是手机中的蓝牙,任何外设都可以。顺带,我们查看android SDK会发现bluetooth包下面多了le.这是android 蓝牙4.2以后新加入的操作蓝牙的包,但是谷歌为了兼容以前的版本
这个方法还是可以使用,这里我们使用le。包下面最新的搜索蓝牙的功能,如下:
scanLeDevice是对方法的封装,这里主要是调用bluetoothlescanner的starscan方法,该方法可以传递两个参数,这里先讨论传递mScanCallback这是一个扫描结果的回掉接口;当然这里操作也应该放到子线程中去处理。
具体的scanLeDevice()方法如下:
4,以上我们就开启了蓝牙的搜索,功能,然后会触发mScanCallback进行结果的监听。主要监听里面的三个方法,onScanResult,onBatchScanResults,onScanFailed,搜索到结果以后,我们需要对它进行解析,代码里面都注释得很清楚
这里我自己对搜索的结果操作为,
加入到mLeDeviceListAdapter中去,这是一个listview的适配器,
5,蓝牙列表,结果显示的适配器代码,很简单,如下面。
以上就是全部代码,下面文章,会从源码的角度分析,最新的开启,蓝牙和以前版本的对比,方便理解,在以后的文章会讲解如何连接嵌入式的蓝牙设备进行数据的传送。当然这里会由浅到深的体现出来。
链接:https://zhuanlan.zhihu.com/p/23341414
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
作者:Bgwan 莳萝花
链接:android BLE 蓝牙4.0+浅析(一) - Android开发 - 知乎专栏
来源:知乎
著作权归作者所有,转载请联系作者获得授权。
android BLE 蓝牙4.0+浅析(一)
Android 4.3 (API Level 18) introduces built-in platform support for Bluetooth Low Energy in the central roleand provides APIs that apps can use to discover devices, query for services, and read/write characteristics.
+代表蓝牙更高版本,
本文介绍Android ble 蓝牙4.0,也就是说API level >= 18,且支持蓝牙4.0的手机才可以使用,如果手机系统版本API level < 18,是用不了蓝牙4.0的,我们通常可以加一个判断。
首先:操作蓝牙,我们需要在AndroidMainfest.xml中配置,如下权限,
<!--蓝牙权限--> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-feature android:name="android.hardware.bluetooth_le" android:required="true"></uses-feature>
说明:hardware是,在底判断是否支持,蓝牙,admin是超级权限,根据用户需求不同加入不同的权限,
蓝牙SDK版本判断,如下代码:
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) { Toast.makeText(this, "当前版本SDK" + Build.VERSION.SDK_INT + "< Android5.0不支持蓝牙", Toast.LENGTH_SHORT).show(); mText.setText("当前版本" + Build.VERSION.SDK_INT + "< Android5.0不支持蓝牙"); return; }
1,打开蓝牙,蓝牙状态等操作,以及是否支持蓝牙BLE
// Use this check to determine whether BLE is supported on the device. Then // you can selectively disable BLE-related features. if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show(); mText.setText(R.string.ble_not_supported); return; } // Initializes Bluetooth adapter. final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); mBluetoothAdapter = bluetoothManager.getAdapter(); //需要时再初始化 mHandler = new Handler(); mProgress = new ProgressDialog(NewActivity.this);
2,如果蓝牙没有打开,我们需要打开蓝牙,打开蓝牙有两种方式,但是建议给用户显示的方式打开,因为用户需要知道这些权限,不然你这个就是牛氓行为。隐式打开为:
mBluetoothAdapter.enable();
,下面的代码为显示的打开方式。
/ Ensures Bluetooth is available on the device and it is enabled. If not, // displays a dialog requesting user permission to enable Bluetooth. if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); Toast.makeText(this, "蓝牙正在打开,建议允许应用操作", Toast.LENGTH_SHORT).show(); }
3,搜索蓝牙操作。
如果蓝牙都已经打开正常,则可以进行搜索周围蓝牙设备的操作,这里记住,不只是手机中的蓝牙,任何外设都可以。顺带,我们查看android SDK会发现bluetooth包下面多了le.这是android 蓝牙4.2以后新加入的操作蓝牙的包,但是谷歌为了兼容以前的版本
mBluetoothAdapter.startLeScan(mLeScanCallback);
这个方法还是可以使用,这里我们使用le。包下面最新的搜索蓝牙的功能,如下:
//最新写法。蓝牙打开才执行 if (mBluetoothAdapter.isEnabled()) { mProgress.setMessage("正在搜索周围设备..."); mProgress.setCancelable(false); mProgress.show(); newtext.setText("蓝牙已经打开,关闭蓝牙请在设置中设置"); mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner(); // Initializes list view adapter. mLeDeviceListAdapter = new LeDeviceListAdapter(); listView.setAdapter(mLeDeviceListAdapter); //显示dialog new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(3000); if (mProgress != null) { mProgress.dismiss(); } } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); mLeDeviceListAdapter.clearDevice(); scanLeDevice(true); } }
scanLeDevice是对方法的封装,这里主要是调用bluetoothlescanner的starscan方法,该方法可以传递两个参数,这里先讨论传递mScanCallback这是一个扫描结果的回掉接口;当然这里操作也应该放到子线程中去处理。
mBluetoothLeScanner.startScan(mScanCallback);//新
具体的scanLeDevice()方法如下:
private void scanLeDevice(final boolean enable) {
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mScanning = false;
mBluetoothLeScanner.stopScan(mScanCallback);
invalidateOptionsMenu();
}
}, SCAN_PERIOD);
mScanning = true;
mBluetoothLeScanner.startScan(mScanCallback);//新} else {
mScanning = false;
mBluetoothLeScanner.stopScan(mScanCallback);
}
invalidateOptionsMenu();
}
4,以上我们就开启了蓝牙的搜索,功能,然后会触发mScanCallback进行结果的监听。主要监听里面的三个方法,onScanResult,onBatchScanResults,onScanFailed,搜索到结果以后,我们需要对它进行解析,代码里面都注释得很清楚
// Device scan callback. private ScanCallback mScanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); if (result == null || result.getDevice() == null || TextUtils.isEmpty(result.getDevice().getName())) { mText.setText("没有搜索到蓝牙设备"); // return; } //如果是外设则可能存在没有ServiceUuids // builder.append("/n").append( // new String(result.getScanRecord().getServiceData( // result.getScanRecord().getServiceUuids().get(0)), // Charset.forName("UTF-8"))); BluetoothDevice device = result.getDevice(); Log.d(TAG, "Device name: " + device.getName()); Log.d(TAG, "Device address: " + device.getAddress()); Log.d(TAG, "Device service UUIDs: " + device.getUuids()); if (builder.toString().contains(device.getName())) { } else { builder.append("\n" + device.getName() + "&" + device.getAddress() + "\n"); } ScanRecord record = result.getScanRecord(); Log.d(TAG, "Record advertise flags: 0x" + Integer.toHexString(record.getAdvertiseFlags())); Log.d(TAG, "Record Tx power level: " + record.getTxPowerLevel()); Log.d(TAG, "Record device name: " + record.getDeviceName()); Log.d(TAG, "Record service UUIDs: " + record.getServiceUuids()); Log.d(TAG, "Record service data: " + record.getServiceData()); mLeDeviceListAdapter.addDevice(device); mLeDeviceListAdapter.notifyDataSetChanged(); mText.setText("搜索结果,builder:" + builder.toString()); } @Override public void onBatchScanResults(List<ScanResult> results) { super.onBatchScanResults(results); for (ScanResult result : results) { Toast.makeText(getApplicationContext(), "result:" + result.getDevice().getAddress(), Toast.LENGTH_SHORT).show(); } } @Override public void onScanFailed(int errorCode) { super.onScanFailed(errorCode); mText.setText("搜索蓝牙失败 errorCode:" + errorCode); } };
这里我自己对搜索的结果操作为,
mLeDeviceListAdapter.addDevice(device);
加入到mLeDeviceListAdapter中去,这是一个listview的适配器,
5,蓝牙列表,结果显示的适配器代码,很简单,如下面。
// Adapter for holding devices found through scanning. private class LeDeviceListAdapter extends BaseAdapter { private ArrayList<BluetoothDevice> mLeDevices; private LayoutInflater mInflator; public LeDeviceListAdapter() { super(); mLeDevices = new ArrayList<BluetoothDevice>(); mInflator = NewActivity.this.getLayoutInflater(); } public void addDevice(BluetoothDevice device) { if (!mLeDevices.contains(device)) { mLeDevices.add(device); } } public void clearDevice() { if (mLeDevices.size() > 0) { mLeDevices.clear(); } } public BluetoothDevice getDevice(int position) { return mLeDevices.get(position); } public void clear() { mLeDevices.clear(); } @Override public int getCount() { return mLeDevices.size(); } @Override public Object getItem(int i) { return mLeDevices.get(i); } @Override public long getItemId(int i) { return i; } @Override public View getView(int i, View view, ViewGroup viewGroup) { DeviceScanActivity.ViewHolder viewHolder; // General ListView optimization code. if (view == null) { view = mInflator.inflate(R.layout.listitem_device, null); viewHolder = new DeviceScanActivity.ViewHolder(); viewHolder.deviceAddress = (TextView) view.findViewById(R.id.device_address); viewHolder.deviceName = (TextView) view.findViewById(R.id.device_name); view.setTag(viewHolder); } else { viewHolder = (DeviceScanActivity.ViewHolder) view.getTag(); } BluetoothDevice device = mLeDevices.get(i); final String deviceName = device.getName(); if (deviceName != null && deviceName.length() > 0) viewHolder.deviceName.setText(deviceName); else viewHolder.deviceName.setText(R.string.unknown_device); viewHolder.deviceAddress.setText(device.getAddress()); return view; } }
以上就是全部代码,下面文章,会从源码的角度分析,最新的开启,蓝牙和以前版本的对比,方便理解,在以后的文章会讲解如何连接嵌入式的蓝牙设备进行数据的传送。当然这里会由浅到深的体现出来。
相关文章推荐
- Android5.0(Lollipop) BLE蓝牙4.0+浅析demo连接(三)
- 关于Android6.0蓝牙Ble搜索的demo和一点心得
- 蓝牙BLE开发基础教程 android5.0 蓝牙4.0 透传 Android Studio(一)
- Android BLE蓝牙4.0开发详解
- Android BLE蓝牙4.0开发—Android手机与BLE终端通信
- BLE 蓝牙4.0
- Android6.0以上系统搜索不到 蓝牙BLE 设备问题
- Android5.0(Lollipop) BLE蓝牙4.0+浅析code(二)
- 蓝牙4.0——Ble 开发要点
- android 蓝牙4.0开发心得(一)蓝牙搜索
- android ble蓝牙开发略解-Android 蓝牙4.0开发
- Android4.4(MT8685)源码蓝牙解析--BLE搜索
- Android5.0(Lollipop) BLE蓝牙4.0+浅析概念(四)
- Android 6.0 蓝牙ble 官方demo简化版
- android搜索蓝牙时,区分所搜索到的设备是2.0还是BLE
- iOS蓝牙4.0开发(BLE)
- IOS 模拟器里面如何打开 蓝牙调试 ble 4.0
- BlueTooth: 低功耗蓝牙bluetooth 4.0 (BLE) CC2540
- 使用BleLib的轻松搞定Android低功耗蓝牙Ble 4.0开发具体解释
- Android 蓝牙 BLE蓝牙 浅析