最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android藍(lán)牙通信之搜索藍(lán)牙設(shè)備

 更新時間:2017年09月29日 09:53:03   作者:山城碼農(nóng)  
這篇文章主要介紹了Android藍(lán)牙通信之搜索藍(lán)牙設(shè)備,需要的朋友可以參考下

一:注意事項

      1:android6.0使用藍(lán)牙時,需要開啟gps定位權(quán)限,不然無法搜索其它藍(lán)牙設(shè)備。

二:權(quán)限

      1:權(quán)限配置

<!--允許程序連接到已配對的藍(lán)牙設(shè)備-->
<uses-permission android:name="android.permission.BLUETOOTH" />
<!-- 允許程序發(fā)現(xiàn)和配對藍(lán)牙設(shè)備 -->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
 <!--android 6.0 涉及到的權(quán)限-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 在SDCard中創(chuàng)建與刪除文件的權(quán)限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 往SDCard寫入數(shù)據(jù)的權(quán)限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    2:動態(tài)權(quán)限代碼

    由于需要用到存儲卡,定位等,android6.0以上需要代碼動態(tài)設(shè)置。

   a)獲取定位設(shè)置

if (Build.VERSION.SDK_INT >= 23) {
  boolean isLocat = isLocationOpen(getApplicationContext());
  Toast.makeText(mContext, "isLo:" + isLocat, Toast.LENGTH_LONG).show();
   //開啟位置服務(wù),支持獲取ble藍(lán)牙掃描結(jié)果
  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);
  //網(wǎng)絡(luò)定位
  boolean isNetWorkProvider = manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
  return isGpsProvider || isNetWorkProvider;
 }

b)存儲卡權(quán)限設(shè)置

if (Build.VERSION.SDK_INT >= 23) {
   int write = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
   int read = checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE);
   //動態(tài)請求讀寫sd卡權(quán)限
   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()方法獲取動態(tài)權(quán)限的結(jié)果:

@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;
  }
 }

 三:藍(lán)牙搜索

android.bluetooth.BluetoothAdapter 是藍(lán)牙開發(fā)用得比較多,并且比較重要的一個類,可以設(shè)備藍(lán)牙名稱,打開,關(guān)閉,搜索等常規(guī)操作。

  1 藍(lán)牙打開,以及搜索

     藍(lán)牙打開和關(guān)閉信息使用BluetoothAdapter.ACTION_STATE_CHANGED去接收廣播

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

