Android蓝牙功能开发(低功耗与经典)

目录

一、第一种框架集成方式

1.在项目根目录的build.gradle文件中,添加如下配置:

2.在app module的build.gradle中,添加依赖:

3.使用前先在你应用的Application中调init方法初始化框架

4.然后必须调用enableBluetooth()方法开启蓝牙功能,你可以在activity中调用:

5.如果是低功耗蓝牙,需要设置配置项,经典蓝牙忽略跳过这一步即可:

6.开启蓝牙能力后,接着你就可以开始进行蓝牙设备扫描,其中,type 为蓝牙设备类型(经典蓝牙或低功耗蓝牙):

7.一旦扫描到设备,你就可以找到目标设备并连接:

8.设备连接成功后,你可以开始跟设备进行通信:

9.那么如何接收蓝牙设备返回给你的数据呢,很简单,在Receiver中接收:

10.最后,调用以下方法去主动断开连接并释放资源 :

第二种集成方式

1.由于是代码引入,故无需像第一步那样进行库的引入,直接在Application中初始化。

2.蓝牙界面

3.UUidStateBean对象

4.蓝牙信息对象BletoothInfoBen

5.进度对话框

6.ble_servies_select_dialog布局

7.gble_layout蓝牙布局


        Android 蓝牙开发,很多项目会使用到,自己去摸索封装或者引用其他框架,也能解决部分问题。为何说是部分问题,Android蓝牙分为低功耗版与经典版,经典版是可以直接选择即可实现链接,低功耗版是需要配置uuid。故推荐一个框架,下面来分享使用教程。分两部分第一部分是直接使用框架,第二部分是修改框架源码,使用哪一种方式可以结合自己的需要。Android开发建议使用Android蓝牙调试工具app初步调试使用,这里推荐BLE调试助手app,各大应用市场都可以下载。BLE调试助手首页展示。 

Java语言版本地址:https://github.com/g-HJY/HBluetooth
Kotlin语言版本地址:https://github.com/g-HJY/Kotlin-HBluetooth (暂停维护)

一、第一种框架集成方式

         首先是集成方式,当然你可以直接在github上将整个项目下载下来,也可以将其以依赖的形式集成到你的项目中,具体步骤如下:

1.在项目根目录的build.gradle文件中,添加如下配置:

allprojects {
	repositories {
		...
		maven { url 'https://jitpack.io' }
	}
}

2.在app module的build.gradle中,添加依赖:

dependencies {
     implementation 'com.github.g-HJY:HBluetooth:V1.3.6'
}

3.使用前先在你应用的Application中调init方法初始化框架

public class XiaoYaApp extends MultiDexApplication {

    @Override
    public void onCreate() {
        super.onCreate();
        HBluetooth.init(this);
    }

}

4.然后必须调用enableBluetooth()方法开启蓝牙功能,你可以在activity中调用:

//开启蓝牙功能
HBluetooth.getInstance().enableBluetooth()

5.如果是低功耗蓝牙,需要设置配置项,经典蓝牙忽略跳过这一步即可:

        分别是主服务UUID(withServiceUUID)、读写特征值UUID(withWriteCharacteristicUUID)、通知UUID(withNotifyCharacteristicUUID)以及是否设置最大传输单元(setMtu不设置不用调)等; 您还可以设置分包发送的时间间隔和包长度

     //请填写你自己设备的UUID
        //低功耗蓝牙才需要如下配置BleConfig,经典蓝牙不需要new HBluetooth.BleConfig()
        HBluetooth.BleConfig bleConfig = new HBluetooth.BleConfig();
        bleConfig.withServiceUUID("0000fe61-0000-1000-8000-00805f9b34fb")
                 .withWriteCharacteristicUUID("0000fe61-0000-1000-8000-00805f9b34fb")
                 .withNotifyCharacteristicUUID("0000fe61-0000-1000-8000-00805f9b34fb")
                //命令长度大于20个字节时是否分包发送,默认false,分包时可以调两参方法设置包之间发送间隔
                //.splitPacketToSendWhenCmdLenBeyond(false)
                //useCharacteristicDescriptor 默认false
                //.useCharacteristicDescriptor(false)
                .setMtu(200, new BleMtuChangedCallback() {
                    @Override
                    public void onSetMTUFailure(int realMtuSize, BluetoothException bleException) {
                        Log.i(TAG, "bleException:" + bleException.getMessage() + "  realMtuSize:" + realMtuSize);
                    }
 
                    @Override
                    public void onMtuChanged(int mtuSize) {
                        Log.i(TAG, "Mtu set success,mtuSize:" + mtuSize);
                    }
                });
     //低功耗蓝牙才需要调setBleConfig
	HBluetooth.getInstance().setBleConfig(bleConfig);

6.开启蓝牙能力后,接着你就可以开始进行蓝牙设备扫描,其中,type 为蓝牙设备类型(经典蓝牙或低功耗蓝牙):

           HBluetooth.getInstance()
                .scan(type, new ScanCallBack() {
            @Override
            public void onScanStart() {
                Log.i(TAG, "开始扫描");
            }
 
            @Override
            public void onScanning() {
                Log.i(TAG, "扫描中");
            }
 
            @Override
            public void onError(int errorType, String errorMsg) {
 
            }
 
            @Override
            public void onScanFinished(List<BluetoothDevice> bluetoothDevices) {
                Log.i(TAG, "扫描结束");
                if (bluetoothDevices != null && bluetoothDevices.size() > 0) {
                    list.clear();
                    list.addAll(bluetoothDevices);
                    adapter.notifyDataSetChanged();
                }
            }
        });
 
 
