写在前面
换工作之后新任务是做个AndroID的App,用Java写算是前期比较简单的一个工作了(现在突然被公司派去了图像处理也不多说了),目标是完成蓝牙扫描-连接-读写数据。
要求只是一个Demo,对于线程方面要求不高,而且我也是第一次写AndroID,因此参考的话也可以后期进行自己的修改和整理。
所有参考资料的网址都给了链接,在对于我逻辑阐述不到位的地方,可以点击参考链接参考前辈们的资料。
API
安卓入门:https://www.runoob.com/w3cnote/android-tutorial-toast.html
蓝牙API:https://www.jb51.cc/manual/view/15887.html ←点击该连接进入应该直接进入到AndroID的BlueDevice的相关参数
蓝牙基础配置:
App的使用需要开启一些蓝牙的基础配置,在各个参考资料中也提到了。
在项目包中找到AndroIDManifest.xml,在里面直接添加蓝牙的基础配置。
注:我的配置是androID版本>6.0的,<6.0的话要去掉几个配置,但是现在感觉市面上也没有<6.0的版本了,如果做<6.0的版本可以单独搜一搜(我下面的一些参考连接中也会提到。
<!-- 蓝牙权限 add by momo--> <uses-permission androID:name="androID.permission.BLUetoOTH_admin" /> <uses-permission androID:name="androID.permission.BLUetoOTH" /> <!-- 基于地理位置 --> <uses-permission androID:name="androID.permission.ACCESS_COARSE_LOCATION" /> <uses-permission androID:name="androID.permission.ACCESS_FINE_LOCATION" /> <!-- 不支持低功耗蓝牙的是否安装 --> <uses-feature androID:name="androID.harDWare.bluetooth_le" androID:required="true" /> <!-- 读写文件的权限 add by momo --> <uses-permission androID:name="androID.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission androID:name="androID.permission.READ_EXTERNAL_STORAGE" />
蓝牙扫描界面
参考链接:https://blog.csdn.net/qq_35270692/article/details/76359873
我的界面如图所示:
界面代码(activity_bluetooth.xml):
<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" xmlns:app="http://schemas.androID.com/apk/res-auto" androID:orIEntation="vertical"> <linearLayout androID:layout_weight="12" androID:orIEntation="horizontal"> <linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" xmlns:app="http://schemas.androID.com/apk/res-auto" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:orIEntation="vertical"> <button androID:ID="@+ID/startScale" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:text="开始扫描" app:backgroundTint="@color/startScale" /> <button androID:ID="@+ID/stopScale" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:text="停止扫描" app:backgroundTint="@color/stopScale" /> <button androID:ID="@+ID/startRead" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:text="开始读取" app:backgroundTint="@color/startRead" /> <button androID:ID="@+ID/stopRead" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:text="停止读取" app:backgroundTint="@color/stopRead" /> <Progressbar androID:ID="@+ID/progressbar" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:text="stopScale" /> <ListVIEw androID:ID="@+ID/ListvIEw" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content"> </ListVIEw> </linearLayout> </linearLayout></linearLayout>
color等一些参数可以自行设置
创建界面内嵌的ListvIEw(layout_ListvIEw_item)
<?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" > <TextVIEw androID:ID="@+ID/device_name" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:text="蓝牙设备名字" androID:layout_margin="2dp" /> <TextVIEw androID:ID="@+ID/device_address" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:text="蓝牙设备的名字" androID:layout_margin="5dp" /> <TextVIEw androID:ID="@+ID/device_status" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:text="蓝牙设备的状态" /></linearLayout>
蓝牙扫描功能
参考连接1:https://blog.csdn.net/qq_39326574 ←这位前辈的博客里写了蓝牙的扫描和读写数据,是最为简单直白的,适合有较好基础的或者较为熟悉蓝牙的朋友学习。
参考链接2:https://www.cnblogs.com/littlecarry/p/11889982.html ←这位前辈是从原理出发详解BLE扫描的基础,可以认真研读一下明白蓝牙收发的机制。
知识点参考:获取当前链接的蓝牙设备
知识点参考:Android检查设备连接状态
知识点参考:Android : BluetoothAdapter.LeScanCallback
知识点参考:蓝牙扫描 LeScanCallback 方法 不回调
知识点参考:BLE的connect()和connectGatt的区别
-------------------------------------------------------------------------
以上是我学习过程中受益匪浅的前辈资料,当遇到问题也许可以通过这些链接找到答案。
接下来是蓝牙扫描功能的代码。
1.新建一个java class,定义蓝牙对象
public class Bluetooth_item_Bean { String bluetoothDevice_name; //蓝牙设备的名字 String bluetoothDevice_Adress; //蓝牙设备的mac地址 String bluetoothDevice_ConectStatus; //连接状态 //判断内容是否相等 @OverrIDe public boolean equals(Object obj) { if(obj instanceof Bluetooth_item_Bean){ if(bluetoothDevice_Adress.equals(((Bluetooth_item_Bean) obj).bluetoothDevice_Adress) /*&& bluetoothDevice_name.equals(((Bluetooth_item_Bean) obj).bluetoothDevice_name)*/ ){ return true; } }else{ return false; } return super.equals(obj); } @OverrIDe public int hashCode() { return bluetoothDevice_Adress.hashCode(); } public String getBluetoothDevice_name() { return bluetoothDevice_name; } public voID setBluetoothDevice_name(String bluetoothDevice_name) { this.bluetoothDevice_name = bluetoothDevice_name; } public String getBluetoothDevice_Adress() { return bluetoothDevice_Adress; } public voID setBluetoothDevice_Adress(String bluetoothDevice_Adress) { this.bluetoothDevice_Adress = bluetoothDevice_Adress; } public String getBluetoothDevice_ConectStatus() { return bluetoothDevice_ConectStatus; } public voID setBluetoothDevice_ConectStatus(String bluetoothDevice_ConectStatus) { this.bluetoothDevice_ConectStatus = bluetoothDevice_ConectStatus; }}
2.新建java class,定义显示文本
public class ListVIEwAdapter extends BaseAdapter { private Context mcontext; //上下文 private List<Bluetooth_item_Bean> ListDatas; //ListvIEw需要用到的信息包括蓝牙名字和蓝牙设备的mac地址; private LayoutInflater layoutInflater; ListVIEwAdapter(Context mcontext, List<Bluetooth_item_Bean> ListDatas){ this.mcontext = mcontext; this.ListDatas = ListDatas; layoutInflater = LayoutInflater.from(mcontext); } @OverrIDe public int getCount() { return ListDatas.size(); } @OverrIDe public Object getItem(int position) { return ListDatas.get(position); } @OverrIDe public long getItemID(int position) { return position; } @OverrIDe public VIEw getVIEw(int position, VIEw vIEw, VIEwGroup parent) { ListvIEwHolder ListvIEwHolder; if(vIEw ==null){ ListvIEwHolder = new ListvIEwHolder(); vIEw = layoutInflater.inflate(R.layout.layout_ListvIEw_item,null); ListvIEwHolder.device_name = (TextVIEw) vIEw.findVIEwByID(R.ID.device_name); ListvIEwHolder.device_Address= (TextVIEw) vIEw.findVIEwByID(R.ID.device_address); ListvIEwHolder.device_ConectStatus = (TextVIEw) vIEw.findVIEwByID(R.ID.device_status); vIEw.setTag(ListvIEwHolder); }else{ ListvIEwHolder = (ListvIEwHolder) vIEw.getTag(); } ListvIEwHolder.device_name.setText(ListDatas.get(position).bluetoothDevice_name); ListvIEwHolder.device_Address.setText(ListDatas.get(position).bluetoothDevice_Adress); ListvIEwHolder.device_ConectStatus.setText(ListDatas.get(position).bluetoothDevice_ConectStatus); return vIEw; } static class ListvIEwHolder{ private TextVIEw device_name; private TextVIEw device_Address; private TextVIEw device_ConectStatus; }}
3.在activity里定义全局变量
private static final int REQUEST_CODE_LOCATION_SETTINGS = 2; //用于Gps打开 private BluetoothManager bluetoothManager; //蓝牙管理器 private BluetoothAdapter bluetoothAdapter; //蓝牙适配器 private static final int REQUEST_ENABLE_BLE = 1; //蓝牙请求 private static final long SCALE_PERIOD= 10*1000; //扫描时长 10秒 private static final String READ_SERVICE_UUID = "0000ffe0-0000-1000-8000-00805f9b34fb"; private static final String READ_characteristics_UUID = "0000ffe1-0000-1000-8000-00805f9b34fb"; //读的这个特征值的uuID //布局中的控件 private button startScalebutton; //开始扫描按钮 private button stopScalebutton; //停止扫描按钮 private button startReadbutton; //开始读数据 private button stopReadButtion; //停止读数据 private ListVIEw ListvIEw; //展示扫描到的结果ListvIEw; private List<Bluetooth_item_Bean> BluetoothDevice_Info; //蓝牙设备的信息 private ListVIEwAdapter adapter; //这个是定义的ListVIEw的内部ListvIEw_item的 private Progressbar progressbar; private Handler handler; private TextVIEw noiseTextVIEw; private TextVIEw attentionTextVIEw; private TextVIEw meditationTextVIEw; private static final int REQUEST_CODE_ACCESS_COARSE_LOCATION = 1; //动态申请权限 private BluetoothGatt mGatt;//通讯协议 RunThread t1 = new RunThread(); //读写线程 private BottomNavigationVIEw bottomNavigation; private Bluetooth_item_Bean bluetooth_item_bean;
4.onCreate函数
@RequiresAPI(API = Build.VERSION_CODES.JELLY_BEAN_MR2) @OverrIDe public voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_bluetooth); //设置连接界面 initVIEw(); //初始化控件 initEvent(); //初始化事件 initData(); //初始化数据 adapter = new ListVIEwAdapter(Ble1Activity.this,BluetoothDevice_Info); //ListVIEw的适配器 ListvIEw.setAdapter(adapter); //将获取到的数据放入展示列表 checkPermission(); //判断SD卡是否存在 //检测当前设备是否支持蓝牙ble if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUetoOTH_LE)){ Toast.makeText(Ble1Activity.this, "当前蓝牙不支持蓝牙设备", Toast.LENGTH_SHORT).show(); finish(); } //通过蓝牙管理器得到一个蓝牙适配器 bluetoothManager = (BluetoothManager) getSystemService(Context.BLUetoOTH_SERVICE); bluetoothAdapter = bluetoothManager.getAdapter(); if(bluetoothAdapter==null){ Toast.makeText(Ble1Activity.this,"该设备不支持蓝牙",Toast.LENGTH_SHORT).show(); } //androID6.0之后要求有定位权限才可以扫描到蓝牙 //动态申请权限 if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){ //如果API版本大于23AndroID6.0的时候 //判断是否具有权限 if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)!= PackageManager.PERMISSION_GRANTED){ //判断是否需要向用户解释为什么需要申请权限 if(ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.ACCESS_COARSE_LOCATION)){ Toast.makeText(Ble1Activity.this,"需要获取定位才可以使用BLE扫描",Toast.LENGTH_SHORT).show(); } //请求权限 ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},REQUEST_CODE_ACCESS_COARSE_LOCATION);//请求码 } } clickListVIEw(); }
5.各类界面的初始化
//控件初始化 private voID initData() { //用于定时取消扫描 handler = new Handler(); //模拟蓝牙设备的信息 BluetoothDevice_Info = new ArrayList<>(); /* for(int i = 0 ;i<3;i++){ Bluetooth_item_Bean bluetooth_device_item_info = new Bluetooth_item_Bean(); bluetooth_device_item_info.bluetoothDevice_name = "蓝牙设备名字"+i; bluetooth_device_item_info.bluetoothDevice_Adress = "蓝牙设备mac地址"+i; bluetooth_device_item_info.bluetoothDevice_ConectStatus = "蓝牙设备状态"+i; BluetoothDevice_Info.add(bluetooth_device_item_info); }*/ } private voID initVIEw() { startScalebutton = (button)findVIEwByID(R.ID.startScale); //初始化控件。开始扫描按钮 stopScalebutton= (button)findVIEwByID(R.ID.stopScale); //初始化控件,停止扫描按钮 startReadbutton = findVIEwByID(R.ID.startRead); //初始化控件,开始读数据 stopReadButtion = findVIEwByID(R.ID.stopRead); //初始化控件,停止读数据 ListvIEw = (ListVIEw) findVIEwByID(R.ID.ListvIEw); //用于展示扫描到的设备信息,ListvIEw progressbar = (Progressbar) findVIEwByID(R.ID.progressbar); progressbar.setVisibility(VIEw.GONE); } private voID initEvent() { startScalebutton.setonClickListener(this); //开始扫描事件 stopScalebutton.setonClickListener(this); //停止扫描 startReadbutton.setonClickListener(this); //开始读数据 stopReadButtion.setonClickListener(this); //停止读数据 }
6.各类click事件的初始化
//蓝牙点击事件private voID clickListVIEw() { //请求到蓝牙后,点击搜索到的蓝牙进行连接 ListvIEw.setonItemClickListener(new AdapterVIEw.OnItemClickListener() { @RequiresAPI(API = Build.VERSION_CODES.JELLY_BEAN_MR2) @OverrIDe public voID onItemClick(AdapterVIEw<?> adapterVIEw, VIEw vIEw, int i, long l) { bluetooth_item_bean = BluetoothDevice_Info.get(i); //获取当前click事件的蓝牙对象 if(bluetooth_item_bean.getBluetoothDevice_Adress()==null){ Toast.makeText(Ble1Activity.this,"请扫描蓝牙",Toast.LENGTH_SHORT).show(); return; } BluetoothDevice device = bluetoothAdapter.getRemoteDevice(bluetooth_item_bean.getBluetoothDevice_Adress()); //根据蓝牙地址获取设备信息 if(device != null && bluetooth_item_bean.getBluetoothDevice_ConectStatus() != "连接成功") { //判空校验 mGatt = device.connectGatt(Ble1Activity.this, true, mBluetoothGattCallback); //进行连接 //连接后改写状态 bluetooth_item_bean.bluetoothDevice_ConectStatus = "连接中..."; for (int j = 0; j < BluetoothDevice_Info.size(); j++) { if(BluetoothDevice_Info.get(j).getBluetoothDevice_Adress().equals(bluetooth_item_bean.getBluetoothDevice_Adress())){ //移除蓝牙设备重新添加 BluetoothDevice_Info.remove(j); break; } } BluetoothDevice_Info.add(bluetooth_item_bean); adapter.notifyDataSetChanged(); }else{ //断开蓝牙连接 mGatt.disconnect(); mGatt.close(); //修改状态 bluetooth_item_bean = BluetoothDevice_Info.get(i); //获取当前click事件的蓝牙对象 //连接后改写状态 bluetooth_item_bean.bluetoothDevice_ConectStatus = "尚未匹配"; for (int j = 0; j < BluetoothDevice_Info.size(); j++) { if(BluetoothDevice_Info.get(j).getBluetoothDevice_Adress().equals(bluetooth_item_bean.getBluetoothDevice_Adress())){ //移除蓝牙设备重新添加 BluetoothDevice_Info.remove(j); break; } } BluetoothDevice_Info.add(bluetooth_item_bean); adapter.notifyDataSetChanged(); } } }); } //界面按钮点击事件 @RequiresAPI(API = Build.VERSION_CODES.JELLY_BEAN_MR2) @OverrIDe public voID onClick(VIEw vIEw) { switch (vIEw.getID()){ case R.ID.startScale: //扫描 *** 作 (扫描一定的事件就自动关闭扫描) //每次扫描之前都断开已经有的蓝牙连接 if(mGatt != null){ mGatt.disconnect(); mGatt.close(); } BluetoothDevice_Info.clear(); progressbar.setVisibility(VIEw.VISIBLE); bluetoothAdapter.startLeScan(mLescaleCallback); //安卓5.0以上后用新的扫描API /* bluetoothManager = (BluetoothManager) getSystemService(Context.BLUetoOTH_SERVICE); if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) { //LogUtil.e("系统版本:","<7.0"); bluetoothManager.getAdapter() .startLeScan(mLescaleCallback); } else {//安卓7.0及以上的方案 //LogUtil.e("系统版本:",">=7.0"); mBluetoothLeScanner = bluetoothManager.getAdapter().getBluetoothLeScanner(); mBluetoothLeScanner.startScan(scanCallback); }*/ handler.postDelayed(new Runnable() { @OverrIDe public voID run() { bluetoothAdapter.stopLeScan(mLescaleCallback); progressbar.setVisibility(VIEw.GONE); } },SCALE_PERIOD); break; case R.ID.stopScale: //停止扫描 progressbar.setVisibility(VIEw.GONE); bluetoothAdapter.stopLeScan(mLescaleCallback); break; case R.ID.startRead: checkStartRead = true; //校验是否有设备连接 if(bluetooth_item_bean != null && bluetooth_item_bean.bluetoothDevice_ConectStatus != null && bluetooth_item_bean.getBluetoothDevice_ConectStatus().equals("连接成功")){ //Toast.makeText(Ble1Activity.this,"已经连接到蓝牙",Toast.LENGTH_SHORT).show(); //return; }else{ Toast.makeText(Ble1Activity.this,"尚未连接蓝牙",Toast.LENGTH_SHORT).show(); return; } BluetoothGattCharacteristic characteristic= mGatt.getService(UUID.fromString(READ_SERVICE_UUID)) .getCharacteristic(UUID.fromString(READ_characteristics_UUID)); mGatt.readCharacteristic(characteristic); break; case R.ID.stopRead: checkStartRead = false; //校验是否有设备连接 if(bluetooth_item_bean != null && bluetooth_item_bean.bluetoothDevice_ConectStatus != null && bluetooth_item_bean.getBluetoothDevice_ConectStatus().equals("连接成功")){ //Toast.makeText(Ble1Activity.this,"已经连接到蓝牙",Toast.LENGTH_SHORT).show(); //return; }else{ Toast.makeText(Ble1Activity.this,"尚未连接蓝牙",Toast.LENGTH_SHORT).show(); return; } break; } }
7.权限处理
//请求权限之后的请求处理 // //执行完上面的请求权限后,系统会d出提示框让用户选择是否允许改权限。选择的结果可以在回到接口中得知: @OverrIDe public voID onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if(requestCode==REQUEST_CODE_ACCESS_COARSE_LOCATION){ if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { //用户允许改权限,0表示允许,-1表示拒绝 PERMISSION_GRANTED = 0, PERMISSION_DENIED = -1 //permission was granted, yay! Do the contacts-related task you need to do. //这里进行授权被允许的处理 } else { //permission denIEd, boo! disable the functionality that depends on this permission. //这里进行权限被拒绝的处理 } } else { super.onRequestPermissionsResult(requestCode, permissions, grantResults); } } //检测定位是否打开 public static final boolean isLocationEnable(Context context) { LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); boolean networkProvIDer = locationManager.isProvIDerEnabled(LocationManager.NETWORK_PROVIDER); boolean gpsProvIDer = locationManager.isProvIDerEnabled(LocationManager.GPS_PROVIDER); if (networkProvIDer || gpsProvIDer) return true; return false; } //如果没有打开,进入定位设置界面,让用户自己选择是否打开定位。选择的结果获取: private voID setLocationService() { Intent locationIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); this.startActivityForResult(locationIntent, REQUEST_CODE_LOCATION_SETTINGS); } @OverrIDe protected voID onResume() { super.onResume(); //确保蓝牙可以使用,如果不可以使用一个d窗 if(!bluetoothAdapter.enable()){ Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(intent,REQUEST_ENABLE_BLE); } } @OverrIDe protected voID onActivityResult(int requestCode, int resultCode, Intent data) { //不同打开蓝牙 if(requestCode ==REQUEST_ENABLE_BLE && resultCode == RESulT_CANCELED){ finish(); return; } //定位 if (requestCode == REQUEST_CODE_LOCATION_SETTINGS) { if (isLocationEnable(this)) { //定位已打开的处理 } else { //定位依然没有打开的处理 Toast.makeText(Ble1Activity.this,"请打开GPS",Toast.LENGTH_SHORT).show(); } } else super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data); }
8.扫描的回调函数
//打开蓝牙后扫描的回调函数 //扫描到设备之后的回调方法 安卓5.0以下 @RequiresAPI(API = Build.VERSION_CODES.JELLY_BEAN_MR2) //这是一个因为版本号过高所以得进行控制的 private BluetoothAdapter.LeScanCallback mLescaleCallback = new BluetoothAdapter.LeScanCallback() { @OverrIDe public voID onLeScan(final BluetoothDevice device, int RSSi, byte[] scanRecord) { if(device.getname()!=null && device.getAddress()!=null) { runOnUiThread(new Runnable() { @OverrIDe public voID run() { final Bluetooth_item_Bean bean = new Bluetooth_item_Bean(); bean.bluetoothDevice_name = device.getname(); bean.bluetoothDevice_Adress = device.getAddress(); int bondState = device.getBondState(); //对蓝牙状态进行判断 switch (bondState){ case BluetoothDevice.BOND_NONE: bean.bluetoothDevice_ConectStatus = "尚未匹配"; break; case BluetoothDevice.BOND_BONDING: bean.bluetoothDevice_ConectStatus = "匹配中"; break; case BluetoothDevice.BOND_BONDED: bean.bluetoothDevice_ConectStatus = "匹配成功"; } if(BluetoothDevice_Info.contains(bean)) { //如果集合中已经包含相同的对象,则不添加进去 }else{ BluetoothDevice_Info.add(bean); adapter.notifyDataSetChanged(); } } }); } } };
9.蓝牙连接的回调函数
//连接的回调函数 /** * @description 连接后的回调函数 * @param * @return * @author zhujialan * @time 2021/3/4 */ @RequiresAPI(API = Build.VERSION_CODES.JELLY_BEAN_MR2) //这是一个因为版本号过高所以得进行控制的 BluetoothGattCallback mBluetoothGattCallback=new BluetoothGattCallback() { //连接回调 @OverrIDe public voID onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { super.onConnectionStateChange(gatt, status, newState); if (newState == BluetoothProfile.STATE_CONNECTED) { //System.out.println("连接成功"); gatt.discoverServices(); //跳转到发现蓝牙服务 }else if (newState == BluetoothProfile.STATE_disCONNECTED) { //断开连接 //System.out.println("断开连接"); //连接后改写状态 bluetooth_item_bean.bluetoothDevice_ConectStatus = "尚未连接"; for (int j = 0; j < BluetoothDevice_Info.size(); j++) { if(BluetoothDevice_Info.get(j).getBluetoothDevice_Adress().equals(bluetooth_item_bean.getBluetoothDevice_Adress())){ //移除蓝牙设备重新添加 BluetoothDevice_Info.remove(j); break; } } BluetoothDevice_Info.add(bluetooth_item_bean); /*adapter.notifyDataSetChanged();*/ //只有在线程中才可以进行修改 Ble1Activity.this.runOnUiThread(new Runnable() { public voID run() { adapter.notifyDataSetChanged(); } }); mGatt.close(); } }
10.发现服务
/** * @description 发现服务 * @param * @return * @author zhujialan * @time 2021/3/4 */ @OverrIDe public voID onServicesdiscovered(BluetoothGatt gatt, int status) { super.onServicesdiscovered(gatt, status); //System.out.println("onServicesdiscovered: ======发现服务"); List<BluetoothGattService> services = gatt.getServices(); //System.out.println("onServicesdiscovered有几个服务:"+services.size()); //连接后改写状态 bluetooth_item_bean.bluetoothDevice_ConectStatus = "连接成功"; for (int j = 0; j < BluetoothDevice_Info.size(); j++) { if(BluetoothDevice_Info.get(j).getBluetoothDevice_Adress().equals(bluetooth_item_bean.getBluetoothDevice_Adress())){ //移除蓝牙设备重新添加 BluetoothDevice_Info.remove(j); break; } } BluetoothDevice_Info.add(bluetooth_item_bean); /*adapter.notifyDataSetChanged();*/ //只有在线程中才可以进行修改 Ble1Activity.this.runOnUiThread(new Runnable() { public voID run() { adapter.notifyDataSetChanged(); } }); }
11.读写数据
/** * @description 读数据 * @param * @return * @author zhujialan * @time 2021/3/4 */ @OverrIDe public voID onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { super.onCharacteristicRead(gatt, characteristic, status); for (int i = 0; i < characteristic.getValue().length; i++) { System.out.println("onCharacteristicRead:读出的值为 "+characteristic.getValue()[i]); //读出的应该是特征数量的数据 } //直接有UUID写 System.out.println("写入..."); BluetoothGattCharacteristic characteristic = mGatt.getService(UUID.fromString(READ_SERVICE_UUID)).getCharacteristic(UUID.fromString(READ_characteristics_UUID)); characteristic.setValue("AAAA123456789FFFF"); mGatt.writeCharacteristic(characteristic); } /** * @description 写数据 * @param * @return * @author zhujialan * @time 2021/3/4 */ @OverrIDe public voID onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { super.onCharacteristicWrite(gatt, characteristic, status); if (status==BluetoothGatt.GATT_SUCCESS){ System.out.println("onCharacteristicWrite: 写入成功"); //gatt.readCharacteristic(characteristic); //onServicesdiscovered(gatt,status); }else { System.out.println("onCharacteristicWrite: 失败"); } } };
结尾
时间比较仓促只来得及简单贴上代码。有一些细小的BUG等我有时间再慢慢调整。
关于读写那边是有些许问题的,相关的信息可以点击参考文档进行修改。
感谢大家阅读。
总结
以上是内存溢出为你收集整理的Android完成BLE5.0低功耗蓝牙扫描界面与功能并读写数据全部内容,希望文章能够帮你解决Android完成BLE5.0低功耗蓝牙扫描界面与功能并读写数据所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)