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调试助手首页展示。 

Android蓝牙_第1张图片

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 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 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。

Android蓝牙_第2张图片

资源地址:

   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 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 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 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 mServiceList;
    private List 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 blueListInfo;//蓝牙设备信息

    private void getCacheData() {

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

        Type type = new TypeToken>() {
        }.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.进度对话框




    




6.ble_servies_select_dialog布局




    

        
    

    

    

    

        

        

        
    


7.gble_layout蓝牙布局




    

        

            

            
        

        

            
        
    

    

        

            

            

        

        

            
        

    

    

        

            

            
        

    


你可能感兴趣的:(移动端,Android,android)