序文
ここ 2 日間、私は Android 版の携帯電話 Bluetooth 通信 APP を開発しており、Android Bluetooth マシンについて簡単な調査を行ってきました。
Android の Bluetooth は、クラシック Bluetooth (BR/EDR) と Bluetooth Low Energy (BLE) の 2 種類に分けられます。
クラシック Bluetooth を開発したので、開発方法について簡単に説明します。
開発する前に、Google の公式 Bluetooth 説明書を読むことをお勧めします。
https://developer.android.google.cn/guide/topics/connectivity/bluetooth
クラシックブルートゥース
許可申請の第一歩
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <!-- 仅在支持BLE(即蓝牙4.0)的设备上运行 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- 如果Android 6.0蓝牙搜索不到设备,需要补充下面两个权限 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" /> <!-- 网络权限 -->
おそらく非常に多くの許可を申請する必要がある
ここから始める前に、Android 9 以降では、キーの権限を呼び出す前にユーザーが 2 回目の確認を行う必要があるため、この検索を権限コールバックに記述する必要があることに注意してください。
//申请用户权限
ActivityCompat.requestPermissions(MainActivity.this, mPermissionListnew, mOpenCode);
2 番目のステップは、検索を開始することです
現在の Bluetooth マネージャーを取得する
mBluetooth = BluetoothAdapter.getDefaultAdapter();
現在の Bluetooth が有効かどうかを確認します
//蓝牙服务未启动
if (!mBluetooth.isEnabled()) {
boolean enable = mBluetooth.enable();
if (!enable) {
SystemExit(getString(R.string.initBluetooth));
return;
}
}
以下は完全なコードです
// 权限回调
@Override
@SuppressLint("MissingPermission")
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
//判断权限是否同意 这里要注意下,每个安卓版本的权限是不一样的
for (Integer permission : grantResults) {
if (permission != 0) {
SystemExit(getString(R.string.run));
return;
}
}
//从系统服务中获取蓝牙管理器
//这里虽然写了很多,但是BluetoothAdapter.getDefaultAdapter() 这个就可以的
if (mBluetooth == null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//从系统服务中获取蓝牙管理器
BluetoothManager bm = getSystemService(BluetoothManager.class);
mBluetooth = bm.getAdapter();
} else {
//获取系统默认的蓝牙适配器
mBluetooth = BluetoothAdapter.getDefaultAdapter();
}
if (mBluetooth == null) {
SystemExit("没有蓝牙功能");
return;
}
}
//蓝牙服务未启动
if (!mBluetooth.isEnabled()) {
boolean enable = mBluetooth.enable();
if (!enable) {
SystemExit(getString(R.string.initBluetooth));
return;
}
}
if (requestCode == mOpenCode) {
//初始化蓝牙
initBluetooth();
}
}
上記に書かれた多くの内容は、実際にはアプリケーション権限のバッチにまだ残っています。
Bluetooth スキャンを開始しましょう
それが上記のinitBluetooth() メソッドです
Bluetooth スキャンをオンにする
Bluetooth スキャンをオンにするのは非常に簡単で、startDiscovery() メソッドを呼び出すだけです。
@SuppressLint("MissingPermission")
private void beginDiscovery() {
if (mBluetooth != null && !mBluetooth.isDiscovering()) {
mBluetooth.startDiscovery();//开始扫描周围的蓝牙设备
}
}
Bluetoothスキャンで返されたデータを取得する
Bluetooth スキャン データを取得するには、まずブロードキャストに登録し、ブロードキャスト コールバックを通じてデータを取得する必要があります。
//需要过滤多个动作,则调用IntentFilter对象的addAction添加新动作
IntentFilter discoveryFilter = new IntentFilter();
//获取新的数据
discoveryFilter.addAction(BluetoothDevice.ACTION_FOUND);
//连接上了
discoveryFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
//状态改变
discoveryFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
//蓝牙连接状态更改
discoveryFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
//蓝牙即将断开
discoveryFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED);
//注册蓝牙设备搜索的广播接收器 discoveryReceiver()这个是回调函数
registerReceiver(discoveryReceiver, discoveryFilter);
コールバックメソッド
@SuppressLint("MissingPermission")
public final BroadcastReceiver discoveryReceiver = new BroadcastReceiver() {
@RequiresApi(api = Build.VERSION_CODES.R)
@SuppressLint("NotifyDataSetChanged")
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
int bondState = device.getBondState();
Fruit fruit = new Fruit();
fruit.setAddress(device.getAddress());
//发现新的蓝牙设备
fruit.setName(device.getName());
if (fruit.getName() == null || fruit.getName().length() == 0) {
fruit.setName("N/A");
}
fruit.setState(bondState);
fruit.setBluetoothType(device.getType());
short rssi = intent.getExtras().getShort(BluetoothDevice.EXTRA_RSSI);
fruit.setRssi(rssi + "");
fruit.setBluetoothDevice(device);
onActivityDataChangedListener.addFruitData(fruit);
switch (action) {
case BluetoothDevice.ACTION_FOUND:
break;
//蓝牙状态修改
//断开蓝牙连接
case BluetoothDevice.ACTION_ACL_DISCONNECTED:
case BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED:
BluetoothServiceConnect remove = StaticObject.bluetoothSocketMap.remove(device.getAddress());
if (remove != null) {
ToastUtil.toastWord(MainActivity.this, MainActivity.this.getString(ConnectTheInterrupt));
remove.close();
Msg m = new Msg(device.getAddress());
m.setStateType(1);
try {
StaticObject.mTaskQueue.put(m);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//蓝牙状态修改
case BluetoothDevice.ACTION_ACL_CONNECTED:
case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
/* fruit.setState(bondState);
short rssi = intent.getExtras().getShort(BluetoothDevice.EXTRA_RSSI);
fruit.setRssi(rssi + "");
onActivityDataChangedListener.addFruitData(fruit);*/
//adapter.notifyDataSetChanged();
break;
}
}
};
さらに、**getBondedDevices()** メソッドを通じて、ペアリングされた Bluetooth 情報を取得できます。
Set<BluetoothDevice> bondedDevices = mBluetooth.getBondedDevices();
if (bondedDevices != null && bondedDevices.size() != 0) {
for (BluetoothDevice device : bondedDevices) {
Fruit fruit = new Fruit();
fruit.setAddress(device.getAddress());
fruit.setName(device.getName());
fruit.setState(device.getBondState());
fruit.setBluetoothType(device.getType());
fruit.setBluetoothDevice(device);
onActivityDataChangedListener.addFruitData(fruit);
}
}
Bluetoothを接続する
上記で Bluetooth ドライバーを取得しました。次のステップは Bluetooth に接続することです。このステップは比較的簡単です
メソッド コールバックを通じて BluetoothDevice オブジェクトを取得し、createInsecureRfcommSocketToServiceRecord() メソッドを呼び出し、uuid を渡して Socker 接続を取得します。
uuid の説明https://note.youdao.com/s/QLLkD2ZA
static final String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";
BluetoothSocket insecureRfcommSocketToServiceRecord= bluetoothDevice.createInsecureRfcommSocketToServiceRecord(UUID.fromString(SPP_UUID));
insecureRfcommSocketToServiceRecord.connect();
//然后这里就获取到输入流和输出流,接下来就可以进行交互了
insecureRfcommSocketToServiceRecord.getOutputStream()
insecureRfcommSocketToServiceRecord.getInputStream()