或者,如果你想在第一步操作后直接进行扫描,则可以这样调用:
        HBluetooth.getInstance()
                .enableBluetooth()
                .scan(type, new ScanCallBack() {
            @Override
            public void onScanStart() {
                Log.i(TAG, "开始扫描");
            }
 
            @Override
            public void onScanning() {
                Log.i(TAG, "扫描中");
            }
 
            @Override
            public void onError(int errorType, String errorMsg) {
 
            }
 
            @Override
            public void onScanFinished(List<BluetoothDevice> bluetoothDevices) {
                Log.i(TAG, "扫描结束");
                if (bluetoothDevices != null && bluetoothDevices.size() > 0) {
                    list.clear();
                    list.addAll(bluetoothDevices);
                    adapter.notifyDataSetChanged();
                }
            }
        });

7.一旦扫描到设备,你就可以找到目标设备并连接:

         HBluetooth.getInstance()
           .connect(device, new ConnectCallBack() {
 
                       @Override
                       public void onConnecting() {
                           Log.i(TAG, "连接中...");
                       }
 
                       @Override
                       public void onConnected(Sender sender) {
                           Log.i(TAG, "连接成功,isConnected:" + mHBluetooth.isConnected());
                           //调用发送器发送命令
                           byte[] demoCommand = new byte[]{0x01, 0x02};
                           sender.send(demoCommand, new SendCallBack() {
                               @Override
                               public void onSending(byte[] command) {
                                   Log.i(TAG, "命令发送中...");
                               }
 
                               @Override
                               public void onSendFailure(BluetoothException bleException) {
                                   Log.e("mylog", "发送命令失败->" + bleException.getMessage());
                               }
                           });
                       }
 
                       @Override
                       public void onDisConnecting() {
                           Log.i(TAG, "断开连接中...");
                       }
 
                       @Override
                       public void onDisConnected() {
                           Log.i(TAG, "已断开连接,isConnected:" + mHBluetooth.isConnected());
                       }
 
                       @Override
                       public void onError(int errorType, String errorMsg) {
                           Log.i(TAG, "错误类型:" + errorType + " 错误原因:" + errorMsg);
                       }
 
                       //低功耗蓝牙才需要BleNotifyCallBack
                       //经典蓝牙可以只调两参方法connect(BluetoothDevice device, ConnectCallBack connectCallBack)
                   }, new BleNotifyCallBack() {
                       @Override
                       public void onNotifySuccess() {
                           Log.i(TAG, "打开通知成功");
                       }
 
                       @Override
                       public void onNotifyFailure(BluetoothException bleException) {
                           Log.i(TAG, "打开通知失败:" + bleException.getMessage());
                       }
                   });

8.设备连接成功后,你可以开始跟设备进行通信:

           HBluetooth.getInstance()
                     .send(demoCommand, new SendCallBack() {
                      @Override
                      public void onSending(byte[] command) {
                             Log.i(TAG, "命令发送中...");
                      }
 
                      @Override
                      public void onSendFailure(BluetoothException bleException) {
                             Log.e("mylog", "发送命令失败->" + bleException.getMessage());
                      }
                      });

9.那么如何接收蓝牙设备返回给你的数据呢,很简单,在Receiver中接收:

          public void initListener() {
              HBluetooth.getInstance().setReceiver(new ReceiveCallBack() {
                  @Override
                  public void onReceived(DataInputStream dataInputStream, byte[] result) {
                      // 打开通知后,设备发过来的数据将在这里出现
                      Log.e("mylog", "收到蓝牙设备返回数据->" + Tools.bytesToHexString(result));
                  }
              });
          }

10.最后,调用以下方法去主动断开连接并释放资源 :

            HBluetooth.getInstance().release();

其他APi

1.带设备名称过滤条件的扫描:

public void scan(@BluetoothType int scanType, int timeUse, ScanFilter filter, ScanCallBack scanCallBack);

public void scan(@BluetoothType int scanType, ScanFilter filter, ScanCallBack scanCallBack);

2.设置连接超时:

HBluetooth.getInstance().setConnectTimeOut(5000);

3.BleConfig(BLE)设置分包发送时间间隔(默认20ms)及包长度(默认20个字节):

public BleConfig splitPacketToSendWhenCmdLenBeyond(boolean splitPacketToSendWhenCmdLenBeyond, int sendTimeInterval);

public BleConfig splitPacketToSendWhenCmdLenBeyond(boolean splitPacketToSendWhenCmdLenBeyond, int sendTimeInterval, int eachSplitPacketLen);

4.开启断开后自动重连机制,默认关闭重连:

HBluetooth.getInstance().openReconnect(3, 4000);


第二种集成方式

         与第一种区别,第二种是修改第一种源码实现的蓝牙连接,主要是针对低功耗蓝牙适配,第一种是直接在初始化的时候配置uuid,实现要先通过测试工具拿到uuid或者由对方给出uuid,而本demo是通过弹出对话框的方式,由用户去选择,但是也是需要知道对方传递数据的uuid是多少,这就需要用到蓝牙调试助手BLE调试助手。下面是蓝牙调试助手演示界面选择包含读写、通知的uuid去尝试看能否拿到数据,拿到数据的就是低功耗蓝牙的可用uuid。

资源地址:

   https://download.csdn.net/download/shi450561200/88621789

