Android實踐 -- Android藍牙設置連接

藍牙開發(fā)相關

使用Android Bluetooth APIs將設備通過藍牙連接并通信,設置藍牙,查找藍牙設備,配對藍牙設備
連接并傳輸數(shù)據(jù),以下是Android系統(tǒng)提供的藍牙相關的類和接口

  • BluetoothAdapter
  • BluetoothDevice
  • BluetoothSocket
  • BluetoothServerSocket
  • BluetoothClass
  • BluetoothProfile
  • BluetoothHeadset
  • BluetoothA2dp
  • BluetoothHealth
  • BluetoothHealthCallback
  • BluetoothHealthAppConfiguration
  • BluetoothProfile.ServiceListener

藍牙權限

使用藍牙功能,需要在AndroidManifest.xml中聲明藍牙相關的權限

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

建立藍牙

  • 初始化連接

在通過藍牙通信之前,需要先確定設備是否支持藍牙功能,先初始化一個BluetoothAdapter的實例,
BluetoothAdapter提供了一個靜態(tài)方法getDefaultAdapter()來獲得BluetoothAdapter的實例

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
    // 設備不支持藍牙功能
}
  • 打開藍牙
    下一步就是打開藍牙,調用isEnabled()方法檢查藍牙功能是否已經(jīng)打開,返回true說明藍牙已開啟,
    返回false說明藍牙功能未開啟,開啟藍牙可以通過發(fā)送廣播ACTION_REQUEST_ENABLE,也可以通過方法
    enable()直接打開,這兩種方法都會有藍牙權限的提示,選擇允許,否則無法打開藍牙
if (!mBluetoothAdapter.isEnabled()) {
  Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
  startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
mBluetoothAdapter.enable();

在應用中可以設置藍牙的狀態(tài)的監(jiān)聽ACTION_STATE_CHANGED廣播,當藍牙的狀態(tài)的變化時,就會觸發(fā)這個
廣播,接收到這個廣播之后,在intent中可以獲得當前藍牙的狀態(tài)和前一次的藍牙的狀態(tài)

int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);

藍牙的狀態(tài)值有:

int STATE_OFF = 10;//藍牙關閉狀態(tài)
int STATE_TURNING_ON = 11;//藍牙正在打開
int STATE_ON = 12;//藍牙打開狀態(tài)
int STATE_TURNING_OFF = 13;//藍牙正在關閉

查找藍牙設備

打開藍牙之后,下一步就是查找可以使用的藍牙設備,藍牙的api中也提供了相關的接口,由于藍牙的掃描
是一個耗電的操作,不用時計時取消掃描藍牙

mBluetoothAdapter.isDiscovering(); //監(jiān)測藍牙是否正在掃描
mBluetoothAdapter.startDiscovery();//開始掃描
mBluetoothAdapter.cancelDiscovery();//取消掃描

為了發(fā)現(xiàn)可用的藍牙的設備,必須在應用中注冊ACTION_FOUND的廣播,調用方法startDiscovery()如果查找到可用的
設備會觸發(fā)這個廣播,這個廣播中帶有EXTRA_DEVICE的設備信息可以通過下面的方法獲得設備的信息

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            Log.e("tag","device name: "+device.getName()+" address: "+device.getAddress());
        }
    }
};
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
  • 查詢已經(jīng)配對的設備列表
    在進行查找之前,可以先獲得之前已經(jīng)配對成功的藍牙設備的列表,可以調用方法getBondedDevices()獲得
    已經(jīng)配對的藍牙設備列表
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
  for (BluetoothDevice device : pairedDevices) {
      //可以獲得已經(jīng)配對的藍牙的名稱和地址
      Log.e("tag","device name: "+device.getName()+" address: "+device.getAddress());
  }
}
  • 是其他設備可見
    上面講的都是發(fā)現(xiàn)其他的藍牙設備,也可以設置設備本身是否對其他設備可見,通過發(fā)送ACTION_REQUEST_DISCOVERABLE
    的廣播,會調用系統(tǒng)的方法,還可以設置多長時間內是可見的,在intent中設置EXTRA_DISCOVERABLE_DURATION,最大值是
    3600s,超過3600s會設置為120s,點擊允許會回調onActivityResult()方法
//設置設備在300s內是可見的
Intent discoverableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);

如果沒有打開藍牙,執(zhí)行上面的操作會自動打開藍牙

可以通過監(jiān)聽ACTION_SCAN_MODE_CHANGED廣播,可以在intent中根據(jù)EXTRA_SCAN_MODE的參數(shù)獲得當前設備的SCAN MODE
有一些幾種模式

int SCAN_MODE_NONE = 20;//這個模式不能被發(fā)現(xiàn)也不能連接
int SCAN_MODE_CONNECTABLE = 21;//這個模式不能被掃描到,但是可以連接
int SCAN_MODE_CONNECTABLE_DISCOVERABLE = 23;//這個模式可以被發(fā)現(xiàn),也能被連接

藍牙的連接

  • Server 端
    通過BluetoothAdapterlistenUsingRfcommWithServiceRecord(String, UUID)方法獲得BluetoothServerSocket對象
    的實例,然后socket就會通過accept()監(jiān)聽客戶端的連接的狀態(tài)
private class AcceptThread extends Thread {
    private final BluetoothServerSocket mmServerSocket;
    public AcceptThread() {
        BluetoothServerSocket tmp = null;
        try {
            tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
        } catch (IOException e) { }
        mmServerSocket = tmp;
    }

    public void run() {
        BluetoothSocket socket = null;
        // 在后臺一直監(jiān)聽客戶端的請求
        while (true) {
            try {
                socket = mmServerSocket.accept();
            } catch (IOException e) {
                break;
            }
            if (socket != null) {
                mmServerSocket.close();
                break;
            }
        }
    }
    public void cancel() {
        try {
            mmServerSocket.close();
        } catch (IOException e) { }
    }
}
  • Client 端
    使用BluetoothDevicecreateRfcommSocketToServiceRecord(UUID)方法獲得BluetoothSocket對象的實例
    然后調用connect()方法,這時server端會監(jiān)聽到這個請求,之后就建立連接,然后就可以進行通信了
private class ConnectThread extends Thread {
  private final BluetoothSocket mmSocket;
  private final BluetoothDevice mmDevice;
  public ConnectThread(BluetoothDevice device) {
      BluetoothSocket tmp = null;
      mmDevice = device;
      try {
          tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
      } catch (IOException e) { }
      mmSocket = tmp;
  }

  public void run() {
      mBluetoothAdapter.cancelDiscovery();

      try {
          mmSocket.connect();
      } catch (IOException connectException) {
          try {
              mmSocket.close();
          } catch (IOException closeException) { }
          return;
      }
  }
  public void cancel() {
      try {
          mmSocket.close();
      } catch (IOException e) { }
  }
}

連接的監(jiān)聽

可以通過注冊廣播監(jiān)聽藍牙設備連接的狀態(tài)變化,廣播BluetoothDevice.ACTION_BOND_STATE_CHANGED,監(jiān)聽到這個廣播之后,可以
在intent中獲得連接的狀態(tài)

int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE);

設備連接的狀態(tài)值

int BOND_NONE = 10;//沒有連接  
int BOND_BONDING = 11;//正在連接  
int BOND_BONDED = 12;//已經(jīng)建立連接  
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容