android 蓝牙4.0多通道
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了android 蓝牙4.0多通道,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含9160字,纯文字阅读大概需要14分钟。
内容图文
很久没记录东西了,前段时间研究了一哈android4.0控制多个外设的情况,注意,需要使用android版本4.3以上,蓝牙4.0及以上。
我这里使用的控制蓝牙灯泡,使用android4.3的手机,手机上的蓝牙是4.0.
记得在manifest文件中加入权限:
< uses-permission android:name ="android.permission.BLUETOOTH" /> < uses-permission android:name ="android.permission.BLUETOOTH_ADMIN" />
先拿到BluetoothManager和BluetoothAdapter的对象。
// 初始化 Bluetooth adapter, 通过蓝牙管理器得到一个参考蓝牙适配器(API必须在以上android4.3或以上和版本) final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); mBluetoothAdapter = bluetoothManager.getAdapter(); // 检查设备上是否支持蓝牙if (mBluetoothAdapter == null) { Toast.makeText(this, R.string.error_bluetooth_not_supported,Toast.LENGTH_SHORT).show(); finish(); return; }
看下是否开启了蓝牙,如果没有开启,跳转到设置去开启蓝牙。
// 为了确保设备上蓝牙能使用, 如果当前蓝牙设备没启用,弹出对话框向用户要求授予权限来启用 if (!mBluetoothAdapter.isEnabled()) { if (!mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } }
调用startScan方法开始扫描,stopScan方法停止扫描,扫描到的设备都在回调函数里。
private void scanLeDevice(finalboolean enable) { if (enable) { // Stops scanning after a pre-defined scan period. mHandler.postDelayed(new Runnable() { @Override publicvoid run() { mScanning = false; mBluetoothAdapter.stopLeScan(mLeScanCallback); invalidateOptionsMenu(); } }, SCAN_PERIOD); mScanning = true; mBluetoothAdapter.startLeScan(mLeScanCallback); } else { mScanning = false; mBluetoothAdapter.stopLeScan(mLeScanCallback); } invalidateOptionsMenu(); }
// Device scan callback. private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { @Override publicvoid onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { runOnUiThread(new Runnable() { @Override publicvoid run() { mLeDeviceListAdapter.addDevice(device); // mLeDeviceListAdapter.notifyDataSetChanged(); } }); } };
扫描后的BluetoothDevice加入到列表中,这时列表中就会有设备,通过getName可以获取设备的蓝牙名字,getAddress获取设备的蓝牙地址。
列表出来了之后,点击某个设备进行连接。
注意这里的连接跟2.0的蓝牙的连接不一样,通过设备的connectGatt方法进行连接,连接完成后会获得一个BluetoothGatt的对象,这个对象中有连接的一些重要信息,切记要保存好。
public boolean connect(final String address) { if (mBluetoothAdapter == null || address == null) { Log.w(TAG, "BluetoothAdapter not initialized or unspecified address."); returnfalse; } if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress) && mBluetoothGatt != null) { Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection."); if (mBluetoothGatt.connect()) { returntrue; } else { returnfalse; } } final BluetoothDevice device = mBluetoothAdapter .getRemoteDevice(address); if (device == null) { Log.w(TAG, "Device not found. Unable to connect."); returnfalse; } // We want to directly connect to the device, so we are setting the // autoConnect // parameter to false. Log.e("AAA", "222"); mBluetoothGatt = device.connectGatt(this, true, mGattCallback); Log.d(TAG, "Trying to create a new connection."); mBluetoothDeviceAddress = address; bluetoothGatts.add(mBluetoothGatt); returntrue; }
连接时有一个回调函数mGattCallback,这个函数中有很多设备的相关信息,比如设备的状态啊,设备中的通道哈,一些服务啊之类的。
// Implements callback methods for GATT events that the app cares about. For // example, // connection change and services discovered. private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { @Override publicvoid onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { System.out.println("onConnectionStateChange"); String intentAction; if (status == BluetoothProfile.STATE_DISCONNECTED && newState == BluetoothProfile.STATE_CONNECTED) { intentAction = ACTION_GATT_CONNECTED; Log.i(TAG, "Connected to GATT server."); // Attempts to discover services after successful connection. Log.i(TAG, "Attempting to start service discovery:" + mBluetoothGatt.discoverServices()); Log.e("dongpuxiao", "连接成功"); mHandler.sendEmptyMessage(MESSAGE_START_SUCCESS); } elseif (status == BluetoothProfile.STATE_DISCONNECTED && newState == BluetoothProfile.STATE_DISCONNECTED) { intentAction = ACTION_GATT_DISCONNECTED; setConnStatus(false); Log.e("dongpuxiao", "连接失败"); Log.i(TAG, "Disconnected from GATT server."); mHandler.sendEmptyMessage(STATE_CONNECTFAILED); } } @Override publicvoid onServicesDiscovered(BluetoothGatt gatt, int status) { System.out.println("onServicesDiscovered-----"); if (status == BluetoothGatt.GATT_SUCCESS) { broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED); displayGattServices(getSupportedGattServices()); mHandler.sendEmptyMessage(MESSAGE_BLUETOOTH_INIT); } else { Log.w(TAG, "onServicesDiscovered received: " + status); } } @Override publicvoid onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { System.out.println("onCharacteristicRead"); if (status == BluetoothGatt.GATT_SUCCESS) { broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); } } @Override publicvoid onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { System.out.println("onDescriptorWriteonDescriptorWrite = " + status + ", descriptor =" + descriptor.getUuid().toString()); } @Override publicvoid onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); if (characteristic.getValue() != null) { System.out.println(characteristic.getStringValue(0)); } System.out.println("--------onCharacteristicChanged-----"); } @Override publicvoid onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) { } publicvoid onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { System.out.println("--------write success----- status:" + status); }; };
连接时会走这个方法onConnectionStateChange,传过来的新状态是连接状态,这时在这个方法中调用一下这句:mBluetoothGatt.discoverServices(),
mBluetoothGatt是连接完成时的对象,还记得吧,调用这句后,会走回调函数的onServicesDiscovered方法。在这个方法中去获取设备的一些服务,蓝牙通道,然后通过这些通道去发送数据给外设。
查看该外设中支持的一些服务通道:
public List<BluetoothGattService> getSupportedGattServices() { if (mBluetoothGatt == null) returnnull; return mBluetoothGatt.getServices(); }
// Demonstrates how to iterate through the supported GATT // Services/Characteristics. // In this sample, we populate the data structure that is bound to the // ExpandableListView // on the UI. private void displayGattServices(List<BluetoothGattService> gattServices) { if (gattServices == null) return; String uuid = null; ArrayList<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>(); ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData = new ArrayList<ArrayList<HashMap<String, String>>>(); mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>(); // Loops through available GATT Services.for (BluetoothGattService gattService : gattServices) { HashMap<String, String> currentServiceData = new HashMap<String, String>(); uuid = gattService.getUuid().toString(); gattServiceData.add(currentServiceData); ArrayList<HashMap<String, String>> gattCharacteristicGroupData = new ArrayList<HashMap<String, String>>(); List<BluetoothGattCharacteristic> gattCharacteristics = gattService .getCharacteristics(); ArrayList<BluetoothGattCharacteristic> charas = new ArrayList<BluetoothGattCharacteristic>(); // Loops through available Characteristics.for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) { charas.add(gattCharacteristic); HashMap<String, String> currentCharaData = new HashMap<String, String>(); uuid = gattCharacteristic.getUuid().toString(); gattCharacteristicGroupData.add(currentCharaData); } mGattCharacteristics.add(charas); gattCharacteristicData.add(gattCharacteristicGroupData); } bluetoothGattChacteristics.add(mGattCharacteristics); }
然后就可以通过Gatt这个对像,就是蓝牙连接完成后获取到的对象,通过这个对象设置好指定的通道向设备中写入和读取数据。
写数据:
public void wirteCharacteristic(BluetoothGattCharacteristic characteristic) { if (mBluetoothAdapter == null || mBluetoothGatt == null) { Log.w(TAG, "BluetoothAdapter not initialized"); return; } mBluetoothGatt.writeCharacteristic(characteristic); }
读数据:
/** * Request a read on a given { @code BluetoothGattCharacteristic}. The read * result is reported asynchronously through the * { @code BluetoothGattCallback#onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int)} * callback. * * @param characteristic * The characteristic to read from. */ public void readCharacteristic(BluetoothGattCharacteristic characteristic) { if (mBluetoothAdapter == null || mBluetoothGatt == null) { Log.w(TAG, "BluetoothAdapter not initialized"); return; } mBluetoothGatt.readCharacteristic(characteristic); }
注意:BluetoothGattCharacteristic这个是指定的通道,蓝牙服务:
BluetoothGattCharacteristic characteristic = null; characteristic = mGattCharacteristics.get(4).get(4);
这两个数字就是从指定的服务中找到你要发送数据的那个服务。
最后,如果要进行多个连接,每次连接完成后可以将BluetoothGatt的对象放到一个list里面,获取到的服务也放到一个List里面,然后发送数据的时候调用不同的Gatt发送不同的通道数据即可。
关于蓝牙4.0的BluetoothLeGatt连接,android Samples有一个例子,发上来吧,需要的朋友可以下载看看。
原文:http://www.cnblogs.com/shang53880/p/4624955.html
内容总结
以上是互联网集市为您收集整理的android 蓝牙4.0多通道全部内容,希望文章能够帮你解决android 蓝牙4.0多通道所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。