由于模块引入hawk作为已选择的蓝牙数据存储,故还需引入hawk框架。
//hawk数据存储
implementation "com.orhanobut:hawk:2.0.1"

1.由于是代码引入,故无需像第一步那样进行库的引入,直接在Application中初始化。

public class XiaoYaApp extends MultiDexApplication {

    @Override
    public void onCreate() {
        super.onCreate();
        //蓝牙
        HBluetooth.init(this);//初始化蓝牙
        HBluetooth.getInstance()
                .setConnectTimeOut(4000);
    }

}

2.蓝牙界面


/**
 * 经典
 * 蓝牙
 */

public class GeNBleActivity extends AppCompatActivity implements HandlerUtils.OnReceiveMessageListener {

    private RecyclerView recycleview;
    private Switch switchBt;
    private SwipeRefreshLayout swipeLayout;
    private HandlerUtils.HandlerHolder myHandlerUtils;
    private int clickState = 1999;//防止误碰蓝牙连接
    private TextView blueTxt;//蓝牙数据显示
    private LinearLayout finish;
    private String tys = "";//

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.gble_layout);
        FullScreenrUtils.initBar(this);//全屏
        StatusBarUtils.setLightStatusBar(this, true);//设置状态栏黑色字体

//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                registerCustomBroadcastReceiver();
//            }
//        }).start();

        tys = getIntent().getExtras().get("typs").toString();

        initView();
    }

    /**
     * 刷新
     * 数据
     */
    private int refreshCount = 0;

    private void refreshView() {

        swipeLayout.setColorSchemeColors(ContextCompat.getColor(this, R.color.colorPrimary));
        swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {

                clickState = 0;
                //开关试图打开
                switchBt.setSwitchPadding(2);
                switchBt.setChecked(true);

                //开关试图打开
                if (refreshCount > 0) {
                    //搜索蓝牙子线程中执行
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            HBluetooth.getInstance().release();
//                            HBluetooth.getInstance().openReconnect(0, 0);//关闭重连
                            initData();
                        }
                    }).start();
                } else {
                    switchBt.setSwitchPadding(2);
                    switchBt.setChecked(true);
                }

                //1.5s后关掉下拉刷新
                swipeLayout.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        swipeLayout.setRefreshing(false);
                        refreshCount = refreshCount + 1;
                    }
                }, 2000);
            }
        });

    }

    /**
     * 初始化
     * 数据
     */
    private static final int REQUEST_ENABLE_BT = 0xff000099;//启用蓝牙请求码

    @SuppressLint("WrongConstant")
    private void initData() {

        int type = 2;

        // 或者,如果你想在第一步操作后直接进行扫描,则可以这样调用:
        HBluetooth.getInstance()
                .enableBluetooth()
                .scan(type, 3000, new ScanCallBack() {
                    @Override
                    public void onScanStart() {
//                        Log.i(TAG, "==开始扫描==");
                    }

                    @Override
                    public void onScanning(List<BluetoothDevice> scannedDevices, BluetoothDevice currentScannedDevice) {
//                        Log.i(TAG, "==扫描中==");
                        if (scannedDevices != null && scannedDevices.size() > 0) {

                            list.clear();
                            list.addAll(scannedDevices);

                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    bluetoothDevicesAdapter.notifyDataSetChanged();
                                }
                            });

                        }
                    }

                    @Override
                    public void onError(int errorType, String errorMsg) {
//                        Log.d(TAG, "onError");
                    }

                    @Override
                    public void onScanFinished(List<BluetoothDevice> bluetoothDevices) {
//                        Log.d(TAG, "==onScanFinished===");
                        if (bluetoothDevices != null && bluetoothDevices.size() > 0) {
                            list.clear();
                            list.addAll(bluetoothDevices);

                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    bluetoothDevicesAdapter.notifyDataSetChanged();

                                }
                            });
                        }

                    }

                });

    }

    //蓝牙设备适配器
    private MyDemoBluetoothDevicesAdapter bluetoothDevicesAdapter;
    private List<BluetoothDevice> list = new ArrayList<>();

    private static final String TAG = "TAG";
    private String bleDevicesAdress = "";

    private void initView() {

        XiaoYaApp.setUuidTmp("");
//        XiaoYaApp.setUuidTmp("0000ffe0-0000-1000-8000-00805f9b34fb");

        finish = findViewById(R.id.finish);

        recycleview = findViewById(R.id.recycleview);
        switchBt = findViewById(R.id.switch_bt);

        swipeLayout = findViewById(R.id.swipeLayout);
        blueTxt = findViewById(R.id.blue_txt);

        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(GeNBleActivity.this);
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        recycleview.setLayoutManager(linearLayoutManager);
        recycleview.setHasFixedSize(true);

        bluetoothDevicesAdapter = new MyDemoBluetoothDevicesAdapter(GeNBleActivity.this, list);

        recycleview.setAdapter(bluetoothDevicesAdapter);
        myHandlerUtils = new HandlerUtils.HandlerHolder(GeNBleActivity.this);

        bluetoothDevicesAdapter.setMyOnItemClickListener(new MyDemoBluetoothDevicesAdapter.OnItemClickListener() {

            @Override
            public void OnItemClick(View view, int position) {

                if (view.getId() == R.id.tv_cancle_conn) {
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            HBluetooth.getInstance().release();
//                            HBluetooth.getInstance().openReconnect(0, 0);//关闭重连
                        }
                    }).start();
                } else {

                    if (clickState == 1999) {
                        return;
                    }
                    clickState = 1999;

                    myListPosition = position;

                    try {

                        //4、连接
//                    Log.e(getPackageName(), "===开始连接=Exception===");
//                    Log.e(TAG, "==扫描uuid==" + Arrays.toString(list.get(position).getUuids()));

                        //保存蓝牙Address数据,供直连使用。
                        bleDevicesAdress = list.get(position).getAddress();


                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                HBluetooth.getInstance().release();
//                                HBluetooth.getInstance().openReconnect(0, 0);//关闭重连
                                initListener();
                                connectData(list.get(position));
                            }
                        }).start();

                    } catch (Exception e) {

                    }

                }

            }

            @Override
            public void OnItemLonClick(int position) {

            }
        });


        //选择
        switchBt.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

                if (!getPermission()) {

                    return;
                }

                if (isChecked) {

                    //打开蓝牙
                    switchBt.setSwitchPadding(2);

                    //扫描蓝牙
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            HBluetooth.getInstance().release();
//                            HBluetooth.getInstance().openReconnect(0, 0);//关闭重连
                            initData();
                        }
                    }).start();

                } else {
                    //关闭蓝牙

                    switchBt.setSwitchPadding(1);

                    //关闭蓝牙
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            HBluetooth.getInstance().release();
//                            HBluetooth.getInstance().openReconnect(0, 0);//关闭重连
                        }
                    }).start();
                    list.clear();
                    bluetoothDevicesAdapter.notifyDataSetChanged();
                }
            }
        });
        clickState = 0;
        refreshView();

        //一进入页面就取一次缓存
