ディレクトリダイレクト
Bluetoothモジュール
Bluetooth 権限を宣言する
アプリでデバイスの検出を開始したり、Bluetooth 設定を操作したりする場合は、アクセス許可に加えてアクセス許可を
BLUETOOTH
宣言する必要があります。BLUETOOTH_ADMIN
ほとんどのアプリケーションは、ローカル Bluetooth デバイスを検出するためにこの権限のみを必要とします。
AndroidManifest.xml ファイルに次の権限を追加します。
<!-- 安卓12之前的蓝牙权限需求-->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<!-- 安卓12新增的蓝牙权限-->
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<!-- 定位权限, 蓝牙搜索需要-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Bluetoothをセットアップする
1.Bluetoothアダプターを入手する
すべての Bluetooth アクティビティで必要です
BluetoothAdapter
。これを取得するにはBluetoothAdapter
、静的getDefaultAdapter()
メソッドを呼び出します。このメソッドは、BluetoothAdapter
デバイス自体の Bluetooth アダプター (Bluetooth ワイヤレス デバイス) を表すオブジェクトを返します。システム全体に対して Bluetooth アダプターは 1 つだけあり、アプリはこのオブジェクトを使用してそれと対話できます。getDefaultAdapter()
が返された場合null
、デバイスは Bluetooth をサポートしていません。
/**
* 获取BluetoothAdapter对象,并判断蓝牙是否获取到
*/
public boolean isBlueToothAvailable() {
//获取BluetoothAdapter对象
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// 判断蓝牙是否可用
return bluetoothAdapter != null;
}
2.Bluetoothを有効にする
次に、Bluetooth が有効になっていることを確認する必要があります。Bluetooth が現在有効になっているかどうかを確認するために呼び出されます
isEnabled()
。このメソッドが false を返した場合、Bluetooth が無効になっていることを意味します。Bluetooth を有効にするように要求するには、 を呼び出してstartActivityForResult()
、Intent オペレーションを渡しますACTION_REQUEST_ENABLE
。この呼び出しでは、(アプリを停止せずに) システム設定を通じて Bluetooth を有効にするリクエストが行われます。
/**
* 启用蓝牙
*
* @param activity 启动该方法的Activity
*/
public void openBlueTooth(Activity activity) {
if (!bluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
activity.startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
} else {
Toast.makeText(activity, "蓝牙已打开", Toast.LENGTH_SHORT).show();
}
}
デバイスの検索
1. ペアリングされたデバイスのクエリ
デバイス検出を実行する前に、ペアリングされたデバイスのセットをクエリして、目的のデバイスが検出状態かどうかを確認する必要があります。これを行うには、 に電話してください
getBondedDevices()
。BluetoothDevice
このメソッドは、ペアになっているデバイスを表すオブジェクトの配列を返します。たとえば、ペアリングされたすべてのデバイスをクエリして、各デバイスの名前と MAC アドレスを取得できます。
/**
* 打印已配对设备
*/
public void printDevice() {
//打印出已配对的设备
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
listAdapter.add(device.getName() + "\n" + device.getAddress());
}
} else {
listAdapter.add("没有已配对设备");
}
}
2. デバイスを検出する
/**
* 广播接收者
* 接收发现蓝牙设备和蓝牙设备扫描结束的广播
*/
private final BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();//获取蓝牙设备
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
//发现设备
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
assert device != null;
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
//如果设备未绑定
listAdapter.add(device.getName() + "\n" + device.getAddress());
}
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
//扫描设备结束
if (listAdapter.getCount() == 0) {
//没有设备
Toast.makeText(BluetoothDeviceListActivity.this, "没有设备",
Toast.LENGTH_SHORT).show();
}
}
}
};
@Override
public void setRequestedOrientation(int requestedOrientation) {
super.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
//注册广播
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
this.registerReceiver(bluetoothReceiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
this.registerReceiver(bluetoothReceiver, filter);
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
listAdapter = new ArrayAdapter<>(this, R.layout.device_name);
ListView lv_device = findViewById(R.id.listView);
Button bt_find = findViewById(R.id.bt_find);
lv_device.setAdapter(listAdapter);
printDevice();
bt_find.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
bluetoothAdapter.startDiscovery(); //开始扫描
}
});
//选择连接设备
lv_device.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View v, int arg2,
long arg3) {
String info = ((TextView) v).getText().toString();
if (info.equals("没有已配对设备")) {
Toast.makeText(getApplicationContext(), "没有已配对设备", Toast.LENGTH_LONG)
.show();
} else {
String address = info.substring(info.length() - 17); //获取蓝牙设备地址
Intent intent = new Intent();
intent.putExtra(EXTRA_DEVICE_ADDRESS, address); //将地址装入EXTRA_DEVICE_ADDRESS
setResult(Activity.RESULT_OK, intent); //将地址传送回MainActivity
finish();
}
}
});
}
接続する
1. デバイスを接続します
/**
* 连接设备
* @param device 蓝牙设备
* @return 连接状态
*/
public boolean connectThread(BluetoothDevice device) {
try {
bluetoothSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
bluetoothAdapter.cancelDiscovery();
bluetoothSocket.connect();
connectStatus = true; //连接成功
// 接收数据进程
new Thread(new Runnable() {
//读线程
@Override
public void run() {
int bytes;
byte[] buffer = new byte[256];
while (true) {
if (bluetoothSocket != null && bluetoothSocket.isConnected()) {
try {
// 接收数据
bytes = bluetoothSocket.getInputStream().read(buffer);
final String readStr = new String(buffer, 0, bytes); //读出的数据
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}).start();
} catch (IOException e) {
connectStatus = false; //连接失败
try {
bluetoothSocket.close();
} catch (IOException e2) {
e.printStackTrace();
}
}
return connectStatus;
}
2. 接続をキャンセルする
/**
* 取消连接
*/
public void cancelConnect() {
try {
bluetoothSocket.close();
connectStatus = false;
} catch (IOException e) {
e.printStackTrace();
}
}
データ送信
1. 青はデータを送信します
/**
* 蓝牙发送数据
*
* @param str 待发送的字符串
*/
public void write(String str) {
if (connectStatus) {
byte[] buffer = str.getBytes();
try {
bluetoothSocket.getOutputStream().write(buffer);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Bluetooth通信テスト結果
SDK バージョン 33 の落とし穴に注意してください
- Android 12 以降では動的許可アプリケーションが必要です。そうでないと、接続された Bluetooth デバイスを取得するときにエラーが報告され、クラッシュします。
- コードは赤で報告されますが、Bluetooth を呼び出す前に動的許可アプリケーションを設定するだけで使用できます。もっと良い解決策があるはずです...
1. まずファイルディレクトリを確認します。
- BluetoothUtils Bluetooth 初期設定のいくつかの方法
- BluetoothDeviceListActivity Bluetooth接続リスト表示
- メインアクティビティのホームページ
- レイアウトの下には UI インターフェイスがあります。
2. 試験方法
1. 携帯電話を使用してラップトップ Bluetooth に接続し、次のように受信 COM ポートを開きます。
2. シリアル ポート デバッグ ツールを開き、ポート番号 (たとえば、私のポートは COM6 ポート) を選択し、シリアル ポートを開きます。
3. Android プログラムをコンパイルして携帯電話にインストールし、左側で [Bluetooth に接続] をクリックし、右側でコンピュータの Bluetooth デバイスを選択します。
4. [送信] ボタンをクリックして、デバッグ ツールへの影響を確認します。
拡大する
Android 側で Bluetooth データ送信を実装することに成功すると、ハードウェアを統合していくつかの機能を実装できます。
- Bluetooth カーは指示を送信することで車の動きを制御します。
- 照明のオンオフやエアコン、カーテンなどの制御といったスマートホームは、当然ながらマイコン上でしか遊べず、実用化にはまだまだ遠い。
詳細については、公式ドキュメントを参照してください: Bluetooth の概要 | Android 開発者 | Android 開発者 (google.cn)
完全なコード リポジトリ: https://gitee.com/chafaner