下面的一個方法是之前寫的,但是那種方法有時候會有掃描不到的情況,現在再寫一種,這種方法,更簡單有效一些.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;
}//體重秤2
else 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[]{"蒼老濕", "小澤老濕", "波多野結衣老濕", "吉澤明步老濕"};//創建item
final String[] items3 = (String[]) tempDeviceList.toArray(new String[tempDeviceList.size()]);//創建item
new Thread(){
@Override
public void run() {
Looper.prepare();
alertDialog alertDialog3 = new AlertDialog.Builder(CommonSettingActivity.this)
.setTitle("掃描設備列表:")
.setIcon(R.mipmap.ic_launcher)
.setItems(items3, new DialogInterface.OnClickListener() {//添加列表
@Override
public 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);//b
message.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(){
@Override
public 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,然後彈出一個彈框,來顯示搜索到設備就可以了.
,