Android蓝牙4.0开发
来源:互联网 发布:电脑扩音器软件 话筒 编辑:程序博客网 时间:2024/04/30 08:48
本文主要展示一个Android蓝牙4.0的开发示例。
一.蓝牙4.0
蓝牙4.0应用的设备一般是比较特殊的设备,比如低耗能蓝牙灯泡。并且使用的类的方法也是有点不同的。
BlueToothAdapter这个类是蓝牙设备的管理类。
BlueToothDevice蓝牙设备对象,里面包含蓝牙的数据。
上面两个类蓝牙设备都会有用到,下面这两个类只有蓝牙4.0才能用到。
BlueToothGatt低耗能蓝牙设备的控制对象
BlueToothGattCharateristic低耗能蓝牙设备的特征值对象
二.下面展示一个蓝牙灯泡的程序设计示例
这个蓝牙灯泡是低耗能蓝牙设备,需要支持蓝牙4.0的手机,Android版本需要以上4.3就可以了。
开发蓝牙设备时,蓝牙的传输协议也是要理解的,这个简单说一下,比如这个蓝牙灯泡,它的协议字段是一个十七位的byte数组,其中数组的第二三四六个数组的值,分别是控制RGB和光亮度,所以控制上面数组的四个值,就可以改变蓝牙灯泡的颜色的改变。
下面的代码:
(一)权限
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /><uses-permission android:name="android.permission.BLUETOOTH" /><!--6.0以上才要加的额外权限 --><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
(二)设备选择的页面
package fuxi.bluetooth40;import android.Manifest;import android.bluetooth.BluetoothAdapter;import android.bluetooth.BluetoothDevice;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.content.pm.PackageManager;import android.os.Build;import android.os.Bundle;import android.support.annotation.NonNull;import android.support.annotation.Nullable;import android.support.v7.app.AppCompatActivity;import android.text.TextUtils;import android.view.View;import android.widget.AdapterView;import android.widget.ArrayAdapter;import android.widget.ListView;import android.widget.Toast;import java.util.ArrayList;import java.util.List;/** * 设备选择页面 */public class DevicesActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { private static final int REQUEST_ENABLE = 1001;//请求打开蓝牙的请求码 private static final int REQUEST_LOCATION = 1002;//请求扫描显示设备的请求码 BluetoothAdapter bluetoothAdapter;//蓝牙管理器 ArrayAdapter<String> adapter;//列表的适配器 List<BluetoothDevice> devices = new ArrayList();//列表的对象 List<String> deviceNames = new ArrayList<>();//列表对象的数据 @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); ListView lv = new ListView(this); setContentView(lv);//显示列表视图 //实例化适配器 adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, deviceNames); //给列表设置适配器 lv.setAdapter(adapter); requestPer();//权限的请求 lv.setOnItemClickListener(this);//给List列表设置点击事件 } /** * 权限的请求方法 */ private void requestPer() { if (Build.VERSION.SDK_INT >= 23) { int check = checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION); if (check != PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_LOCATION); } else { //有了权限,就扫描蓝牙设备 checkBlue(); } } else { //版本低于6。0 checkBlue(); } } /** * 请求权限后的回调方法 */ @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_LOCATION && grantResults[0] == PackageManager.PERMISSION_GRANTED) { //成功了,扫描蓝牙 checkBlue(); } else { setResult(RESULT_CANCELED); finish(); } } /** * 重写onResume方法,进行广播接收者的注册 */ @Override protected void onResume() { super.onResume(); registerReceiver(receiver, new IntentFilter(BluetoothDevice.ACTION_FOUND)); } /** * 重写生命周期的onPause方法,进行广播接收者的注销 */ @Override protected void onPause() { super.onPause(); unregisterReceiver(receiver); } /** * 创建广播接收者 * //获取设备广播 */ private BroadcastReceiver receiver = new BroadcastReceiver() { //收到广播后的回调方法 @Override public void onReceive(Context context, Intent intent) { //获取设备 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); devices.add(device);//添加蓝牙设备对象 //添加蓝牙设备名称 deviceNames.add(TextUtils.isEmpty(device.getName()) ? "未命名" : device.getName()); Toast.makeText(DevicesActivity.this,"",Toast.LENGTH_SHORT).show(); adapter.notifyDataSetChanged();//刷新适配器 } }; /** * 蓝牙设备的扫描操作,并显示在视图列表中 */ public void checkBlue() { //是否打开了蓝牙 bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (bluetoothAdapter.isEnabled()) {//蓝牙已经就绪,可以进行扫描 deviceNames.clear(); devices.clear(); adapter.notifyDataSetChanged(); //开始扫描设置,扫描完成后会系统自动发送广播 bluetoothAdapter.startDiscovery(); } else {//蓝牙还没有就绪,要先打开蓝牙 openBlue(); } } /** * 打开蓝牙设备 */ private void openBlue() { //打开蓝牙 startActivityForResult(new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE), REQUEST_ENABLE); } /** * 请求打开蓝牙后返回的回调方法方法 * 进行扫描蓝牙设备操作 */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); checkBlue(); } /** * 点击列表视图的回调方法 * 这里只能选择固定产品的设备,选择其他的就提示重选 */ @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { BluetoothDevice device = devices.get(position); //KQX if (device.getName().startsWith("KQX")) { setResult(RESULT_OK, getIntent().putExtra("device", device));//传递数据,这个对象已经序列化过了 finish(); } else { Toast.makeText(this, "请选择卡丘熊蓝牙灯", Toast.LENGTH_SHORT).show(); } }}
(三)主页面显示的布局文件
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="test" android:text="校验" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="rgb" android:text="测试颜色" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="loop" android:text="循环显示" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="stopLoop" android:text="取消循环显示" /></LinearLayout>
(四)设备控制的页面
package fuxi.bluetooth40;import android.bluetooth.BluetoothDevice;import android.bluetooth.BluetoothGatt;import android.bluetooth.BluetoothGattCallback;import android.bluetooth.BluetoothGattCharacteristic;import android.bluetooth.BluetoothGattDescriptor;import android.bluetooth.BluetoothGattService;import android.content.Intent;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import java.util.List;/** * Android蓝牙4.0演示使用 */public class MainActivity extends AppCompatActivity { private static final int REQUEST_DEVICE = 1000;//设备选择页面的请求码 BluetoothDevice device;//蓝牙设备对象 BluetoothGatt gatt;//低耗能蓝牙设备对象 BluetoothGattCharacteristic writer;//耗能设备的输入的特征值 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); startActivityForResult(new Intent(this, DevicesActivity.class), REQUEST_DEVICE); } /** * 测试 */ public void test(View v) { //发送数据 // byte[] buf = getBuf((byte) 0x30); // byte[] buf = {0x55, (byte) 0xaa, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; byte[] buf = new byte[17]; buf[0] = 0x55; buf[1] = (byte) 0xaa; buf[2] = 0x30; writer.setValue(buf); gatt.writeCharacteristic(writer); } /** * 改变颜色 */ public void rgb(View v) { int r = (int) (Math.random() * 255); int g = (int) (Math.random() * 255); int b = (int) (Math.random() * 255); byte[] buf = getBuf(new byte[]{0x07, (byte) r, (byte) g, (byte) b, 0x00, (byte) 0x80}); writer.setValue(buf); gatt.writeCharacteristic(writer); } /** * 循环改变颜色 */ public void loop(View v) { handler.sendEmptyMessageDelayed(1,1000); } /** * 取消循环改变颜色 */ public void stopLoop(View v) { handler.removeMessages(1); } Handler handler=new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); changeLoop(); handler.sendEmptyMessageDelayed(1,1000); } }; private void changeLoop(){ int r = (int) (Math.random() * 255); int g = (int) (Math.random() * 255); int b = (int) (Math.random() * 255); byte[] buf = getBuf(new byte[]{0x07, (byte) r, (byte) g, (byte) b, 0x00, (byte) 0x80}); writer.setValue(buf); gatt.writeCharacteristic(writer); } /** * 蓝牙设备连接后的回调方法 */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_DEVICE && resultCode == RESULT_OK) { device = data.getParcelableExtra("device"); if (device != null) conn();//连接这个低耗能蓝牙设备 } else { finish(); } } /** * 连接低耗能蓝牙设备的方法 */ private void conn() { //BLE连接过程,这里需要最低版本是API是18,也就是android4.3以后的手机 //第一个参数上下文 //第二个参数是否自动连接 //第三个参数连接后的回调方法 gatt = device.connectGatt(this, false, mGattCallback); //连接 gatt.connect(); } /** * 连接蓝牙时,连接的回调接口 */ BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { //选择部分需要的回调方法 @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { super.onConnectionStateChange(gatt, status, newState); Log.e("TAG", "-------------------->>第一步"); Log.e("TAG", "----------->onConnectionStateChange"); //获取服务 获取设备电量 获取设备名称 gatt.discoverServices(); } @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { super.onServicesDiscovered(gatt, status); //获取低耗能蓝牙设备对象 List<BluetoothGattService> services = gatt.getServices(); for (BluetoothGattService service : services) { Log.e("TAG", "---------------" + service.getUuid()); for (BluetoothGattCharacteristic bluetoothGattCharacteristic : service.getCharacteristics()) { Log.e("TAG", "------------->>>" + bluetoothGattCharacteristic.getUuid()); } } Log.e("TAG", "----------->>onServicesDiscovered"); //获得需要的数据 //这里是设备对象的第三个服务的第一个特征值,用来数据的设置 writer = services.get(2).getCharacteristics().get(0); //这里是设备对象的第三个服务的第二个特征值,用来数据的读取 BluetoothGattCharacteristic reader = gatt.getServices().get(2).getCharacteristics().get(1); //打开读取开关 Log.e("TAG", "----------->>获取到特征值"); for (BluetoothGattDescriptor descriptor : reader.getDescriptors()) { descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); gatt.writeDescriptor(descriptor); } gatt.setCharacteristicNotification(reader, true); } }; /** * 设置,获取协议数据 */ public byte[] getBuf(byte... buf) { byte[] bufs = new byte[17]; //两位协议头 bufs[0] = 0x55; bufs[1] = (byte) 0xaa; //协议命令共14个,不足补0 if (buf != null && buf.length > 0) { for (int i = 0; i < buf.length; i++) { bufs[2 + i] = buf[i];//从第三个开始设置 } } return bufs; }}
程序运行后先显示的是选择蓝牙设备的ListView页面,选择对的蓝牙设备,然后进入蓝牙设备控制页面,点击按钮就可以对蓝牙设备进行控制。但是首先你得有一个低耗能的蓝牙设备!
说一下蓝牙的其他知识:蓝牙2.0和蓝牙3.0其实功能是差不多的,都是可以使用手机连接,并且可以进行手机无线无网通信,蓝牙4.0就和前面的版本有很多的区别,它的发展主要是用来适应其他的蓝牙设备,并且一般是单向连接,比如上面的蓝牙灯泡,只需要手机给蓝牙设备传入指令让它执行就可以了。
蓝牙2.0开发,之前有个开发示例(实现两个手机无网无线的通信):
http://blog.csdn.net/wenzhi20102321/article/details/53870789
- Android 蓝牙4.0开发
- android 蓝牙4.0开发
- android蓝牙4.0开发
- Android蓝牙4.0开发
- android ble蓝牙开发略解-Android 蓝牙4.0开发
- Android蓝牙4.0Ble开发
- Android Bluetooth蓝牙开发\蓝牙协议\蓝牙通信例子_Android支持蓝牙4.0版本_BLE开发
- Android Bluetooth蓝牙开发\蓝牙协议\蓝牙通信例子_Android支持蓝牙4.0版本_BLE开发
- Android Bluetooth蓝牙开发\蓝牙协议\蓝牙通信例子_Android支持蓝牙4.0版本_BLE开发
- Android Bluetooth蓝牙开发\蓝牙协议\蓝牙通信例子_Android支持蓝牙4.0版本_BLE开发
- Android Bluetooth蓝牙开发\蓝牙协议\蓝牙通信例子_Android支持蓝牙4.0版本_BLE开发
- Android Bluetooth蓝牙开发\蓝牙协议\蓝牙通信例子_Android支持蓝牙4.0版本_BLE开发
- Android Bluetooth蓝牙开发\蓝牙协议\蓝牙通信例子_Android支持蓝牙4.0版本_BLE开发
- Android Bluetooth蓝牙开发\蓝牙协议\蓝牙通信例子_Android支持蓝牙4.0版本_BLE开发
- Android Bluetooth蓝牙开发\蓝牙协议\蓝牙通信例子_Android支持蓝牙4.0版本_BLE开发
- Android Bluetooth蓝牙开发\蓝牙协议\蓝牙通信例子_Android支持蓝牙4.0版本_BLE开发
- Android Bluetooth蓝牙开发\蓝牙协议\蓝牙通信例子_Android支持蓝牙4.0版本_BLE开发
- Android Bluetooth蓝牙开发\蓝牙协议\蓝牙通信例子_Android支持蓝牙4.0版本_BLE开发
- 解决Spring 3.0 json返回中文乱码问题
- C++ 虚函数表解析
- 【Android】灵云在线语义理解功能使用说明
- <转>深入理解Spark RDD抽象模型和编写RDD函数
- Kali-linux-2016.2安装后常用配置记录(1)
- Android蓝牙4.0开发
- MTD/MT/MDD/MD以及LIB/DLL之间的一些联系和问题
- z-index失效情况
- 数据从关系型数据库到大数据平台再到关系型数据库
- NFC初步开发详解
- 蓝鸥React Native零基础入门到项目实战 props
- 认识iOS Application Extension(应用扩展)
- jenkins邮件通知的配置
- Spring、Spring MVC、MyBatis整合文件配置详解