藍(lán)牙打開后,我們可以獲取設(shè)備的藍(lán)牙信息

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

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

 /*確保藍(lán)牙被發(fā)現(xiàn),在榮耀8手機上,設(shè)置了還是默認(rèn)的2分鐘,所以以下幾句代碼程序中沒有,*/
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
//設(shè)置可見狀態(tài)的持續(xù)時間為300秒,但是最多是300秒
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivityForResult(discoverableIntent, REQUEST_DISCOVERABLE_BLUETOOTH);
private void initSearchBroadcast() {
  IntentFilter intentFilter = new IntentFilter();
  //發(fā)現(xiàn)設(shè)備
  intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
  //設(shè)備配對狀態(tài)改變
  intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
  //藍(lán)牙設(shè)備狀態(tài)改變
  intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
  //開始掃描
  intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
  //結(jié)束掃描
  intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
  //其它設(shè)備請求配對
  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("正在掃描設(shè)備,請稍候...");
    } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {//結(jié)束掃描
     Logger.e(TAG + "設(shè)備搜索完畢");
     setProgressBarIndeterminateVisibility(false);
     log1.setText("掃描完成");
     bondAdapter.notifyDataSetChanged();
     unbondAdapter.notifyDataSetChanged();
     scanStatus = false;
    } else if (BluetoothDevice.ACTION_FOUND.equals(action)) {//發(fā)現(xiàn)設(shè)備
     findDevice(intent);
    } else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {//藍(lán)牙配對狀態(tài)的廣播
     BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
     Logger.e(TAG + device.getName() + "藍(lán)牙配對廣播:" + device.getBondState());
     switch (device.getBondState()) {
      case BluetoothDevice.BOND_BONDING:
       Logger.e(TAG + device.getName() + "藍(lán)牙配對廣播 正在配對......");
       break;
      case BluetoothDevice.BOND_BONDED:
       Logger.e(TAG + device.getName() + "藍(lán)牙配對廣播 完成配對,本機自動配對");
       bondDevices.add(device);
       unbondDevices.remove(device);
       bondAdapter.notifyDataSetChanged();
       unbondAdapter.notifyDataSetChanged(); 
       break;
      case BluetoothDevice.BOND_NONE:
       Logger.e(TAG + device.getName() + "藍(lán)牙配對廣播 取消配對");
       unbondDevices.add(device);
       bondDevices.remove(device);
       unbondAdapter.notifyDataSetChanged();
       bondAdapter.notifyDataSetChanged();
      default:
       break;
     }
    } else if (action.equals(ACTION_PAIRING_REQUEST)) {//其它設(shè)備藍(lán)牙配對請求
     BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
     int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE); //當(dāng)前的配對的狀態(tài)
     try {
      String path = Environment.getExternalStorageDirectory() + "/blueTest/";
      String deviceName = btDevice.getName();
      Logger.e(TAG + "藍(lán)牙 匹配信息:" + deviceName + "," + btDevice.getAddress() + ",state:" + state);
      //1.確認(rèn)配對,高版本無效,藍(lán)牙配對不是zuk的問題,而是安卓6.0的bug,凡是遇到藍(lán)牙適配問題的,請同時打開藍(lán)牙和定位,再去配對,基本90%都沒有問題了。
      Object object = ClsUtils.setPairingConfirmation(btDevice.getClass(), btDevice, true);
      //2.終止有序廣播,如果沒有將廣播終止,則會出現(xiàn)一個一閃而過的配對框。
      abortBroadcast();
      //3.調(diào)用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)) {//藍(lán)牙開關(guān)狀態(tài)
     // BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
     int statue = mBluetoothAdapter.getState();
     switch (statue) {
      case BluetoothAdapter.STATE_OFF:
       Logger.e("藍(lán)牙狀態(tài):,藍(lán)牙關(guān)閉");
       ClsUtils.closeDiscoverableTimeout(mBluetoothAdapter);
       break;
      case BluetoothAdapter.STATE_ON:
       Logger.e("藍(lán)牙狀態(tài):,藍(lán)牙打開");
       ClsUtils.setDiscoverableTimeout(1000 * 60, mBluetoothAdapter);
       scanBluetooth();
       break;
      case BluetoothAdapter.STATE_TURNING_OFF:
       Logger.e("藍(lán)牙狀態(tài):,藍(lán)牙正在關(guān)閉");
       mBluetoothAdapter.cancelDiscovery();
       break;
      case BluetoothAdapter.STATE_TURNING_ON:
       Logger.e("藍(lán)牙狀態(tài):,藍(lán)牙正在打開");
       break;
     }
    }
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
 };
//發(fā)現(xiàn)設(shè)備的代碼如下
 private void findDevice(Intent intent) throws Exception{
 //獲取到設(shè)備對象
 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
 String str = device.getName() + "|" + device.getAddress();
 Logger.e("掃描到設(shè)備:" + str);
 if (device.getBondState() == BluetoothDevice.BOND_BONDED) {//判斷當(dāng)前設(shè)備地址下的device是否已經(jīng)配對
  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", "搜索完畢,準(zhǔn)備刷新!");
 bondAdapter.notifyDataSetChanged();
 unbondAdapter.notifyDataSetChanged();
}

四:藍(lán)牙配對

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

1 當(dāng)我們搜索到目標(biāo)手機的藍(lán)牙后,android設(shè)備主動發(fā)起連接請求,代碼如下

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

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

 BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
     int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE); //當(dāng)前的配對的狀態(tài)
     try {
      String path = Environment.getExternalStorageDirectory() + "/blueTest/";
      String deviceName = btDevice.getName();
      Logger.e(TAG + "藍(lán)牙 匹配信息:" + deviceName + "," + btDevice.getAddress() + ",state:" + state); 
      if(deviceName.equals(TEST_DEVICE_NAME)){//TEST_DEVICE_NAME 為被匹配藍(lán)牙設(shè)備的名稱,自己手動定義
       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();
     }
//確認(rèn)配對
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;
 }
//配對需要調(diào)用的方法
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;
 }     

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

demo代碼下載:github

總結(jié)

