1、获取蓝牙适配器;是调用蓝牙设置接口的管理类;
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
2、判断蓝牙是否开启
btAdapter.isEnabled();
3、开启/关闭蓝牙
btAdapter.enable();
btAdapter.disable();
4、搜索蓝牙设备
//调用改方法后,开始搜索蓝牙设备并通过广播返回
btAdapter.startDiscovery();
5、取消搜索蓝牙设备
if (btAdapter.isDiscovering()) {
btAdapter.cancelDiscovery();
}
6、获取已配对的蓝牙设备列表
Set<BluetoothDevice> devices = btAdapter.getBondedDevices();
if (devices != null && !devices.isEmpty()) {
Iterator<BluetoothDevice> iterator = devices.iterator();
while (iterator.hasNext()) {
BluetoothDevice bluetoothDevice = iterator.next();
Log.d(TAG, "getBondDevices: bluetoothDevice: " + bluetoothDevice.getName());
if (bluetoothDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
//设备已配对
...
}
}
}
7、获取当前正在连接中的蓝牙设备
Set<BluetoothDevice> devices = btAdapter.getBondedDevices();
if (devices != null && !devices.isEmpty()) {
Iterator<BluetoothDevice> iterator = devices.iterator();
while (iterator.hasNext()) {
BluetoothDevice bluetoothDevice = iterator.next();
Log.d(TAG, "getBondDevices: bluetoothDevice: " + bluetoothDevice.getName());
if (bluetoothDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
boolean isConnect = false;
//isConnected系统接口是隐藏的,需要使用反射的方式来调用;
try {
Method method = BluetoothDevice.class.getDeclaredMethod("isConnected", (Class[]) null);
method.setAccessible(true);
//返回true表示设备正在连接中
isConnect = (boolean) method.invoke(bluetoothDevice, (Object[]) null);
Log.d(TAG, "getBondDevices: isConnect: "+isConnect);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
8、配对某个蓝牙设备
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
pair(device);
} else {
Toast.makeText(context.getApplicationContext(), "该设备已经绑定", Toast.LENGTH_SHORT).show();
}
/**
* 蓝牙配对
*/
private void pair(final BluetoothDevice device) {
ThreadManager.getInstance().startIoExecutor(new Runnable() {
@Override
public void run() {
try {
Method method = device.getClass().getMethod("createRfcommSocket", new Class[]{int.class});
BluetoothSocket socket = (BluetoothSocket) method.invoke(device, 1);
socket.connect();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
9、删除已配对的某个蓝牙设备
public void unBondDevice(BluetoothDevice device) {
if (device == null || btAdapter == null) {
return;
}
try {
Method m = device.getClass().getMethod("removeBond", (Class[]) null);
m.invoke(device, (Object[]) null);
} catch (Exception e) {
Log.d(TAG, e.getMessage());
}
}
10、蓝牙相关广播监听
IntentFilter filter = new IntentFilter();
//蓝牙状态变化广播
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
//开始扫描蓝牙设备广播
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
//找到蓝牙设备广播
filter.addAction(BluetoothDevice.ACTION_FOUND);
//蓝牙设备连接回调
filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
//断开连接的蓝牙设备回调
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
filter.addAction(BluetoothDevice.ACTION_FOUND);
//扫描蓝牙设备结束广播
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
//蓝牙设备配对状态改变广播
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
//设备扫描模式改变广播
filter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
//蓝牙请求配对广播
filter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
//蓝牙配对连接状态广播
filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
//蓝牙音频状态广播,用于检测蓝牙音频设备(例如耳机、音箱)的连接状态变化。
filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothDevice.ACTION_UUID);
//蓝牙控制广播
filter.addAction(BluetoothAvrcpController.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothAvrcpController.ACTION_PLAYER_SETTING);
context.registerReceiver(btReceiver, filter);
private final BroadcastReceiver btReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, "onReceive: action: " + action);
switch (action) {
case BluetoothAdapter.ACTION_STATE_CHANGED:
//BluetoothAdapter.STATE_OFF: 蓝牙已关闭。
//BluetoothAdapter.STATE_TURNING_OFF: 蓝牙正在关闭中。
//BluetoothAdapter.STATE_ON: 蓝牙已开启。
//BluetoothAdapter.STATE_TURNING_ON: 蓝牙正在开启中。
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
if (iBtLis != null) {
iBtLis.onBtStateChanged(state);
}
break;
case BluetoothAdapter.ACTION_DISCOVERY_STARTED:
Log.d(TAG, "onReceive: 开始搜索");
break;
case BluetoothDevice.ACTION_FOUND:
Log.d(TAG, "onReceive: 搜索到蓝牙设备");
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d(TAG, "onReceive: device: " + device.getName());
if (iBtLis != null) {
iBtLis.onSearchedDevice(device);
}
break;
case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
Log.d(TAG, "onReceive: 搜索结束");
break;
case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
BluetoothDevice device2 = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//BluetoothDevice.BOND_NONE: 设备当前没有配对。
//BluetoothDevice.BOND_BONDING: 设备当前正在进行配对。
//BluetoothDevice.BOND_BONDED: 设备当前已成功配对。
int state2 = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
Log.d(TAG, "onReceive: state: " + state2);
if (iBtLis != null) {
iBtLis.onBondStateChanged(device2, state2);
}
if (state2 == BluetoothDevice.BOND_BONDED) {
connectMediaBrowser();
} else {
disconnectMediaBrowser();
}
break;
case BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED:
BluetoothDevice device3 = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//BluetoothAdapter.STATE_DISCONNECTED: 表示蓝牙连接已断开。
//BluetoothAdapter.STATE_CONNECTING: 表示正在建立蓝牙连接。
//BluetoothAdapter.STATE_CONNECTED: 表示蓝牙连接已建立。
//BluetoothAdapter.STATE_DISCONNECTING: 表示正在断开蓝牙连接。
int state3 = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, BluetoothAdapter.STATE_DISCONNECTED);
if (iBtLis != null) {
iBtLis.onConnectStateChanged(device3, state3);
}
break;
case BluetoothAdapter.ACTION_SCAN_MODE_CHANGED:
//BluetoothAdapter.SCAN_MODE_NONE: 表示蓝牙设备没有启用扫描模式。
//BluetoothAdapter.SCAN_MODE_CONNECTABLE: 表示蓝牙设备处于可连接模式,可以接受来自其他设备的连接请求。
//BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE: 表示蓝牙设备处于可连接和可被发现模式,可以接受连接请求并被其他设备发现。
int mode = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE, BluetoothAdapter.SCAN_MODE_NONE);
break;
case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED:
//BluetoothProfile.STATE_DISCONNECTED: 表示 A2DP 连接已断开。
//BluetoothProfile.STATE_CONNECTING: 表示正在建立 A2DP 连接。
//BluetoothProfile.STATE_CONNECTED: 表示 A2DP 连接已建立。
//BluetoothProfile.STATE_DISCONNECTING: 表示正在断开 A2DP 连接。
int state4 = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED);
BluetoothDevice device4 = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
break;
case BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED:
break;
case BluetoothDevice.ACTION_ACL_CONNECTED:
BluetoothDevice device5 = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d(TAG, "onReceive: Connected device: " + device5.getName());
break;
case BluetoothDevice.ACTION_ACL_DISCONNECTED:
BluetoothDevice device6 = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d(TAG, "onReceive: Disconnected device: " + device6.getName());
break;
}
}
};
11、蓝牙音乐连接控制
public void connectMediaBrowser() {
if (null != mMediaBrowser) {
disconnectMediaBrowser();
}
int version = Build.VERSION.SDK_INT;
if (version > Build.VERSION_CODES.P) { //适配安卓10
Log.i(TAG, "version > Build.VERSION_CODES.P");
mMediaBrowser = new MediaBrowser(context,
new ComponentName(BT_BROWSED_PACKAGE, "com.android.bluetooth.avrcpcontroller.BluetoothMediaBrowserService"),
mConnectionCallback, null);
} else {
Log.i(TAG, "version <= Build.VERSION_CODES.P");
mMediaBrowser = new MediaBrowser(context,
new ComponentName(BT_BROWSED_PACKAGE, BT_BROWSED_SERVICE),
mConnectionCallback, null);
}
mMediaBrowser.connect();
Log.d(TAG, "connectMediaBrowser: " + mMediaBrowser.isConnected());
mTryConnectMediaSessionCnt++;
}
private MediaBrowser.ConnectionCallback mConnectionCallback = new MediaBrowser.ConnectionCallback() {
@Override
public void onConnected() {
Log.d(TAG, "onConnected: session token " + mMediaBrowser.getSessionToken());
if (mMediaBrowser.getSessionToken() == null) {
throw new IllegalArgumentException("No Session token");
}
//get mediaContoller
mMediaController = new MediaController(
context, mMediaBrowser.getSessionToken());
mMediaController.registerCallback(mMediaControllerCallback);
mTryConnectMediaSessionCnt = 0;
}
@Override
public void onConnectionFailed() {
Log.d(TAG, "onConnectionFailed");
if (mTryConnectMediaSessionCnt <= 5) {
connectMediaBrowser();
}
}
@Override
public void onConnectionSuspended() {
Log.d(TAG, "onConnectionSuspended");
mTryConnectMediaSessionCnt = 0;
}
};
/**
* 蓝牙音乐监听
*/
private final MediaController.Callback mMediaControllerCallback =
new MediaController.Callback() {
@Override
public void onPlaybackStateChanged(final PlaybackState playbackState) {
if (playbackState != null) {
Log.d(TAG, "onPlaybackStateChanged: playbackState: " + playbackState);
int state = playbackState.getState();
long position = playbackState.getPosition();
if (iBtMusicLis != null) {
BtMusicStateBean btMusicStateBean = new BtMusicStateBean();
btMusicStateBean.setState(state);
btMusicStateBean.setPosition(position);
iBtMusicLis.onBtMusicStateChanged(btMusicStateBean);
}
}
}
@Override
public void onMetadataChanged(final MediaMetadata mediaMetadata) {
if (mediaMetadata != null) {
//歌词
String title = mediaMetadata.getString(MediaMetadata.METADATA_KEY_TITLE);
//歌手-歌词
String artist = mediaMetadata.getString(MediaMetadata.METADATA_KEY_ARTIST);
//歌曲长度 ms
long duration = mediaMetadata.getLong(MediaMetadata.METADATA_KEY_DURATION);
//歌名
String album = mediaMetadata.getString(MediaMetadata.METADATA_KEY_ALBUM);
Log.d(TAG, "onMetadataChanged: title: " + title
+ " artist: " + artist
+ " duration: " + duration
+ " album: " + album
);
if (artist.contains("-")) {
artist = artist.split("-")[0];
}
if (iBtMusicLis != null) {
BtMusicBean btMusicBean = new BtMusicBean();
btMusicBean.setMusicName(album);
btMusicBean.setMusicAuthor(artist);
btMusicBean.setMusicText(title);
btMusicBean.setMusicTime(duration);
iBtMusicLis.onBtMusicChanged(btMusicBean);
}
}
}
@Override
public void onQueueChanged(final List<MediaSession.QueueItem> queue) {
Log.d(TAG, "onQueueChanged: " + queue);
}
@Override
public void onSessionDestroyed() {
Log.d(TAG, "onSessionDestroyed:!!!");
}
};
/**
* 蓝牙音乐控制
*/
private boolean BtMusicPlayContorlCmd(int cmd) {
Log.d(TAG, "BtMusicPlayContorlCmd is cmd = " + cmd);
if (null == mMediaController || null == mMediaController.getTransportControls()) {
Log.d(TAG, "mediaSession is not ready");
return false;
}
MediaController.TransportControls mediaControllerCntrl =
mMediaController.getTransportControls();
switch (cmd) {
case BtGlobal.CMD_PLAY:
mediaControllerCntrl.play();
break;
case BtGlobal.CMD_PAUSE:
mediaControllerCntrl.pause();
break;
case BtGlobal.CMD_PRV:
mediaControllerCntrl.skipToPrevious();
break;
case BtGlobal.CMD_NEXT:
mediaControllerCntrl.skipToNext();
break;
}
return true;
}