如何通过笔记本Java程序控制蓝牙连接的Android手机振动/发声?
实现笔记本Java程序通过蓝牙向Android发送振动/声音提醒
这个需求需要分Android端和桌面Java端两部分实现,核心是通过蓝牙建立Socket通信,桌面端发送指令,Android端接收后执行对应操作。
一、Android端配置与实现
1. 权限配置
在AndroidManifest.xml中添加必要权限:
<!-- 蓝牙基础权限 --> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <!-- Android 6+ 蓝牙扫描/连接需要定位权限 --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- 振动权限 --> <uses-permission android:name="android.permission.VIBRATE" /> <!-- Android 13+ 通知权限(若播放声音需通知栏提示) --> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <!-- 声明蓝牙功能 --> <uses-feature android:name="android.hardware.bluetooth" android:required="true" />
2. 蓝牙服务端实现
创建后台线程监听蓝牙连接,接收指令并执行操作:
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothServerSocket; import android.bluetooth.BluetoothSocket; import android.os.Vibrator; import android.media.MediaPlayer; import android.content.Context; import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.UUID; public class BluetoothServerThread extends Thread { private final BluetoothServerSocket mmServerSocket; private final Context mContext; // 通用串口服务UUID,两端必须一致 private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); public BluetoothServerThread(Context context) { mContext = context; BluetoothServerSocket tmp = null; try { BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (!bluetoothAdapter.isEnabled()) { // 可提示用户开启蓝牙,或调用Intent触发开启 return; } // 创建服务器Socket tmp = bluetoothAdapter.listenUsingRfcommWithServiceRecord("JavaBluetoothServer", MY_UUID); } catch (Exception e) { e.printStackTrace(); } mmServerSocket = tmp; } public void run() { BluetoothSocket socket = null; while (true) { try { // 等待桌面端连接 socket = mmServerSocket.accept(); } catch (Exception e) { break; } if (socket != null) { manageConnectedSocket(socket); try { mmServerSocket.close(); } catch (Exception e) { e.printStackTrace(); } break; } } } private void manageConnectedSocket(BluetoothSocket socket) { try { BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); String command; // 读取桌面端指令 while ((command = reader.readLine()) != null) { switch (command) { case "VIBRATE": // 触发2秒振动 Vibrator vibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE); if (vibrator.hasVibrator()) { vibrator.vibrate(2000); } break; case "PLAY_SOUND": // 播放系统默认提示音,可替换为自定义音频 MediaPlayer mediaPlayer = MediaPlayer.create(mContext, android.provider.Settings.System.DEFAULT_NOTIFICATION_URI); mediaPlayer.start(); break; } } } catch (Exception e) { e.printStackTrace(); } } public void cancel() { try { mmServerSocket.close(); } catch (Exception e) { e.printStackTrace(); } } }
3. 启动蓝牙服务
在Activity或Service中启动线程:
// 示例:在Activity的onCreate中启动 BluetoothServerThread serverThread = new BluetoothServerThread(this); serverThread.start();
二、桌面Java端实现
1. 引入BlueCove库
Java SE无原生蓝牙API,需使用BlueCove库:
- Maven项目在
pom.xml中添加依赖:
<dependency> <groupId>net.sf.bluecove</groupId> <artifactId>bluecove</artifactId> <version>2.1.1</version> </dependency>
- 非Maven项目直接下载BlueCove jar包并添加到项目依赖。
2. 客户端连接与发送指令
编写程序搜索已配对设备,建立连接并发送指令:
import javax.bluetooth.*; import javax.microedition.io.Connector; import javax.microedition.io.StreamConnection; import java.io.OutputStream; public class BluetoothClient { // 与Android端一致的UUID private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); // 替换为你的Android设备蓝牙名称 private static final String TARGET_DEVICE_NAME = "YourAndroidDeviceName"; public static void main(String[] args) { try { LocalDevice localDevice = LocalDevice.getLocalDevice(); DiscoveryAgent agent = localDevice.getDiscoveryAgent(); // 获取已配对设备列表 RemoteDevice[] pairedDevices = agent.retrieveDevices(DiscoveryAgent.PREKNOWN); RemoteDevice targetDevice = null; // 查找目标设备 for (RemoteDevice device : pairedDevices) { if (device.getFriendlyName(false).equals(TARGET_DEVICE_NAME)) { targetDevice = device; break; } } if (targetDevice == null) { System.out.println("未找到已配对的目标设备"); return; } // 建立Socket连接 String connectionURL = "btspp://" + targetDevice.getBluetoothAddress() + ":" + MY_UUID.toString() + ";authenticate=false;encrypt=false"; StreamConnection connection = (StreamConnection) Connector.open(connectionURL); // 发送振动指令 OutputStream outputStream = connection.openOutputStream(); outputStream.write("VIBRATE\n".getBytes()); outputStream.flush(); System.out.println("振动指令已发送"); // 可选:发送播放声音指令 // outputStream.write("PLAY_SOUND\n".getBytes()); // outputStream.flush(); // System.out.println("声音指令已发送"); // 关闭资源 outputStream.close(); connection.close(); } catch (Exception e) { e.printStackTrace(); } } }
三、关键注意事项
- UUID一致性:两端必须使用相同UUID,否则无法建立连接,推荐使用示例中的通用串口服务UUID。
- 蓝牙配对:确保笔记本与Android手机已完成蓝牙配对,否则桌面端无法识别目标设备。
- 线程处理:Android端蓝牙监听必须在后台线程执行,避免主线程ANR;桌面端蓝牙操作建议放在单独线程中(控制台程序可忽略)。
- 权限验证:Android端需确保所有必要权限已授予,尤其是Android 6+的定位权限,否则无法扫描或连接蓝牙设备。
- 设备名称替换:桌面端代码中的
TARGET_DEVICE_NAME需替换为你的Android设备蓝牙名称。
内容的提问来源于stack exchange,提问作者Amit Jain
相关产品推荐
相关产品推荐