//        MyEventManager.postMsg("=getcahegetcahe=", "getCache");

        getCacheData();

        finish.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        //打开蓝牙搜索
        switchBt.setSwitchPadding(2);
        switchBt.setChecked(true);

    }

    /**
     * 修改
     * 蓝牙数据
     */
    private int myListPosition = 0;

    private void upBlutoothSata(boolean isConnnted) {

        if (isConnnted) {
            XiaoYaApp.getBlDevices().setType(999);
//            Toast.makeText(GeNBleActivity.this, "蓝牙连接成功", Toast.LENGTH_SHORT).show();
        } else {
            XiaoYaApp.getBlDevices().setType(333);
//            Toast.makeText(GeNBleActivity.this, "蓝牙已断开", Toast.LENGTH_SHORT).show();
        }

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
//                bluetoothDevicesAdapter.notifyItemChanged(myListPosition, XiaoYaApp.getBlDevices());

                bluetoothDevicesAdapter.notifyDataSetChanged();
//                MyEventManager.postMsg("==更新页面状态==" + XiaoYaApp.getBlDevices().getType(), "formAndroid");

                myHandlerUtils.sendEmptyMessageDelayed(UPDATE_DEVICESTYPE, 100);
//                XiaoYaApp.getBlDevices().setType(2);
            }
        });

    }

    /**
     * 连接
     * 蓝牙
     */

    private void connectData(BluetoothDevice device) {

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                showProgressDialog();
            }
        });

        //保存蓝牙信息
        Logger.d("===开始连接--====" + (device != null));

        isConneted = false;//蓝牙能否重连,false表示不重连
//        Log.d(TAG, "===connectData:开始 000===");
        if (device != null) {
            XiaoYaApp.setBlDevices(device);//保存全局的device
        } else {
            cancleDialogProgress();
            return;
        }
