国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android藍牙通信之搜索藍牙設備

2019-10-22 18:26:56
字體:
來源:轉載
供稿:網友

一:注意事項

      1:android6.0使用藍牙時,需要開啟gps定位權限,不然無法搜索其它藍牙設備。

二:權限

      1:權限配置

<!--允許程序連接到已配對的藍牙設備--><uses-permission android:name="android.permission.BLUETOOTH" /><!-- 允許程序發現和配對藍牙設備 --><uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <!--android 6.0 涉及到的權限--><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><!-- 在SDCard中創建與刪除文件的權限 --><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/><!-- 往SDCard寫入數據的權限 --><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    2:動態權限代碼

    由于需要用到存儲卡,定位等,android6.0以上需要代碼動態設置。

   a)獲取定位設置

if (Build.VERSION.SDK_INT >= 23) {  boolean isLocat = isLocationOpen(getApplicationContext());  Toast.makeText(mContext, "isLo:" + isLocat, Toast.LENGTH_LONG).show();   //開啟位置服務,支持獲取ble藍牙掃描結果  if (!isLocat) {  Intent enableLocate = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);  startActivityForResult(enableLocate, 1);  }} /**  * 判斷位置信息是否開啟  *  * @param context  * @return  */ private static boolean isLocationOpen(final Context context) {  LocationManager manager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);  //gps定位  boolean isGpsProvider = manager.isProviderEnabled(LocationManager.GPS_PROVIDER);  //網絡定位  boolean isNetWorkProvider = manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);  return isGpsProvider || isNetWorkProvider; }

b)存儲卡權限設置

if (Build.VERSION.SDK_INT >= 23) {   int write = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);   int read = checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE);   //動態請求讀寫sd卡權限   if (write != PackageManager.PERMISSION_GRANTED || read != PackageManager.PERMISSION_GRANTED) {    requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, SD_CARD);   }}

然后通過onRequestPermissionsResult()方法獲取動態權限的結果:

