android bluetooth--Bluetooth on、検索、ペアリング、接続
アンドロイド
の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);
関連
-
Android: インポートモジュールエラー Android リソースのリンクに失敗しました
-
エラーが発生しました。ArrayAdapter は、リソース ID が TextView である必要があります。
-
ActivityはOnFragmentInteractionListenerを実装しなければならないに関する質問
-
Google PlayデバイスはPlay保護機構の認証を受けていません。
-
アンドロイドスタジオのエラーを解決する --> Error:(1, 0) id 'com.android.application' を持つプラグインが見つかりません。
-
Android ProgressBarの色を変更する
-
Androidカスタムドロップダウンリストボックスコントロール
-
Android.support.v7.widget.Toolbar が見つかりませんでした。
-
Android studio 制約レイアウト ConstraintLayout
-
cmakeを使用しているアンドロイドスタジオはc++をサポートし、問題は、cmakeのエラーを同期することはできません。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Android端末にADBが接続できない!を解決。理由: デバイスが認証されていない!
-
java.lang.NullPointerException: NULLオブジェクト参照で仮想メソッド......を呼び出そうとしました。
-
android.os の NetworkOnMainThreadException。
-
gitlab 設定エラー。リモートリポジトリから読み込めなかったか、ホストキーの検証に失敗しました。
-
Android のパッケージングに失敗し、Android リソースのリンクに失敗したことを示すプロンプトが表示される
-
repo: コマンドが見つかりません
-
アプリの実行エラー。ターゲットデバイスが見つからない問題
-
Android Studio常见错误之:Rendering Problems/The following classes could not be instantiated
-
CursorIndexOutOfBoundsException:インデックス -1 が要求されました。
-
新しいAndroidプロジェクトの作成時に、AndroidManifest.xmlファイルが見つからないというプロンプトが表示されます。