//        Log.d(TAG, "===connectData:开始 1111===");

        HBluetooth.getInstance()
                .setConnectTimeOut(4000)
                .connect(device, new ConnectCallBack() {
                    @Override
                    public void onConnecting() {
                        Logger.d("=====连接中=====");
                    }

                    @Override
                    public void onConnected(Sender sender) {
                        clickState = 0;

                        Logger.d("=====连接成功=====");
                        myHandlerUtils.sendEmptyMessageDelayed(TIPS_SELECT_UUID, 3000);

                        //调用发送器发送命令
                        byte[] demoCommand = new byte[]{0x01, 0x02};
                        sender.send(demoCommand, new SendCallBack() {
                            @Override
                            public void onSending(byte[] command) {
//                                Log.i(TAG, "==命令发送中..==");
                            }

                            @Override
                            public void onSendFailure(BluetoothException bleException) {
//                                Log.d(TAG, "==发送命令失败->===" + bleException.getMessage());
                            }
                        });

                    }

                    @Override
                    public void onDisConnecting() {

//                        Log.d(TAG, "===断开连接中...===");
                    }

                    @Override
                    public void onDisConnected() {
                        clickState = 0;
                        Logger.d("=====已断开连接=====");

                        myHandlerUtils.sendEmptyMessage(UPDATE_BLT_DISC_STATE);//修改蓝牙为断开状态
//                        Log.d(TAG, "===断开...===");
                        cancleDialogProgress();
                    }

                    @Override
                    public void onError(int errorType, String errorMsg) {

//                        Log.d(TAG, "==错误类型:" + errorType + " ===错误原因:" + errorMsg);
                    }

                    //低功耗蓝牙才需要BleNotifyCallBack
                    //经典蓝牙可以只调两参方法connect(BluetoothDevice device, ConnectCallBack connectCallBack)
                }, new BleNotifyCallBack() {
                    @Override
                    public void onNotifySuccess() {
                        isConneted = true;
                        myHandlerUtils.sendEmptyMessageDelayed(UPDATE_BLT_CONNTED_STATE, 3000);//修改蓝牙显示连接状态

                        cancleDialogProgress();
//                        senDMsgDataDe();
                        Logger.d("===打开通知成功--====");

                    }

                    @Override
                    public void onNotifyFailure(BluetoothException bleException) {

                        cancleDialogProgress();
                        Logger.d("===打开通知失败--====");

                    }
                });
    }


    /**
     * 接收
     * 数据
     * 监听
     */
    public void initListener() {
        HBluetooth.getInstance().setReceiver(new ReceiveCallBack() {
            @Override
            public void onReceived(DataInputStream dataInputStream, byte[] result) {
                Logger.d("===接收数据====" + Tools.bytesToHexString(result));
                // 打开通知后,设备发过来的数据将在这里出现
            }
        });
        HBluetooth.getInstance().openReconnect(200, 4000);
    }

    /**
     * Create a
     * BroadcastReceiver
     * for ACTION_FOUND.
     * 扫描发现设备
     * 蓝牙配对并连接
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == REQUEST_ENABLE_BT) {//打开蓝牙回调
            if (resultCode == RESULT_OK) {
//                Log.d("TAG", "====onActivityResult:成功======");
            }
        }

    }

    @Override
    protected void onResume() {
        super.onResume();

    }

    @Override
    protected void onStop() {
        super.onStop();

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        HBluetooth.getInstance().release();
//        HBluetooth.getInstance().openReconnect(0, 0);//关闭重连
    }

    /**
     * 重连
     * 监听
     */

    private static final int UPDATE_BLT_CONNTED_STATE = 0x000666;
    private static final int UPDATE_BLT_DISC_STATE = 0x0000777;
    private static final int TIPS_SELECT_UUID = 0x000888;//提示选择服务id
    private static final int UPDATE_DEVICESTYPE = 1000;
    private static final int SELECT_CONN = 0X0001;

    private boolean isConneted = false;

    @Override
    public void handlerMessage(Message msg) {
        switch (msg.what) {
            case UPDATE_BLT_CONNTED_STATE://修改蓝牙为连接待接收数据状态
                isConneted = true;
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        upBlutoothSata(true);
                    }
                }).start();

                break;
            case UPDATE_BLT_DISC_STATE://修改蓝牙为断开状态
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        upBlutoothSata(false);
                    }
                }).start();

                break;

            case TIPS_SELECT_UUID:
//                Log.d(TAG, "===延时2S显示配置服务UUID: ==" + isConneted);

                showServicesUUid();//延时2S显示配置服务UUID
                break;

            case UPDATE_DEVICESTYPE://修 XiaoYaApp.getBlDevices().setType(2);
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        XiaoYaApp.getBlDevices().setType(2);
                    }
                }).start();

                break;

            case SELECT_CONN:
                oneConnectBle();//选择服务连接
                break;
            default:
                break;
        }
    }

    /**
     * 只连接
     * 蓝牙一次
     */
    private void oneConnectBle() {
        BluetoothDevice bluetoothDevice = XiaoYaApp.getBlDevices();

        new Thread(new Runnable() {
            @Override
            public void run() {

                Logger.d("===连接蓝牙====");
//                Log.d(TAG, "====handleMessage:==只连接蓝牙一次===");
                if (bluetoothDevice != null) {
//                    HBluetooth.getInstance().release();
//                    HBluetooth.getInstance().openReconnect(0, 0);//关闭重连
                    XiaoYaApp.getBlDevices().setType(2);
                    connectData(bluetoothDevice);
                }
            }
        }).start();
    }

    /**
     * 判断权限
     * 是否通过,
     * 如果通过
     * 就初始化
     */
    private boolean mHasPermission; // 是否通过权限

    private boolean getPermission() {

        mHasPermission = checkPermission();
        if (!mHasPermission) {
            // 未获取权限,申请权限
            runOnUiThread(new Runnable() {
                @Override
                public void run() {

                    Toast.makeText(GeNBleActivity.this, "未获取权限,申请权限", Toast.LENGTH_SHORT).show();
                }
            });

            requestPermission();

        } else if (mHasPermission) {
            // 已经获取权限
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(GeNBleActivity.this, "已经获取权限", Toast.LENGTH_SHORT).show();
                }
            });

        }

        return mHasPermission;
    }

    /**
     * 显示UUID
     */

    private void showServicesUUid() {

        mServiceList = new ArrayList<>();
        uUidStateBeanList = new ArrayList<>();
        mServiceList.clear();
        uUidStateBeanList.clear();

        mServiceList = XiaoYaApp.getmServiceList();

        Log.d(TAG, "==showServicesUUid: =mServiceList集合大小==" + (mServiceList == null));

        for (int y = 0; y < mServiceList.size(); y++) {

            UUidStateBean uu = new UUidStateBean();
            uu.setUUid(mServiceList.get(y).getUuid() + "");

            uu.setSelected(false);
            uUidStateBeanList.add(uu);
        }
//        Log.d(TAG, "===showServicesUUid:取消对话框======");
        cancleDialogProgress();

        if (!isConneted && mServiceList != null) {

            showDialog();
//            Toast.makeText(GeNBleActivity.this, "数据", Toast.LENGTH_LONG).show();
        } else {
            BluetoothDevice blethDeviceInfo = XiaoYaApp.getBlDevices();
            saveBleDevicesInfo(blethDeviceInfo.getName(), blethDeviceInfo.getAddress(), "");
        }

    }

    /**
     * 显示UUId
     * 供用户
     * 选择
     */
    private RecyclerView dialogServList;
    private BtUUIDSelectAdapter btUUIDSelectAdapter;
    private List<BluetoothGattService> mServiceList;
    private List<UUidStateBean> uUidStateBeanList;
    private int selectUUidPosition = 0;

    private void showDialog() {

        View view = getLayoutInflater().from(this).inflate(R.layout.ble_servies_select_dialog, null);

        dialogServList = view.findViewById(R.id.dialogServList);
        btUUIDSelectAdapter = new BtUUIDSelectAdapter(GeNBleActivity.this, uUidStateBeanList);

        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(GeNBleActivity.this);
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        dialogServList.setLayoutManager(linearLayoutManager);
        dialogServList.setHasFixedSize(true);

        dialogServList.setAdapter(btUUIDSelectAdapter);

        final AlertDialog dialog = new AlertDialog.Builder(this).create();
        dialog.setCancelable(true);
        dialog.setCanceledOnTouchOutside(false);

        TextView tv_cancle = view.findViewById(R.id.common_dialog_cancel_tv);
        tv_cancle.setText("取消");

        TextView tv_sure = view.findViewById(R.id.common_dialog_confirm_tv);
        tv_sure.setText("确定");
        tv_sure.setTextColor(Color.parseColor("#ff333333"));
        TextView tv_title = view.findViewById(R.id.common_dialog_title_tv);
        tv_title.setText("请选择可用UUID");

        //确定
        tv_sure.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                BluetoothDevice blethDevice = XiaoYaApp.getBlDevices();

                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        HBluetooth.getInstance().release();
//                        HBluetooth.getInstance().openReconnect(0, 0);//关闭重连
                        String uuidServices = uUidStateBeanList.get(selectUUidPosition).getUUid() + "" + XiaoYaApp.getUuidTmp();
                        XiaoYaApp.setUuidTmp(uuidServices + "");

                        //取缓存

                        myHandlerUtils.sendEmptyMessageDelayed(SELECT_CONN, 200);

                        myHandlerUtils.sendEmptyMessageDelayed(UPDATE_BLT_CONNTED_STATE, 1000);

                        //保存蓝牙信息
                        saveBleDevicesInfo(blethDevice.getName(), blethDevice.getAddress(), uuidServices);

                        dialog.dismiss();

                    }
                }).start();


            }
        });

        //取消对话框
        tv_cancle.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });

        dialog.show();
        dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
        //设置位置窗体
        Window window = dialog.getWindow();
        window.setGravity(Gravity.CENTER);