@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {  switch (requestCode){   case SD_CARD:    if(grantResults.length>0&&grantResults[0] == PackageManager.PERMISSION_GRANTED){     //允許訪問    }else{     Toast.makeText(mContext,"您拒絕了程序訪問存儲卡",Toast.LENGTH_LONG).show();    }    break;   case COARES_LOCATION:    break;  } }

 三:藍牙搜索

android.bluetooth.BluetoothAdapter 是藍牙開發用得比較多,并且比較重要的一個類,可以設備藍牙名稱,打開,關閉,搜索等常規操作。

  1 藍牙打開,以及搜索

     藍牙打開和關閉信息使用BluetoothAdapter.ACTION_STATE_CHANGED去接收廣播

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();mBluetoothAdapter.setName("blueTestPhone"); //判斷藍牙是否打開boolean originalBluetooth = (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled());if (originalBluetooth) { mBluetoothAdapter.startDiscovery();} else if (originalBluetooth == false) { mBluetoothAdapter.enable();}

藍牙打開后,我們可以獲取設備的藍牙信息

StringBuilder sb = new StringBuilder(); //獲取本機藍牙名稱 String name = mBluetoothAdapter.getName();//獲取本機藍牙地址 String address = mBluetoothAdapter.getAddress();

搜索完成后,通過BluetoothDevice.ACTION_FOUND廣播去接收結果,廣播代碼如下(注意:可能出現設備搜索不到的情況,設備需要開啟允許周圍設備搜索,或者通過程序來控制允許搜索的時間范圍)

Android,藍牙通信,搜索藍牙設備

 /*確保藍牙被發現,在榮耀8手機上,設置了還是默認的2分鐘,所以以下幾句代碼程序中沒有,*/Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);//設置可見狀態的持續時間為300秒,但是最多是300秒discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);startActivityForResult(discoverableIntent, REQUEST_DISCOVERABLE_BLUETOOTH);private void initSearchBroadcast() {  IntentFilter intentFilter = new IntentFilter();  //發現設備  intentFilter.addAction(BluetoothDevice.ACTION_FOUND);  //設備配對狀態改變  intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);  //藍牙設備狀態改變  intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);  //開始掃描  intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);  //結束掃描  intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);  //其它設備請求配對  intentFilter.addAction(ACTION_PAIRING_REQUEST);  //intentFilter.addAction(BluetoothAdapter.CONNECTION_STATE_CHANGED);  registerReceiver(bluetoothReceiver, intentFilter); }private BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {  @Override  public void onReceive(Context context, Intent intent) {   String action = intent.getAction();   Logger.e(TAG + "mBluetoothReceiver action =" + action);   try {    if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {//開始掃描     setProgressBarIndeterminateVisibility(true);     log1.setText("正在掃描設備,請稍候...");    } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {//結束掃描     Logger.e(TAG + "設備搜索完畢");     setProgressBarIndeterminateVisibility(false);     log1.setText("掃描完成");     bondAdapter.notifyDataSetChanged();     unbondAdapter.notifyDataSetChanged();     scanStatus = false;    } else if (BluetoothDevice.ACTION_FOUND.equals(action)) {//發現設備     findDevice(intent);    } else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {//藍牙配對狀態的廣播     BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);     Logger.e(TAG + device.getName() + "藍牙配對廣播:" + device.getBondState());     switch (device.getBondState()) {      case BluetoothDevice.BOND_BONDING:       Logger.e(TAG + device.getName() + "藍牙配對廣播 正在配對......");       break;      case BluetoothDevice.BOND_BONDED:       Logger.e(TAG + device.getName() + "藍牙配對廣播 完成配對,本機自動配對");       bondDevices.add(device);       unbondDevices.remove(device);       bondAdapter.notifyDataSetChanged();       unbondAdapter.notifyDataSetChanged();        break;      case BluetoothDevice.BOND_NONE:       Logger.e(TAG + device.getName() + "藍牙配對廣播 取消配對");       unbondDevices.add(device);       bondDevices.remove(device);       unbondAdapter.notifyDataSetChanged();       bondAdapter.notifyDataSetChanged();      default:       break;     }    } else if (action.equals(ACTION_PAIRING_REQUEST)) {//其它設備藍牙配對請求     BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);     int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE); //當前的配對的狀態     try {      String path = Environment.getExternalStorageDirectory() + "/blueTest/";      String deviceName = btDevice.getName();      Logger.e(TAG + "藍牙 匹配信息:" + deviceName + "," + btDevice.getAddress() + ",state:" + state);      //1.確認配對,高版本無效,藍牙配對不是zuk的問題,而是安卓6.0的bug,凡是遇到藍牙適配問題的,請同時打開藍牙和定位,再去配對,基本90%都沒有問題了。      Object object = ClsUtils.setPairingConfirmation(btDevice.getClass(), btDevice, true);      //2.終止有序廣播,如果沒有將廣播終止,則會出現一個一閃而過的配對框。      abortBroadcast();      //3.調用setPin方法進行配對...      boolean ret = ClsUtils.setPin(btDevice.getClass(), btDevice, PWD);     } catch (Exception e) {      // TODO Auto-generated catch block      e.printStackTrace();      Toast.makeText(mContenxt, "error:" + btDevice + "," + state, Toast.LENGTH_LONG).show();     }    } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {//藍牙開關狀態     // BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);     int statue = mBluetoothAdapter.getState();     switch (statue) {      case BluetoothAdapter.STATE_OFF:       Logger.e("藍牙狀態:,藍牙關閉");       ClsUtils.closeDiscoverableTimeout(mBluetoothAdapter);       break;      case BluetoothAdapter.STATE_ON:       Logger.e("藍牙狀態:,藍牙打開");       ClsUtils.setDiscoverableTimeout(1000 * 60, mBluetoothAdapter);       scanBluetooth();       break;      case BluetoothAdapter.STATE_TURNING_OFF:       Logger.e("藍牙狀態:,藍牙正在關閉");       mBluetoothAdapter.cancelDiscovery();       break;      case BluetoothAdapter.STATE_TURNING_ON:       Logger.e("藍牙狀態:,藍牙正在打開");       break;     }    }   } catch (Exception e) {    e.printStackTrace();   }  } };//發現設備的代碼如下 private void findDevice(Intent intent) throws Exception{ //獲取到設備對象 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); String str = device.getName() + "|" + device.getAddress(); Logger.e("掃描到設備:" + str); if (device.getBondState() == BluetoothDevice.BOND_BONDED) {//判斷當前設備地址下的device是否已經配對  if (!bondDevices.contains(device)) {   bondDevices.add(device);  } } else {  if (!unbondDevices.contains(device)) {   unbondDevices.add(device);  }  if (device.getName().equals(TEST_DEVICE_NAME)) {   boolean bondStatus = ClsUtils.createBond(device.getClass(), device);   Logger.i(TAG + " bondStatus:" + bondStatus);  } } Log.e("error", "搜索完畢,準備刷新!"); bondAdapter.notifyDataSetChanged(); unbondAdapter.notifyDataSetChanged();}

四:藍牙配對

   正常情況下,藍牙匹配需要彈出一個匹配確認框,如下圖,但我想實現的是,匹配其中一方,不能手動點擊配對,因為發起藍牙連接的設備是android設備,是不能觸摸的,所以就要通過程序來解決這個問題,特別聲明:(測試的android設備,版本為5.x,并且已經root,沒有root的設備,或者不是android5.x不清楚能否實現自動匹配,因為我只有這個測試設備)。

Android,藍牙通信,搜索藍牙設備

1 當我們搜索到目標手機的藍牙后,android設備主動發起連接請求,代碼如下

 if (device.getName().equals(TEST_DEVICE_NAME)) {    boolean bondStatus = ClsUtils.createBond(device.getClass(), device);    Logger.i(TAG + " bondStatus:" + bondStatus); }//發起藍牙匹配請求 public boolean createBond(Class btClass, BluetoothDevice btDevice)   throws Exception {  Method createBondMethod = btClass.getMethod("createBond");  Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice);  return returnValue.booleanValue();}

2 當被匹配方點擊配對后,系統會通過BluetoothDevice.ACTION_BOND_STATE_CHANGED廣播告訴android設備,此時android設備就可以自動確認,通過這個流程來完成整個藍牙的配對,具體代碼如下

 BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);     int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE); //當前的配對的狀態     try {      String path = Environment.getExternalStorageDirectory() + "/blueTest/";      String deviceName = btDevice.getName();      Logger.e(TAG + "藍牙 匹配信息:" + deviceName + "," + btDevice.getAddress() + ",state:" + state);       if(deviceName.equals(TEST_DEVICE_NAME)){//TEST_DEVICE_NAME 為被匹配藍牙設備的名稱,自己手動定義       Object object = ClsUtils.setPairingConfirmation(btDevice.getClass(), btDevice, true);       abortBroadcast();       boolean ret = ClsUtils.setPin(btDevice.getClass(), btDevice, PWD);      }     } catch (Exception e) {      // TODO Auto-generated catch block      e.printStackTrace();      Toast.makeText(mContenxt, "error:" + btDevice + "," + state, Toast.LENGTH_LONG).show();     }//確認配對public Object setPairingConfirmation(Class<?> btClass, BluetoothDevice device, boolean isConfirm) throws Exception {  Method setPairingConfirmation = btClass.getDeclaredMethod("setPairingConfirmation", boolean.class);  Object object = setPairingConfirmation.invoke(device, isConfirm);   return object; }//配對需要調用的方法public boolean setPin(Class<? extends BluetoothDevice> btClass, BluetoothDevice btDevice,         String str) throws Exception {  try {   Method removeBondMethod = btClass.getDeclaredMethod("setPin",     new Class[]       {byte[].class});   Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice,     new Object[]       {str.getBytes()});   Log.e("returnValue", "" + returnValue);  } catch (SecurityException e) {   // throw new RuntimeException(e.getMessage());   e.printStackTrace();  } catch (IllegalArgumentException e) {   // throw new RuntimeException(e.getMessage());   e.printStackTrace();  } catch (Exception e) {   // TODO Auto-generated catch block   e.printStackTrace();  }  return true; }     

      到目前為止,藍牙權限,以及動態權限,藍牙的打開,關閉,搜索,以及自動配對(特別聲明:(自動配對的android設備,版本為5.x,并且已經root,沒有root的設備,或者不是android5.x不清楚能否實現自動匹配,因為我只有這個測試設備)。)代碼至此結束。

demo代碼下載:github

總結

以上所述是小編給大家介紹的Android藍牙通信之搜索藍牙設備,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對VEVB武林網網站的支持!


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 海阳市| 平邑县| 西青区| 沽源县| 固原市| 宝应县| 康定县| 贵德县| 四子王旗| 塔河县| 扎赉特旗| 奎屯市| 临洮县| 钟山县| 石柱| 嫩江县| 家居| 宣威市| 龙岩市| 沙湾县| 东海县| 冷水江市| 洞头县| 兰州市| 青浦区| 武鸣县| 林周县| 革吉县| 浪卡子县| 瓮安县| 西充县| 陆河县| 岳阳县| 闻喜县| 宁南县| 德兴市| 府谷县| 大田县| 青川县| 铜鼓县| 闵行区|