我正在制作一个蓝牙连接的应用程序,如下面的代码所示,我可以将两个设备相互配对,但是问题是我无法取消配对这些设备。
蓝牙控制器:
public class BluetoothController implements Closeable {
/**
* Tag string used for logging.
*/
private static final String TAG = "BluetoothManager";
/**
* Interface for Bluetooth OS services.
*/
private final BluetoothAdapter bluetooth;
/**
* Class used to handle communication with OS about Bluetooth system events.
*/
private final BroadcastReceiverDelegator broadcastReceiverDelegator;
/**
* The activity which is using this controller.
*/
private final Activity context;
/**
* Used as a simple way of synchronization between turning on the Bluetooth and starting a
* device discovery.
*/
private boolean bluetoothDiscoveryScheduled;
/**
* Used as a temporary field for the currently bounding device. This field makes this whole
* class not Thread Safe.
*/
private BluetoothDevice boundingDevice;
/**
* Instantiates a new BluetoothController.
*
* @param context the activity which is using this controller.
* @param listener a callback for handling Bluetooth events.
*/
public BluetoothController(Activity context,BluetoothAdapter adapter, BluetoothDiscoveryDeviceListener listener) {
this.context = context;
this.bluetooth = adapter;
this.broadcastReceiverDelegator = new BroadcastReceiverDelegator(context, listener, this);
}
/**
* Checks if the Bluetooth is already enabled on this device.
*
* @return true if the Bluetooth is on, false otherwise.
*/
public boolean isBluetoothEnabled() {
return bluetooth.isEnabled();
}
/**
* Starts the discovery of new Bluetooth devices nearby.
*/
public void startDiscovery() {
broadcastReceiverDelegator.onDeviceDiscoveryStarted();
// This line of code is very important. In Android >= 6.0 you have to ask for the runtime
// permission as well in order for the discovery to get the devices ids. If you don't do
// this, the discovery won't find any device.
if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(context,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
1);
}
// If another discovery is in progress, cancels it before starting the new one.
if (bluetooth.isDiscovering()) {
bluetooth.cancelDiscovery();
}
// Tries to start the discovery. If the discovery returns false, this means that the
// bluetooth has not started yet.
Log.d(TAG, "Bluetooth starting discovery.");
if (!bluetooth.startDiscovery()) {
Toast.makeText(context, "Error while starting device discovery!", Toast.LENGTH_SHORT)
.show();
Log.d(TAG, "StartDiscovery returned false. Maybe Bluetooth isn't on?");
// Ends the discovery.
broadcastReceiverDelegator.onDeviceDiscoveryEnd();
}
}
/**
* Turns on the Bluetooth.
*/
public void turnOnBluetooth() {
Log.d(TAG, "Enabling Bluetooth.");
broadcastReceiverDelegator.onBluetoothTurningOn();
bluetooth.enable();
}
/**
* Performs the device pairing.
*
* @param device the device to pair with.
* @return true if the pairing was successful, false otherwise.
*/
public boolean pair(BluetoothDevice device) {
// Stops the discovery and then creates the pairing.
if (bluetooth.isDiscovering()) {
Log.d(TAG, "Bluetooth cancelling discovery.");
bluetooth.cancelDiscovery();
}
Log.d(TAG, "Bluetooth bonding with device: " + deviceToString(device));
boolean outcome = device.createBond();
Log.d(TAG, "Bounding outcome : " + outcome);
// If the outcome is true, we are bounding with this device.
if (outcome == true) {
this.boundingDevice = device;
}
return outcome;
}
/**
* Checks if a device is already paired.
*
* @param device the device to check.
* @return true if it is already paired, false otherwise.
*/
public boolean isAlreadyPaired(BluetoothDevice device) {
return bluetooth.getBondedDevices().contains(device);
}
/**
* Converts a BluetoothDevice to its String representation.
*
* @param device the device to convert to String.
* @return a String representation of the device.
*/
public static String deviceToString(BluetoothDevice device) {
return "[Address: " + device.getAddress() + ", Name: " + device.getName() + "]";
}
/**
* {@inheritDoc}
*/
@Override
public void close() {
this.broadcastReceiverDelegator.close();
}
/**
* Checks if a deviceDiscovery is currently running.
*
* @return true if a deviceDiscovery is currently running, false otherwise.
*/
public boolean isDiscovering() {
return bluetooth.isDiscovering();
}
/**
* Cancels a device discovery.
*/
public void cancelDiscovery() {
if(bluetooth != null) {
bluetooth.cancelDiscovery();
broadcastReceiverDelegator.onDeviceDiscoveryEnd();
}
}
/**
* Turns on the Bluetooth and executes a device discovery when the Bluetooth has turned on.
*/
public void turnOnBluetoothAndScheduleDiscovery() {
this.bluetoothDiscoveryScheduled = true;
turnOnBluetooth();
}
/**
* Called when the Bluetooth status changed.
*/
public void onBluetoothStatusChanged() {
// Does anything only if a device discovery has been scheduled.
if (bluetoothDiscoveryScheduled) {
int bluetoothState = bluetooth.getState();
switch (bluetoothState) {
case BluetoothAdapter.STATE_ON:
// Bluetooth is ON.
Log.d(TAG, "Bluetooth succesfully enabled, starting discovery");
startDiscovery();
// Resets the flag since this discovery has been performed.
bluetoothDiscoveryScheduled = false;
break;
case BluetoothAdapter.STATE_OFF:
// Bluetooth is OFF.
Log.d(TAG, "Error while turning Bluetooth on.");
Toast.makeText(context, "Error while turning Bluetooth on.", Toast.LENGTH_SHORT);
// Resets the flag since this discovery has been performed.
bluetoothDiscoveryScheduled = false;
break;
default:
// Bluetooth is turning ON or OFF. Ignore.
break;
}
}
}
/**
* Returns the status of the current pairing and cleans up the state if the pairing is done.
*
* @return the current pairing status.
* @see BluetoothDevice#getBondState()
*/
public int getPairingDeviceStatus() {
if (this.boundingDevice == null) {
throw new IllegalStateException("No device currently bounding");
}
int bondState = this.boundingDevice.getBondState();
// If the new state is not BOND_BONDING, the pairing is finished, cleans up the state.
if (bondState != BluetoothDevice.BOND_BONDING) {
this.boundingDevice = null;
}
return bondState;
}
/**
* Gets the name of the currently pairing device.
*
* @return the name of the currently pairing device.
*/
public String getPairingDeviceName() {
return getDeviceName(this.boundingDevice);
}
/**
* Gets the name of a device. If the device name is not available, returns the device address.
*
* @param device the device whose name to return.
* @return the name of the device or its address if the name is not available.
*/
public static String getDeviceName(BluetoothDevice device) {
String deviceName = device.getName();
if (deviceName == null) {
deviceName = device.getAddress();
}
return deviceName;
}
/**
* Returns if there's a pairing currently being done through this app.
*
* @return true if a pairing is in progress through this app, false otherwise.
*/
public boolean isPairingInProgress() {
return this.boundingDevice != null;
}
/**
* Gets the currently bounding device.
*
* @return the {@link #boundingDevice}.
*/
public BluetoothDevice getBoundingDevice() {
return boundingDevice;
}
}
BroadcastreceiverDeglator类:
public class BroadcastReceiverDelegator extends BroadcastReceiver implements Closeable {
/**
* Callback for Bluetooth events.
*/
private final BluetoothDiscoveryDeviceListener listener;
/**
* Tag string used for logging.
*/
private final String TAG = "BroadcastReceiver";
/**
* The context of this object.
*/
private final Context context;
/**
* Instantiates a new BroadcastReceiverDelegator.
*
* @param context the context of this object.
* @param listener a callback for handling Bluetooth events.
* @param bluetooth a controller for the Bluetooth.
*/
public BroadcastReceiverDelegator(Context context, BluetoothDiscoveryDeviceListener listener, BluetoothController bluetooth) {
this.listener = listener;
this.context = context;
this.listener.setBluetoothController(bluetooth);
// Register for broadcasts when a device is discovered.
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
context.registerReceiver(this, filter);
}
/**
* {@inheritDoc}
*/
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, "Incoming intent : " + action);
switch (action) {
case BluetoothDevice.ACTION_FOUND :
// Discovery has found a device. Get the BluetoothDevice
// object and its info from the Intent.
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d(TAG, "Device discovered! " + BluetoothController.deviceToString(device));
listener.onDeviceDiscovered(device);
break;
case BluetoothAdapter.ACTION_DISCOVERY_FINISHED :
// Discovery has ended.
Log.d(TAG, "Discovery ended.");
listener.onDeviceDiscoveryEnd();
break;
case BluetoothAdapter.ACTION_STATE_CHANGED :
// Discovery state changed.
Log.d(TAG, "Bluetooth state changed.");
listener.onBluetoothStatusChanged();
break;
case BluetoothDevice.ACTION_BOND_STATE_CHANGED :
// Pairing state has changed.
Log.d(TAG, "Bluetooth bonding state changed.");
listener.onDevicePairingEnded();
break;
default :
// Does nothing.
break;
}
}
/**
* Called when device discovery starts.
*/
public void onDeviceDiscoveryStarted() {
listener.onDeviceDiscoveryStarted();
}
/**
* Called when device discovery ends.
*/
public void onDeviceDiscoveryEnd() {
listener.onDeviceDiscoveryEnd();
}
/**
* Called when the Bluetooth has been enabled.
*/
public void onBluetoothTurningOn() {
listener.onBluetoothTurningOn();
}
/**
* {@inheritDoc}
*/
@Override
public void close() {
context.unregisterReceiver(this);
}
}
要取消配对的代码是什么,我应该在哪里使用它?