//        WindowManager.LayoutParams lp = window.getAttributes();
//        lp.dimAmount =0.0f;
//        lp.x = 0; //新位置X坐标
//        lp.y = -400; //新位置Y坐标
//        dialog.onWindowAttributesChanged(lp);
        window.setContentView(view);

        dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);//弹框
        dialog.getWindow().setLayout((this.getWindowManager().getDefaultDisplay().getWidth() / 5 * 3), LinearLayout.LayoutParams.WRAP_CONTENT);
        dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
        btUUIDSelectAdapter.notifyDataSetChanged();

        btUUIDSelectAdapter.setMyOnItemClickListener(new BtUUIDSelectAdapter.OnItemClickListener() {
            @Override
            public void OnItemClick(View view, int position) {

                selectUUidPosition = position;

                for (int y = 0; y < uUidStateBeanList.size(); y++) {

                    uUidStateBeanList.get(y).setSelected(false);

                }

                UUidStateBean uUidStateBean = new UUidStateBean();
                uUidStateBean.setSelected(true);
                uUidStateBean.setUUid(uUidStateBeanList.get(position).getUUid() + "");
                uUidStateBeanList.set(position, uUidStateBean);

                btUUIDSelectAdapter.notifyDataSetChanged();
            }

            @Override
            public void OnItemLonClick(int position) {

            }
        });
    }

    /**
     * 发送
     * 数据
     */
    public void senDMsgDataDe() {

//        MyEventManager.postMsg("==拉取数据请求==" + strHex, "formAndroid");
        byte[] demoCommand = BlueToothUtils.hex2Byte("ff fe 0b 27 01 d0 00 17 04 03 0f 1e 00");
//        byte[] demoCommand = BlueToothUtils.hex2Byte(strHex);

        int s = 0;
        while (true) {
            s++;
            if (s > 2) {
                break;
            }
            try {
                Thread.sleep(1500);

                HBluetooth.getInstance()
                        .send(demoCommand, new SendCallBack() {
                            @Override
                            public void onSending(byte[] command) {
//                                Log.d(TAG, "命令发送中123...");
                            }

                            @Override
                            public void onSendFailure(BluetoothException bleException) {
//                                Log.d(TAG, "发送命令失败->" + bleException.getMessage());
                            }
                        });

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }


    /**
     * 申请
     * 权限
     */
    private void requestPermission() {
        ActivityCompat.requestPermissions(this, NEEDED_PERMISSIONS, PERMISSION_REQUEST_CODE);
    }

    /**
     * @return 检查
     * 是否
     * 已经
     * 授予权限
     */
    private boolean checkPermission() {
        for (String permission : NEEDED_PERMISSIONS) {
            if (ActivityCompat.checkSelfPermission(this, permission)
                    != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }

        return true;
    }

    private static final int PERMISSION_REQUEST_CODE = 0;
    // 两个权限需要动态申请
    private static final String[] NEEDED_PERMISSIONS = new String[]{
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
    };

    /**
     * 监听从uni-app
     * 传过来的蓝牙uuid
     * 缓存数据
     */
    private String cacheServicesId = "";
    private List<BletoothInfoBen> blueListInfo;//蓝牙设备信息

    private void getCacheData() {

        blueListInfo = new ArrayList<>();
        String tp = tys;//页面跳转的时候传过来
        String value = Hawk.get(tp);//取低功耗蓝牙数据
        Gson gson = new Gson();

        Type type = new TypeToken<ArrayList<BletoothInfoBen>>() {
        }.getType();
        blueListInfo = gson.fromJson(value, type);

        StringBuilder stb = new StringBuilder();

        if (blueListInfo==null){
            return;
        }
        // 拿到蓝牙yaservicesID
        if (blueListInfo.size() > 0) {
            for (int y = 0; y < blueListInfo.size(); y++) {
                stb.append(blueListInfo.get(y).getServicesId() + " ");
            }
        }

        XiaoYaApp.setUuidTmp(stb + ",");
        Logger.d("=====获取到缓存蓝牙数据======" + stb);
    }


    /**
     * 保存
     * 蓝牙设备
     * 信息数据
     */
    private void saveBleDevicesInfo(String name, String devicesAdress, String servicesId) {

        long str = System.currentTimeMillis();

        String tp = tys;//页面跳转的时候传过来

        String names = "";

        if (name != null) {
            names = name;
        }

        String times = MyDateUtils.getSimpleYMDDate(str);

        BletoothInfoBen bluetoothDevice = new BletoothInfoBen();

        bluetoothDevice.setName(names);
        bluetoothDevice.setTypes(tp);
        bluetoothDevice.setDeviceId(devicesAdress);
        bluetoothDevice.setServicesId(servicesId);
        bluetoothDevice.setBindTime(times);

        if (blueListInfo==null){
            return;
        }

        blueListInfo.add(bluetoothDevice);

        String result = JSON.toJSONString(blueListInfo);
        Hawk.put(tp, result);//保存低功耗蓝牙

    }

    /**
     * 关闭对话框
     */
    private void cancleDialogProgress() {

        if (dialogProgress != null) {

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    dialogProgress.cancel();
                }
            });

        }

    }

    /**
     * 进度对话框
     */
    private AlertDialog dialogProgress;

    private void showProgressDialog() {

        View view = getLayoutInflater().from(this).inflate(R.layout.ble_dialog_progress_layout, null);

        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(GeNBleActivity.this);
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);

