1. ホーム
  2. android

android bluetooth--Bluetooth on、検索、ペアリング、接続

2022-02-17 20:12:41
<パス

アンドロイド のbltは、api18 android4.3以上しかサポートしておらず、一部の機能ではapi19 android4.4も必要です。
ですから、bltプロジェクトを作る前に、利用できるバージョンの範囲を明確にしておく必要があります。

これからbltの扉を開く操作についてお話します。Bltを開く方法、他のデバイスを検索する方法、選択したデバイスをペアリングする方法、以前にペアリングしたデバイスをマックアドレスで接続する方法、接続した2台(または複数台のペア)のデバイスが正常に通信する方法など、です。

bltについて学ぶ前に、bltによって2つのデバイスが互いに通信する方法を理解することが重要です。基本的な手順を見てみましょう。

1、bltを開く。
-1) パーミッション
-2) Bltをオンにするデバイスのリスニング
--3) Bltのオン/オフを切り替えるアクション

2, 近くのデバイスを検索する & 近くのデバイスに検索させる
-1) 近くの端末を最大300秒まで検索可能にする(apiの段階的なバージョンアップで300秒以上になる可能性がある。)
-2) 近くの接続可能なデバイスを検索する。旧来のapiは検索結果をインターフェースでコールバックし、新しいapiは検索結果をブロードキャストで受け取るように依頼する。(ここではブロードキャストで結果を受け取るようにしている)。

3、ターゲットデバイスとのペアリング
-1) ペアリングするターゲットデバイスのために、アンドロイドシステム自体がペアリング動作を完了し、次回の自動ペアリングのためにペアリングに成功したデバイスのマックアドレスを保存します。
-2) ペアリングされたデバイスの自動ペアリング。このアクションもシステムによって行われます。私たちは、システムによって与えられたステータスに基づいて、これがペアリングされているかどうかを判断する必要があるだけです。

4. ペアリングに成功したデバイスと接続する
-1) ペアリングに成功した機器に接続する場合、まずサーバー側を確立する必要があります。サーバー側は、クライアントが接続するのを待つスレッドブロックを行う場合にのみ確立されます。
-2) クライアント側が確立する前に、サーバー側が確立するようにしてください。クライアント側の接続処理もスレッドブロック化する。接続が成功したことを知り、サーバー側はペアリングされたデバイスが正常に接続されたことをメッセージとして受け取ります。

5、注意事項
-1) ペアリングに成功したデバイスは、再度ペアリングする必要はなく、システムからマックアドレスを取得するだけで接続できます。これは、システムから返されるステータス値に従って行われます。
-2) 近くのデバイスを検索することは、メモリを消費する動作であり、デバイスを接続する「前」に検索を停止しなければならない。
-3) デバイスのペアリングに成功しても、接続に成功するわけではありません。ペアリングと接続は別のものであり、ペアリングは接続動作の前に行われます。
--(-4) プログラムが明示的に "no more blt operations" と言ったら、blt broadcast の登録を解除し、blt connection を停止し、Bluetooth オブジェクトをログオフさせます。これは、例えば、プログラムの終了、ユーザーのノーアクションのタイムアウト、または論理的にblt接続を必要としないことによって行われます。

以上が、Bluetooth接続が成功した後に、正しく情報を転送できる手順です。
次に、対応するステップがコードロジックでどのように表現されるかを見ていきます。

1、パーミッション

  • 1
  • 2
  • 1
  • 2
