AndroidStudio安卓原生开发蓝牙扫描设备Mac的另一种方法下面的一个方法是之前写的,但是那种方法有时候会有扫描不到的情况,现在再写一种,这种方法,更简单有效一些.AndroidStudio安卓原生开发_Android扫描附近指定的。

下面的一个方法是之前写的,但是那种方法有时候会有扫描不到的情况,现在再写一种,这种方法,更简单有效一些.AndroidStudio安卓原生开发_Android扫描附近指定的蓝牙设备_通过设备名称过滤_计算距离_离扫描设备近的显示的时候放在前面---Android原生开发工作笔记128_全栈哥的专栏-CSDN博客下面这里直接上代码吧,我这边的应用场景是,比如我扫描附近的体重秤,注意,我扫描的时候,需要过滤,只把扫描到的特定型号的,体重秤显示出来,比如附近的手机,血压计等都不能扫描出来.同时比如如果有两台体重秤的话,一台离的近,一台离的远,我需要把离得近的体重秤,在显示的时候,优先显示在上面.根据离扫描设备的距离,做个倒序排序: 这里有个不好的地方,就是,我是用扫描到的设备的蓝牙的名称来进行过滤的,比如体重秤的话,他这个型号的,的蓝牙名称都是以QN- 开头的,我直接判断,我扫描到的蓝牙设备...
1.首先在activity中,去检查有没有定位权限,这里我利用定位,根据蓝牙信号的强弱计算,
设备离平板的距离了.在oncreate中去调用就可以了.
/*** 解决:无法发现蓝牙设备的问题** 对于发现新设备这个功能, 还需另外两个权限(Android M 以上版本需要显式获取授权,附授权代码):*/private final int ACCESS_LOCATION=1;@SuppressLint("WrongConstant")private void getPermission() {if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {int permissionCheck = 0;permissionCheck = this.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION);permissionCheck= this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION);if (permissionCheck != PackageManager.PERMISSION_GRANTED) {//未获得权限this.requestPermissions( // 请求授权new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION},ACCESS_LOCATION);// 自定义常量,任意整型}}}
2.去初始化蓝牙
private BluetoothAdapter bluetoothAdapter;private BluetoothGatt mBluetoothGatt; //这个可以定义到最上面//初始化蓝牙设备private void initBluetooth() {bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();if (bluetoothAdapter == null) {Toast.makeText(this, "此设备不支持蓝牙操作", Toast.LENGTH_LONG).show();return;}}
3.写个搜索方法去调用 searchDevices(); 这个方法可以点击某个搜索的按钮的时候调用
private void searchDevices() {bluetoothAdapter.getBluetoothLeScanner().startScan(scanCallback);}
4.然后去写回调方法,搜索到设备以后回调方法
public ScanCallback scanCallback = new ScanCallback() {public void onScanResult(int var1, ScanResult var2) {String mac_address="";String device_name ="";mac_address=var2.getDevice().getAddress();device_name = var2.getDevice().getName();String deviceAddress = "";String deviceName = "";double deviceSignal = 0.0;boolean isFind = false;if(deviceNum.equals("0")){isFind = false;deviceName = "未知设备";//deviceAddress = "未知设备->"device.getAddress();deviceAddress = mac_address;}else if(deviceNum.equals("1") && device_name!=null && device_name.toString().startsWith("QN-")){isFind = true;deviceName = "体重秤";//deviceAddress = "体重秤->"mac_address;deviceAddress = mac_address;}//体重秤2else if(deviceNum.equals("7") && device_name!=null && device_name.toString().startsWith("QN-")){isFind = true;deviceName = "体重秤";//deviceAddress = "体重秤->"mac_address;deviceAddress = mac_address;}.... 这里可以写很多,看自己有多少设备了,这里我依然是直接用设备名称搜索的else{isFind = false;}//找到检测设备以后,添加到设备列表中去if(isFind){if(strMacLists.contains(deviceAddress)){}else{//获取蓝牙信号强度,信号强度强的放在前面//添加到列表int iRssi = var2.getRssi();;// 将蓝牙信号强度换算为距离double power = (iRssi - 59) / 25.0;deviceSignal = power;DeviceInfo deviceInfo = new DeviceInfo();deviceInfo.setAddress(deviceAddress);deviceInfo.setName(deviceName);deviceInfo.setSignal(deviceSignal);macLists.add(deviceInfo);strMacLists.add(deviceAddress);}}}};
5.上面就是搜索到了设备以后,然后构建一个DeviceInfo这个类,然后添加到list中去,这里对象中,带有
rssi也就是deviceSignal这个是表示距离的属性,会根据这个,给搜索到的设备进行距离排序.
然后,某个按钮按下,去调用搜索方法.
//1.每次搜索前初始化一下设备信息macLists = new ArrayList<DeviceInfo>();//1.显示正在扫描BaseApplication.context().showDialog(CommonSettingActivity.this, "正在扫描请稍后...");final int[] deviceCount = {0};macLists = new ArrayList<DeviceInfo>();strMacLists = new ArrayList<String>();//定时器循环final Timer scanTimer = new Timer();TimerTask scanTask = new TimerTask(){public void run() {//Looper.prepare();if((deviceCount[0] < macLists.size()) && (macLists.size()>0)){//1.有新设备添加,记录设备数量deviceCount[0] =macLists.size();}else if((deviceCount[0] == macLists.size()) && (macLists.size() > 0)){//2.已经没有新设备被扫描到,扫描结束BaseApplication.context().closeDialog();scanTimer.cancel();//3.按照信号强度排序Collections.sort(macLists, new ComparatorSort());ArrayList<String> tempDeviceList = new ArrayList<>();for (DeviceInfo macList : macLists) {tempDeviceList.add(macList.getName() "->" macList.getAddress());}//搜索蓝牙设备按钮//String[] items3 = new String[]{"苍老湿", "小泽老湿", "波多野结衣老湿", "吉泽明步老湿"};//创建itemfinal String[] items3 = (String[]) tempDeviceList.toArray(new String[tempDeviceList.size()]);//创建itemnew Thread(){@Overridepublic void run() {Looper.prepare();alertDialog alertDialog3 = new AlertDialog.Builder(CommonSettingActivity.this).setTitle("扫描设备列表:").setIcon(R.mipmap.ic_launcher).setItems(items3, new DialogInterface.OnClickListener() {//添加列表@Overridepublic void onClick(DialogInterface dialogInterface, int i) {//Toast.makeText(CommonSettingActivity.this, "点的是:"items3[i], Toast.LENGTH_SHORT).show();//EditText mac_edit_text = findViewById(R.id.set_edittext_mac);//获取mac地址//mac_edit_text.setText(items3[i]);Message message=new Message();Bundle bundle=new Bundle();bundle.putString("deviceMac", items3[i]);message.setData(bundle);//bmessage.what = 310;setMacHandler.sendMessage(message);}}).create();alertDialog3.show();alertDialog3.getWindow().setLayout(1600,800);Looper.loop();}}.start();}else if(macLists.size() == 0 ){BaseApplication.context().closeDialog();scanTimer.cancel();//Toast.makeText(this,"121",Toast.LENGTH_SHORT).show();new Thread(){@Overridepublic void run() {Looper.prepare();Toast.makeText(CommonSettingActivity.this, "未扫描到设备", Toast.LENGTH_SHORT).show();Looper.loop();}}.start();}}};scanTimer.schedule(scanTask,8000,5000);searchDevices();
6.可以看到上面,当按下按钮的时候,实际上去先打开一个timer,timer会每个5秒钟,去执行一次,
会检查搜索到的list的size,如果经过5秒的搜索,size大于0,就先记住这个size,然后再去搜索,
再经过5秒钟搜索如果,上次搜索的已经记下的个数,小于现在macLists这个的size,说明又有新的设备
被扫描到了,就再次记下最新的size,知道记下的size和macLists的size一样的时候,说明已经没有新
设备被扫描到了,就退出这个timer,然后弹出一个弹框,来显示搜索到设备就可以了.