//        TextView progress_dialog_title = view.findViewById(R.id.progress_dialog_title);
//        progress_dialog_title.setText("启动蓝牙连接");

        dialogProgress = new AlertDialog.Builder(this).create();
        dialogProgress.setCancelable(true);
        dialogProgress.setCanceledOnTouchOutside(true);

        dialogProgress.show();
        dialogProgress.getWindow().setBackgroundDrawableResource(android.R.color.transparent);

        //设置位置窗体
        Window window = dialogProgress.getWindow();
        window.setGravity(Gravity.CENTER);
        window.setContentView(view);

        dialogProgress.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);//弹框
        dialogProgress.getWindow().setLayout((this.getWindowManager().getDefaultDisplay().getWidth() / 5 * 3), LinearLayout.LayoutParams.WRAP_CONTENT);
        dialogProgress.getWindow().setBackgroundDrawableResource(android.R.color.transparent);

    }

}

3.UUidStateBean对象


public class UUidStateBean {

    private int state;
    private String UUid;
    private boolean selected;

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }

    public String getUUid() {
        return UUid;
    }

    public void setUUid(String UUid) {
        this.UUid = UUid;
    }

    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }

    @Override
    public String toString() {
        return "UUidStateBean{" +
                "state=" + state +
                ", UUid='" + UUid + '\'' +
                ", selected=" + selected +
                '}';
    }

}

4.蓝牙信息对象BletoothInfoBen

/**
 * 蓝牙
 * 信息对象
 */

public class BletoothInfoBen implements Serializable {

    private String name;//蓝牙名称
    private String types;//蓝牙类型  体温计or 血糖仪等等
    private String deviceId;//蓝牙设备id
    private String servicesId;//蓝牙服务id
    private String bindTime;//绑定时间

    public BletoothInfoBen() {
    }

    public BletoothInfoBen(String name, String types, String deviceId, String servicesId, String bindTime) {
        this.types = types;
        this.name = name;
        this.deviceId = deviceId;
        this.servicesId = servicesId;
        this.bindTime = bindTime;

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getTypes() {
        return types;
    }

    public void setTypes(String types) {
        this.types = types;
    }

    public String getDeviceId() {
        return deviceId;
    }

    public void setDeviceId(String deviceId) {
        this.deviceId = deviceId;
    }

    public String getServicesId() {
        return servicesId;
    }

    public void setServicesId(String servicesId) {
        this.servicesId = servicesId;
    }

    public String getBindTime() {
        return bindTime;
    }

    public void setBindTime(String bindTime) {
        this.bindTime = bindTime;
    }

    @Override
    public String toString() {
        return "BletoothInfoBen{" +
                "name='" + name + '\'' +
                ", deviceId='" + deviceId + '\'' +
                ", servicesId='" + servicesId + '\'' +
                ", bindTime='" + bindTime + '\'' +
                '}';
    }

}

5.进度对话框

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="@dimen/dp_160"
    android:background="@drawable/popup_dialog_bg"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        android:id="@+id/enter_wifi_password"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_50"
        android:layout_marginLeft="@dimen/dp_35"
        android:layout_marginRight="@dimen/dp_35"
        android:background="@null"
        android:gravity="center"
        android:text="蓝牙连接中......"
        android:textAlignment="center"
        android:textColor="#333333"
        android:textSize="@dimen/sp_14" />


</LinearLayout>

6.ble_servies_select_dialog布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/popup_dialog_bg"
    android:orientation="vertical">