2, get the BluetoothManager object. the main role of BluetoothManager is to get the object we need from it //@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) //First get the BluetoothManager BluetoothManager bluetoothManager=(BluetoothManager) context.getService(Context.BLUETOOTH_SERVICE);
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3
3, Get the Bluetooth adapter. The Bluetooth adapter is our main object for manipulating Bluetooth, from which we can get the paired Bluetooth collection, get the Bluetooth transport object, and so on //Get the BluetoothAdapter if (bluetoothManager ! = null) BluetoothAdapter mBluetoothAdapter = bluetoothManager.getAdapter();
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3
3, Register the broadcast to receive Bluetooth pairing information. Call before Bluetooth is turned on // Use BroadcastReceiver to get search results IntentFilter intent = new IntentFilter(); intent.addAction(BluetoothDevice.ACTION_FOUND);// search for found devices intent.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);//state change intent.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);//action scan mode changed intent.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);//action state changed context.registerReceiver(searchDevices, intent);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
/** * Bluetooth receiving broadcast */ private BroadcastReceiver searchDevices = new BroadcastReceiver() { // Receive public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Bundle b = intent.getExtras(); Object[] lstName = b.keySet().toArray(); // Show all received messages and their details for (int i = 0; i < lstName.length; i++) { String keyName = lstName[i].toString(); Log.e("bluetooth", keyName + ">>>>" + String.valueOf(b.get(keyName))); } BluetoothDevice device; // Get the information of the device when searching for the device; note, it is possible to search for the same device again and again here if (BluetoothDevice.ACTION_FOUND.equals(action)) { device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); onRegisterBltReceiver.onBluetoothDevice(device); } //When status change else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) { device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); switch (device.getBondState()) { case BluetoothDevice.BOND_BONDING:// pairing now Log.d("BlueToothTestActivity", "pairing ...... "); onRegisterBltReceiver.onBltIng(device); break; case BluetoothDevice.BOND_BONDED://pairing is finished Log.d("BlueToothTestActivity", "Finished pairing"); onRegisterBltReceiver.onBltEnd(device); break; case BluetoothDevice.BOND_NONE://unpaired/unpaired Log.d("BlueToothTestActivity", "Unpairing"); onRegisterBltReceiver.onBltNone(device); default: break; } } } };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
4, Anti-registration broadcast and clear Bluetooth connection. Call when you don't need to use Bluetooth /** * Anti-registration broadcast to unpair Bluetooth * * @param context */ public void unregisterReceiver(Context context) { context.unregisterReceiver(searchDevices); if (mBluetoothAdapter ! = null) mBluetoothAdapter.cancelDiscovery(); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
5, determine if the current device supports Bluetooth, and if so, turn it on /** * Determine if Bluetooth is supported and turn on Bluetooth * After getting the BluetoothAdapter, you still need to determine if Bluetooth is supported, and if Bluetooth is turned on. * If it is not turned on, you need to ask the user to turn on Bluetooth. */ public void checkBleDevice(Context context) { if (mBluetoothAdapter ! = null) { if (!mBluetoothAdapter ! if (!mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); enableBtIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(enableBtIntent); } } else { Log.i("blueTooth", "This phone does not support Bluetooth"); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
6, Search for Bluetooth. Search and add to a custom collection for use in your own program's logic. Note: The results of the search are called back in the broadcast, no callbacks are made here. If you use an outdated interface, the results are called back in the current logic. We are using broadcast here and do not recommend using deprecated methods. /** * Search for Bluetooth devices * Search the BLE device by calling startLeScan() of BluetoothAdapter. * You need to pass BluetoothAdapter.LeScanCallback parameter when calling this method. * So you need to implement BluetoothAdapter.LeScanCallback interface, the result of BLE device search will be returned by this callback. *

* Since the search needs to minimize power consumption, you need to be careful when using it in practice. * 1. stop scanning as soon as the corresponding device is found. * 2. Do not loop through the devices and set a suitable time limit for each search. Avoid continuous non-stop scanning and power consumption when the device is not in the available range. *

* If you only need to search for peripherals with the specified UUID, you can call the startLeScan(UUID[], BluetoothAdapter.LeScanCallback) method. * where the UUID array specifies the UUID of the GATT Services supported by your application. *

* Note: When searching, you can only search for legacy Bluetooth devices or BLE devices, which are completely independent and cannot be searched for at the same time. */

private boolean startSearthBltDevice(Context context) { // Start searching for devices, and when a device is found it should be added to the device collection and saved checkBleDevice(context); //If a new device is found, stop scanning, the new device will be broadcasted to the new logic. if (getmBluetoothAdapter().isDiscovering()) stopSearthBltDevice(); Log.i("bluetooth", "Local Bluetooth address: " + getmBluetoothAdapter().getAddress()); //Start search mBluetoothAdapter.startDiscovery(); // The true here doesn't mean the device is found, but means the search is started successfully. return true; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
7, Stop searching for Bluetooth devices public boolean stopSearthBltDevice() { //pause the search device if(mBluetoothAdapter!=null) return mBluetoothAdapter.cancelDiscovery(); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5
8,Connect to Bluetooth. Note: The prerequisite for connecting to Bluetooth is that we have already set up the Bluetooth server side. So, here we set up the Bluetooth server first
-1) Set up the Bluetooth server side first /** * This operation should be placed in a subthread because of the thread blocking problem */ public void run(Handler handler) { // The server-side bltsocket needs to pass in the uuid and a separate string for authentication, usually in the form of a package name BluetoothServerSocket bluetoothServerSocket = tmBluetoothAdapter.listenUsingRfcommWithServiceRecord("com.bluetooth.demo", BltContant.SPP_UUUID); while (true) { try { //Note, when accept() returns BluetoothSocket, the socket is already connected, so the connect method should not be called. //This will thread block until a Bluetooth device is linked in, then it will go down socket = getBluetoothServerSocket().accept(); if (socket ! = null) { BltAppliaction.bluetoothSocket = socket; // Callback result notification Message message = new Message(); message.what = 3; message.obj = socket.getRemoteDevice(); handler.sendMessage(message); // If your bluetooth device is only a one-to-one connection, then execute the following code getBluetoothServerSocket().close(); //If your bluetooth device is one-to-many, then you should call break; to jump out of the loop //break; } } catch (IOException e) { try { getBluetoothServerSocket().close(); } catch (IOException e1) { e1.printStackTrace(); } break; } } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
-2) After the Bluetooth server is established, then the Bluetooth connection is made. /** * Try to connect to a device, done in a subthread because it will thread block * * @param btDev Bluetooth device object * @param handler Result callback event * @return */ private void connect(BluetoothDevice btDev, Handler handler) { try { // Connect by negotiating uuid with server mBluetoothSocket = btDev.createRfcommSocketToServiceRecord(BltContant.SPP_UUUID); if (mBluetoothSocket ! = null) // There is only one bluetooth globally, so we can save this socket object in appliaction BltAppliaction.bluetoothSocket = mBluetoothSocket; //get bltSocket object by reflection, same result as uuid connection, but we don't advocate to use reflection method here //mBluetoothSocket = (BluetoothSocket) btDev.getClass().getMethod("createRfcommSocket", new Class[]{int.class}).invoke(btDev, 1); Log.d("blueTooth", "Starting connection... "); // Call before establish if (getmBluetoothAdapter().isDiscovering()) //Stop searching getmBluetoothAdapter().cancelDiscovery(); // Call connect if the socket is not connected. if (!getmBluetoothSocket().isConnected()) { // You should make sure the device is not searching for the device at the time of calling connect(). // If the device is searching for a device at the same time, it will significantly slow down the connection rate and will largely fail. getmBluetoothSocket().connect(); } Log.d("blueTooth", "already linked"); if (handler == null) return; //result callback Message message = new Message(); message.what = 4; message.obj = btDev; handler.sendMessage(message); } catch (Exception e) { Log.e("blueTooth", "... Link failed"); try { getmBluetoothSocket().close(); } catch (IOException e1) { e1.printStackTrace(); } e.printStackTrace(); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
9, automatically connect to devices that have been successfully paired in the past. Note: Connection is only possible if the server side is turned on, if not then 8.1 will be performed /** * Trying to pair and connect * * @param btDev */ public void createBond(BluetoothDevice btDev, Handler handler) { if (btDev.getBondState() == BluetoothDevice.BOND_NONE) { if (btDev.getBondState() == BluetoothDevice. // If this device is unpaired, try to pair if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { btDev.createBond(); } } else if (btDev.getBondState() == BluetoothDevice.BOND_BONDED) { // If this device is already paired, try to connect connect(btDev, handler); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
/** * Get the system's saved devices that have been successfully paired and try to connect */ public void getBltList() { if (getmBluetoothAdapter() == null) return; // Get the set of paired remote devices Set<BluetoothDevice> devices = getmBluetoothAdapter().getBondedDevices(); if (devices.size() > 0) { for (Iterator<BluetoothDevice> it = devices.iterator(); it.hasNext(); ) { BluetoothDevice device = it.next(); // automatically connect to existing Bluetooth devices createBond(device, null); } } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
Note: The outside world only needs to call the getBltList(); method for auto-linking. 10, Enter the mac address to automatically connect to the device. The prerequisite is that the system was originally connected to that address. /** * Enter the mac address for auto-pairing * Provided that the system saves the object with that address * * @param address */ public void autoConnect(String address, Handler handler) { if (getmBluetoothAdapter().isDiscovering()) getmBluetoothAdapter().cancelDiscovery(); BluetoothDevice btDev = getmBluetoothAdapter().getRemoteDevice(address); connect(btDev, handler); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
11, Bluetooth connection status. Used to determine whether the Bluetooth device is: unpaired or paired and unconnected or connected public String bltStatus(int status) { String a = "Unknown status"; switch (status) { case BluetoothDevice.BOND_BONDING: a = "Connecting"; break; case BluetoothDevice.BOND_BONDED: a = "Connection complete"; break; case BluetoothDevice.BOND_NONE: a = "Not connected/unconnected"; break; } return a; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
11,蓝牙点击事件。包括蓝牙的打开,关闭,被搜索,断开连接 /** * 蓝牙操作事件 * * @param context * @param status */ public void clickBlt(Context context, int status) { switch (status) { case BltContant.BLUE_TOOTH_SEARTH://搜索蓝牙设备,在BroadcastReceiver显示结果 startSearthBltDevice(context); break; case BltContant.BLUE_TOOTH_OPEN://本机蓝牙启用 if (getmBluetoothAdapter() != null) getmBluetoothAdapter().enable();//启用 break; case BltContant.BLUE_TOOTH_CLOSE://本机蓝牙禁用 if (getmBluetoothAdapter() != null) getmBluetoothAdapter().disable();//禁用 break; case BltContant.BLUE_TOOTH_MY_SEARTH://本机蓝牙可以在300s内被搜索到 Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); context.startActivity(discoverableIntent); break; case BltContant.BLUE_TOOTH_CLEAR://本机蓝牙关闭当前连接 try { if (getmBluetoothSocket() != null) getmBluetoothSocket().close(); } catch (IOException e) { e.printStackTrace(); } break; } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
到此,蓝牙从打开到连接的方法都写完了。最后我们来总结一下。
当我们获得到了bluetoothsocket对象的时候,我们就可以像使用socket编程一样,让两个蓝牙之间传输数据。甚至可以在程序内部监听蓝牙耳机的暂停/播放/音量键等的点击事件。 具体的蓝牙操作,我将放在demo里供大家学习。 demo下载 (function () { ('pre.prettyprint code').each(function () { var lines = ( t h i s ) . t e x t ( ) . s p l i t ( \n ) . l e n g t h ; v a r numbering = $('
    ').addClass('pre-numbering').hide(); ( t h i s ) . a d d C l a s s ( h a s n u m b e r i n g ) . p a r e n t ( ) . a p p e n d ( numbering); for (i = 1; i
    //@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    //First get the BluetoothManager
     BluetoothManager bluetoothManager=(BluetoothManager) context.getService(Context.BLUETOOTH_SERVICE);