Android 藍牙學習

學習緣由

上個禮拜公司要開發個簡單的五子棋遊戲!其中一個需求就是支持藍牙對戰!所以苦逼的我學習藍牙方面的知識了!

簡介

  • Bluetooth是目前使用最廣泛的無線通訊協議,近距離無線通訊的標準。傳說瑞典有個國王特別愛吃藍莓導致自己的牙齒天天都是藍色的,在他執政期間這位國王非常善於交際,能說會到,和鄰國的搞得關係非常好,這個Bluetooth的發明者覺得藍牙它的作用就是在近距離溝通周圍的設備,跟這個國王很類似,於是起名叫藍牙。

  • 主要針對短距離設備通訊(10米)

  • 無線耳機,無線鼠標,無線鍵盤

Android 中的使用

藍牙 API 簡單簡介

  • BluetoothAdapter (藍牙本地適配器)
  1. cancelDiscovery() 停止當前搜索藍牙的 Task
  2. disable() 關閉藍牙
  3. enable() 打開藍牙
  4. getAddress() 得到本地藍牙適配器的地址
  5. getBondedDevices() 得到已經綁定的藍牙的設備
  6. getDefaultAdapter() 得到本地藍牙適配器
  7. getName() 得到本地藍牙的名稱
  8. getRemoteDevice(byte[] address) 得到遠程藍牙設備
  9. getRemoteDevice(String address) 得到遠程藍牙設備
  10. isEnabled() 判斷藍牙是否打開
  11. setName(String name) 設置藍牙名稱
  12. startDiscovery() 開始搜多附近藍牙
  13. listenUsingInsecureRfcommWithServiceRecord(String name, UUID uuid) 創建 BluetoothServerSocket
  • BluetoothDevice
  1. createBond() 藍牙配對 (低版本不支持,>=api19)
  2. createRfcommSocketToServiceRecord(UUID uuid) 創建 BluetoothSocket
  3. getBondState() 得到配對的狀態
  4. getAddress() 得到遠程藍牙適配器的地址
  5. getName() 得到遠程藍牙的名稱
  • BluetoothSocket 與 BluetoothServerSocket

這兩個 API 和Socket 和ServerSocket 差不多 這裏不予介紹

*** 當然了,Android 中藍牙相關的API還很多!這裏我只說了幾個常用的!!!! ***

Android 中的實戰

** 現在我們就按照正常的邏輯來走! **

第一步

我們要先得到 藍牙本地適配器,來判斷設備是否支持藍牙!

    mAdapter=BluetoothAdapter.getDefaultAdapter();
    //判斷設備是否支持藍牙
    if (mAdapter==null){
        Toast.makeText(this, "不支持藍牙", Toast.LENGTH_SHORT).show();
    }
第二步

好了!現在下面要做的就是判斷藍牙是否打開了!沒有打開則打開!

	if (!mAdapter.isEnabled()){//藍牙沒有打開
      //  mAdapter.enable();//不支持這樣寫,影響用戶體驗

        //建議使用這種方式
        Intent intent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(intent, 200);
    }

代碼寫得很清楚!我就不解釋啦!!!

第三步

成功打開藍牙之後,要想別人的適配上能夠發現,我們得設置藍牙的可見性,現在我就來設置藍牙的可見性!看代碼

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode==200){
        Intent dis=new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
        dis.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
        startActivity(dis);
    }
}

不知大家有沒有注意到,我是在 onActivityResult(int requestCode, int resultCode, Intent data) 這個回調函數中設置藍牙可見性的!因爲我們在打開藍牙的時候用了 startActivityForResult(Intent intent,int requestCode) 這個方法!還有一點大家也要注意 就是藍牙在設置可見性的時候,有個時常。就是這個字段 BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION 對應的值!這個最大值是300秒!

第四步

至此,我們就可以搜索附近的藍牙啦!那麼有同學會問了,我們怎麼知道有設備被搜索到呢?這個很簡單哦!但我們搜索到設備的時候,系統就會給我們發送廣播啦!我們只有註冊個廣播接收器就行啦!

mAdapter.startDiscovery();//開始搜索

//註冊藍牙廣播接收器。
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);//發現藍牙動作
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索結束動作
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);//搜素開始動作
registerReceiver(blueReceiver, filter);

 /**
 * 藍牙接收器
 **/
public class BlueReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(BluetoothDevice.ACTION_FOUND)) {
            BluetoothDevice device = 						intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            deviceList.add(device);
            adapter.notifyDataSetChanged();
        }
        if (intent.getAction().equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
				
        }
        if (intent.getAction().equals(BluetoothAdapter.ACTION_DISCOVERY_STARTED)) {

        }
    }
}

在 BlueReceiver 中我只是簡單的把搜索到得設備放到集合中。被沒有做過多的操作!

第五步

現在到了比較重要的步驟了!當我們搜索到了藍牙的之後,我要配對,因爲只有在配對之後才能連接哦!

  BluetoothDevice device = (BluetoothDevice) adapter.getItem(i);
  if (device.getBondState() == BluetoothDevice.BOND_BONDED) {//是否已配對
         connect(device);
   } else {
      
              try {
        		Method boned=device.getClass().getMethod("createBond");
        		boolean isok= (boolean) boned.invoke(device);
        		if(isok)
        		{
        			 connect(device);
        		}
    		  } catch (Exception e) {
       				 e.printStackTrace();
        			
    		  }
         
  }

這裏,我想說明的是就是這個配對,在 API19 之後 createBond() Android對外提供了這個方法!但是在 API19 以前並沒有提供這個方法,所以呢我只能用反射了!這個兼容性比較好奧!!

第六步

現在,就很簡答啦!只要連接就行啦!在這裏我放在了一個線程中了!

private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;

    public ConnectThread(BluetoothDevice device) {
        mmDevice = device;
        BluetoothSocket tmp = null;

        try {
            tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) {
            Log.e(TAG, "create() failed", e);
        }
        mmSocket = tmp;
    }

    @Override
    public void run() {
        Log.i(TAG, "BEGIN mConnectThread");
        setName("ConnectThread");

        mAdapter.cancelDiscovery();
        try {

            mmSocket.connect();

        } catch (IOException e) {
            connectionFailed();
            try {
                mmSocket.close();
            } catch (IOException e2) {
                Log.e(TAG, "unable to close() socket during connection failure", e2);
            }
            BlueToothService.this.start();
            return;
        }

        synchronized (BlueToothService.this) {
            mConnectThread = null;
        }

        connected(mmSocket, mmDevice);//這裏是另外一個讀取數據的線程,這裏就和socket操作一樣了
        write("start".getBytes());
    }

    public void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) {
            Log.e(TAG, "close() of connect socket failed", e);
        }
    }
}

** 好啦!如果你讀到這裏 就也就學會了藍牙的簡單操作了! **

發佈了115 篇原創文章 · 獲贊 8 · 訪問量 42萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章