    <RelativeLayout
        android:id="@+id/common_dialog_top_rl"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="@dimen/dp_10"
        android:gravity="center_vertical"
        android:paddingLeft="15dp"
        android:paddingRight="15dp">

        <TextView
            android:id="@+id/common_dialog_title_tv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/dp_15"
            android:gravity="center_horizontal"
            android:textColor="#555555"
            android:textSize="@dimen/sp_16"
            tools:text="标题" />
    </RelativeLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/dialogServList"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="5dp"
        android:layout_weight="1" />

    <View
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:background="#F5F5F5" />

    <LinearLayout
        android:id="@+id/common_dialog_bottom_ll"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/common_dialog_cancel_tv"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:clickable="true"
            android:gravity="center"
            android:textColor="#0679FE"
            android:textSize="@dimen/sp_14"
            tools:text="取消" />

        <View
            android:id="@+id/common_dialog_vertical_line"
            android:layout_width="1dp"
            android:layout_height="match_parent"
            android:background="#F5F5F5" />

        <TextView
            android:id="@+id/common_dialog_confirm_tv"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:clickable="true"
            android:gravity="center"
            android:textColor="#0679FE"
            android:textSize="@dimen/sp_14"
            tools:text="确定" />
    </LinearLayout>
</LinearLayout>

7.gble_layout蓝牙布局

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#91CEC7"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_40"
        android:layout_marginTop="@dimen/dp_5"
        android:gravity="center_vertical"
        android:orientation="horizontal">

        <LinearLayout
            android:id="@+id/finish"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/dp_15"
            android:gravity="center_vertical"
            android:orientation="horizontal">

            <ImageView
                android:layout_width="@dimen/dp_25"
                android:layout_height="@dimen/dp_20"
                android:scaleType="fitCenter"
                android:src="@mipmap/back" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/dp_10"
                android:gravity="center_vertical"
                android:text="返回"
                android:textColor="#666666"
                android:textAlignment="center"
                android:textSize="@dimen/sp_18"
                tools:ignore="RtlCompat" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center_vertical"
                android:text="蓝牙搜索"
                android:textColor="#666666"
                android:textAlignment="center"
                android:textSize="@dimen/sp_18"
                tools:ignore="RtlCompat" />
        </LinearLayout>
    </RelativeLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="@dimen/dp_30"
        android:layout_marginRight="@dimen/dp_30"
        android:layout_marginBottom="@dimen/dp_50"
        android:background="@drawable/blelist_bg_shape"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/dp_30"
            android:layout_marginTop="@dimen/dp_30"
            android:layout_marginRight="@dimen/dp_30"
            android:layout_marginBottom="@dimen/dp_5"
            android:background="#ffffff"
            android:orientation="horizontal">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text=""
                android:textSize="@dimen/sp_16" />

            <Switch
                android:id="@+id/switch_bt"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:thumb="@drawable/thumb_bg"
                android:track="@drawable/track_bg"
                tools:ignore="UseSwitchCompatOrMaterialXml" />

        </LinearLayout>

        <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
            android:id="@+id/swipeLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginBottom="60dp"
            android:layout_weight="1"
            android:background="#ffffff">

            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/recycleview"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginTop="13dp" />
        </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

    </LinearLayout>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_30"
                android:layout_marginLeft="@dimen/dp_10"
                android:layout_marginRight="@dimen/dp_10"
                android:text="接收蓝牙数据" />

            <TextView
                android:id="@+id/blue_txt"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/dp_10"
                android:layout_marginRight="@dimen/dp_10"
                android:text="" />
        </LinearLayout>

    </ScrollView>

</LinearLayout>

  • 23
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
BLE(低功耗蓝牙)是一种通过蓝牙无线技术进行低功耗通信的协议。它是在传统蓝牙(Classic Bluetooth)的基础上发展而来,主要用于物联网、智能家居和健康追踪等领域。 BLE主要特点有以下几个方面: 1. 低功耗:BLE采用了一种优化的通信方式,使设备在通信过程中的功耗大大降低,从而延长了设备的电池寿命,这对于需要长时间运行的设备非常重要。 2. 简化传输:BLE使用了一种称为GATT(通用属性)的协议,将数据分为服务和特征,通过读、写或订阅操作来传输数据,这种简化了传输过程,减少了额外的开销。 3. 快速连接:BLE的连接速度比传统蓝牙更快,可以在几十毫秒内建立连接,这对于移动设备和传感器等需要快速响应的设备非常重要。 4. 多设备连接:BLE支持同时连接多个设备,可以通过同一个移动设备与多个BLE设备进行通信,提高了系统的灵活性和可扩展性。 Android提供了一套完整的BLE开发API,开发者可以使用这些API来实现BLE通信功能。在Android中,开发BLE应用涉及到四个主要组件:BLE设备扫描、设备连接、数据传输和GATT服务管理。 开发者可以使用Android的BluetoothAdapter类来进行设备扫描和连接操作,可以通过BluetoothGatt类来进行GATT服务的操作,包括读、写、订阅等。 总之,BLE作为一种低功耗蓝牙通信协议,在物联网和智能设备领域应用广泛。在Android平台上进行BLE开发,可以借助Android提供的API,快速实现BLE通信功能

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值