以上所述是小編給大家介紹的Android藍(lán)牙通信之搜索藍(lán)牙設(shè)備,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

  • Android繪制機器人小實例

    Android繪制機器人小實例

    這篇文章主要為大家詳細(xì)介紹了Android繪制機器人小實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Android仿微信和QQ多圖合并框架(類似群頭像)的實現(xiàn)方法

    Android仿微信和QQ多圖合并框架(類似群頭像)的實現(xiàn)方法

    這篇文章主要給大家介紹了關(guān)于Android仿微信和QQ多圖合并框架的相關(guān)資料,其實就是我們平時所見的群聊頭像,文中通過示例代碼介紹的非常詳細(xì),對各位Android開發(fā)者們具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-12-12
  • 揭秘Android視圖繪制的流程步驟

    揭秘Android視圖繪制的流程步驟

    在Android的UI中,View是至關(guān)重要的一個組件,它是用戶界面的基本構(gòu)建塊,在View的繪制過程中,涉及到很多重要的概念和技術(shù),本文將詳細(xì)介紹Android?View的繪制過程,讓你能夠更好地理解和掌握Android的UI開發(fā),需要的朋友可以參考下
    2023-06-06
  • android AlertDialog的簡單使用實例

    android AlertDialog的簡單使用實例

    本篇文章主要介紹了android AlertDialog的簡單使用實例,具有一定的參考價值,有興趣的可以了解一下。
    2017-01-01
  • Android FaceDetector實現(xiàn)人臉檢測功能

    Android FaceDetector實現(xiàn)人臉檢測功能

    這篇文章主要為大家詳細(xì)介紹了Android FaceDetector實現(xiàn)人臉檢測功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • Android如何使用GestureDetector進行手勢檢測詳解

    Android如何使用GestureDetector進行手勢檢測詳解

    GestureDetector使用很方便,提供了單擊,雙擊,長按等操作的處理,但是一般的定義界面都比較復(fù)雜,還用很多需要注意的地方,這篇文章主要給大家介紹了關(guān)于Android如何使用GestureDetector進行手勢檢測的相關(guān)資料,需要的朋友可以參考下
    2022-01-01
  • Android獲取手機安裝應(yīng)用程序的詳細(xì)信息

    Android獲取手機安裝應(yīng)用程序的詳細(xì)信息

    在開發(fā)Android應(yīng)用時,有時我們需要獲取設(shè)備上已安裝的所有應(yīng)用程序的信息,這篇文章為大家整理了一些常用的方法,希望對大家有所幫助
    2025-03-03
  • Android 逆向?qū)W習(xí)詳解及實例

    Android 逆向?qū)W習(xí)詳解及實例

    本文主要介紹Android 逆向?qū)W習(xí),這里整理逆向?qū)W習(xí)的思路及學(xué)習(xí)要點,并附示例代碼,幫助大家學(xué)習(xí)理解,有需要的小伙伴可以參考下
    2016-09-09
  • android聊天界面鍵盤、表情切換絲滑實現(xiàn)的具體思路

    android聊天界面鍵盤、表情切換絲滑實現(xiàn)的具體思路

    這篇文章主要給大家介紹了關(guān)于android聊天界面鍵盤、表情切換絲滑實現(xiàn)的具體思路,具體實現(xiàn)包括在XML布局中使用FrameLayout和RecyclerView,并在代碼中進行相應(yīng)的高度控制和事件處理,需要的朋友可以參考下
    2024-12-12
  • Android使用Scroller實現(xiàn)彈性滑動效果

    Android使用Scroller實現(xiàn)彈性滑動效果

    這篇文章主要介紹了Android使用Scroller實現(xiàn)彈性滑動效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12

最新評論

云霄县| 滦南县| 新闻| 类乌齐县| 上思县| 康定县| 湖口县| 甘孜县| 两当县| 佳木斯市| 朝阳县| 靖宇县| 绥芬河市| 新乐市| 拉萨市| 峨山| 县级市| 武陟县| 凤山县| 罗定市| 沂水县| 利川市| 富宁县| 屯昌县| 利川市| 建始县| 都昌县| 泉州市| 永新县| 邵阳县| 潮安县| 姜堰市| 抚顺县| 浦东新区| 双鸭山市| 丘北县| 体育| 承德县| 汪清县| 肇东市| 固阳县|