在为配对/未配对的蓝牙设备配对和取消配对时没有收到广播接收器的回调
Not getting callback to broadcast receiver while pairing and unpairing bluetooth device for paired/ unpaired
在下面的代码中,我正在发现所有可用的 BLE 设备并尝试根据要求配对和取消配对设备。但是我没有在注册的广播接收器中收到回调。
public class DeviceConfigurationActivity extends AppCompatActivity {
Context context;
Toolbar toolbar;
RecyclerView recyclerView;
DeviceListAdapter mAdapter;
ArrayList<BluetoothDevice> mList;
RelativeLayout rlBack;
//BLUETOOTH
BluetoothAdapter bluetoothAdapter;
Set<BluetoothDevice> pairedDevices;
String deviceName, deviceHardwareAddress;
ProgressBar progressBar;
private Intent bluetoothSerialServiceIntent;
boolean mBound = false;
private BluetoothSerialService btService;
String selectedWorkType = "";
private int btDevicePosition;
private BTDeviceEntity connectedDevice;
private BluetoothDevice alreadyConnectedBTDevice;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_device_configuration);
init();
}
public void init(){
context = this;
toolbar = findViewById(R.id.toolbar);
recyclerView = findViewById(R.id.recycler_view);
rlBack = findViewById(R.id.rl_back);
progressBar = findViewById(R.id.progress_bar);
mList = new ArrayList<>();
//Method calling
setListeners();
setUpRecyclerView();
setUpBluetooth();
}
private void setListeners() {
rlBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
}
/**
* BLUETOOTH SETUP
*/
private void setUpBluetooth() {
progressBar.setVisibility(View.VISIBLE);
//GET BLUETOOTH DEFAULT ADAPTER AND START DISCOVERY
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothAdapter.startDiscovery();
if (bluetoothAdapter == null){
Toast.makeText(context, "Device doesn't support Bluetooth", Toast.LENGTH_SHORT).show();
}
//CHECK IF BLUETOOTH IS ENABLED
checkIfEnabled();
//REGISTER FOR A BROADCASTS WHEN A DEVICE IS DISCOVERED
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(receiver, filter);
//REGISTER FOR A BROADCASTS FOR A DEVICE STATE CHANGED
IntentFilter intent = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
registerReceiver(mPairReceiver, intent);
}
private void setUpRecyclerView() {
mAdapter = new DeviceListAdapter(context, mList, new DeviceListAdapter.DeviceListAdapterInterface() {
@Override
public void onConnect(BluetoothDevice device, int position) {
onConnection(device, position);
}
});
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.setAdapter(mAdapter);
}
//CHECK IF ENABLED
private void checkIfEnabled() {
if (!bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 0);
//Toast.makeText(getApplicationContext(), "Turned on", Toast.LENGTH_LONG).show();
}else {
//Toast.makeText(getApplicationContext(), "Already on", Toast.LENGTH_LONG).show();
}
}
private void onConnection(BluetoothDevice device, int position) {
//connectedDevice = device;
btDevicePosition = position;
if (device.getBondState() != Constants.STATE_DISCONNECTED) {
new AlertDialog.Builder(context)
.setTitle("Connect to device")
.setMessage("Are you sure you want to connect to " + device.getName() + " ?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
pairDevice(device);
dialog.dismiss();
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).show();
} else {
new AlertDialog.Builder(context)
.setTitle("Disconnect from device")
.setMessage("Are you sure you want to disconnect from " + device.getName() + " ?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
unpairDevice(device);
dialog.dismiss();
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).show();
}
}
private void pairDevice(BluetoothDevice device){
Method method;
try {
method = device.getClass().getMethod("createBond", (Class[])null);
method.invoke(device, (Object[]) null);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
mList.remove(btDevicePosition);
mList.add(device);
//mAdapter.updateAdapter(mList);
//mAdapter.updateDeviceState(btDevicePosition, device.getBondState());
}
private void unpairDevice(BluetoothDevice device){
Method method;
try {
method = device.getClass().getMethod("removeBond", (Class[])null);
method.invoke(device, (Object[])null);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
mList.remove(btDevicePosition);
mList.add(device);
//mAdapter.updateAdapter(mList);
//mAdapter.updateDeviceState(btDevicePosition, device.getBondState());
}
// Create a BroadcastReceiver for ACTION_FOUND.
private final BroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
mList.add(device);
//Set adapter
Log.i("BT", device.getName() + "\n" + device.getAddress());
progressBar.setVisibility(View.GONE);
mAdapter.updateAdapter(mList);
}
}
};
private final BroadcastReceiver mPairReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
final int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
final int prevState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, BluetoothDevice.ERROR);
if (state == BluetoothDevice.BOND_BONDED && prevState == BluetoothDevice.BOND_BONDING) {
Toast.makeText(context, "Paired", Toast.LENGTH_SHORT).show();
// mAdapter.updateAdapter(mList);
} else if (state == BluetoothDevice.BOND_NONE && prevState == BluetoothDevice.BOND_BONDED) {
Toast.makeText(context, "Unpaired", Toast.LENGTH_SHORT).show();
// mAdapter.updateAdapter(mList);
}
}
}
};
/**
* HANDLER METHODS
*/
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
unregisterReceiver(mPairReceiver);
}
}
下面是我用于回收站视图的适配器 class。这里也面临更新连接或断开更新状态的问题。
public class DeviceListAdapter extends RecyclerView.Adapter<DeviceListAdapter.MyViewHolder> {
Context context;
ArrayList<BluetoothDevice> mList;
DeviceListAdapterInterface mListener;
public interface DeviceListAdapterInterface{
void onConnect(BluetoothDevice device, int position);
}
public void updateAdapter(ArrayList<BluetoothDevice> mList){
this.mList = mList;
notifyDataSetChanged();
}
public DeviceListAdapter(Context context, ArrayList<BluetoothDevice> mList,DeviceListAdapterInterface mListener) {
this.context = context;
this.mList = mList;
this.mListener = mListener;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int position) {
View view = LayoutInflater.from(context).inflate(R.layout.row_bt_device2, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, @SuppressLint("RecyclerView") int position) {
BluetoothDevice model = mList.get(position);
myViewHolder.txtDeviceName.setText(model.getName());
if (model.getBondState() != Constants.STATE_DISCONNECTED){
myViewHolder.txtConnectionStatus.setText("Connect");
}else {
myViewHolder.txtConnectionStatus.setText("Disconnect");
}
myViewHolder.txtConnectionStatus.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mListener.onConnect(model, position);
}
});
}
@Override
public int getItemCount() {
return mList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView txtDeviceName, txtConnectionStatus;
ImageView imgIcon;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
txtDeviceName = itemView.findViewById(R.id.txt_device_name);
txtConnectionStatus = itemView.findViewById(R.id.txt_connection_status);
imgIcon = itemView.findViewById(R.id.img_icon);
}
}
}
请提出解决方案。任何帮助将不胜感激。提前致谢。
在 startDiscovery() registerReciever 之前。
public BroadcastReceiver connectionCallbacks = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case BluetoothCommands.STATE_CONNECTING:
break;
case BluetoothCommands.STATE_CONNECTED:
break;
case BluetoothCommands.STATE_DISCONNECTED:
break;
case BluetoothDevice.ACTION_FOUND:
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//From here you can add devices to your list.
break;
case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
if (intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR) == BluetoothDevice.BOND_BONDED) {
}
break;
}
}
};
在pairDevice方法中调用
device.createBond();
注册这些操作。
public IntentFilter getConnectionIntentFilter() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothCommands.STATE_CONNECTING);
intentFilter.addAction(BluetoothCommands.STATE_CONNECTED);
intentFilter.addAction(BluetoothCommands.STATE_DISCONNECTED);
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
return intentFilter;
}
在下面的代码中,我正在发现所有可用的 BLE 设备并尝试根据要求配对和取消配对设备。但是我没有在注册的广播接收器中收到回调。
public class DeviceConfigurationActivity extends AppCompatActivity {
Context context;
Toolbar toolbar;
RecyclerView recyclerView;
DeviceListAdapter mAdapter;
ArrayList<BluetoothDevice> mList;
RelativeLayout rlBack;
//BLUETOOTH
BluetoothAdapter bluetoothAdapter;
Set<BluetoothDevice> pairedDevices;
String deviceName, deviceHardwareAddress;
ProgressBar progressBar;
private Intent bluetoothSerialServiceIntent;
boolean mBound = false;
private BluetoothSerialService btService;
String selectedWorkType = "";
private int btDevicePosition;
private BTDeviceEntity connectedDevice;
private BluetoothDevice alreadyConnectedBTDevice;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_device_configuration);
init();
}
public void init(){
context = this;
toolbar = findViewById(R.id.toolbar);
recyclerView = findViewById(R.id.recycler_view);
rlBack = findViewById(R.id.rl_back);
progressBar = findViewById(R.id.progress_bar);
mList = new ArrayList<>();
//Method calling
setListeners();
setUpRecyclerView();
setUpBluetooth();
}
private void setListeners() {
rlBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
}
/**
* BLUETOOTH SETUP
*/
private void setUpBluetooth() {
progressBar.setVisibility(View.VISIBLE);
//GET BLUETOOTH DEFAULT ADAPTER AND START DISCOVERY
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothAdapter.startDiscovery();
if (bluetoothAdapter == null){
Toast.makeText(context, "Device doesn't support Bluetooth", Toast.LENGTH_SHORT).show();
}
//CHECK IF BLUETOOTH IS ENABLED
checkIfEnabled();
//REGISTER FOR A BROADCASTS WHEN A DEVICE IS DISCOVERED
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(receiver, filter);
//REGISTER FOR A BROADCASTS FOR A DEVICE STATE CHANGED
IntentFilter intent = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
registerReceiver(mPairReceiver, intent);
}
private void setUpRecyclerView() {
mAdapter = new DeviceListAdapter(context, mList, new DeviceListAdapter.DeviceListAdapterInterface() {
@Override
public void onConnect(BluetoothDevice device, int position) {
onConnection(device, position);
}
});
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.setAdapter(mAdapter);
}
//CHECK IF ENABLED
private void checkIfEnabled() {
if (!bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 0);
//Toast.makeText(getApplicationContext(), "Turned on", Toast.LENGTH_LONG).show();
}else {
//Toast.makeText(getApplicationContext(), "Already on", Toast.LENGTH_LONG).show();
}
}
private void onConnection(BluetoothDevice device, int position) {
//connectedDevice = device;
btDevicePosition = position;
if (device.getBondState() != Constants.STATE_DISCONNECTED) {
new AlertDialog.Builder(context)
.setTitle("Connect to device")
.setMessage("Are you sure you want to connect to " + device.getName() + " ?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
pairDevice(device);
dialog.dismiss();
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).show();
} else {
new AlertDialog.Builder(context)
.setTitle("Disconnect from device")
.setMessage("Are you sure you want to disconnect from " + device.getName() + " ?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
unpairDevice(device);
dialog.dismiss();
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).show();
}
}
private void pairDevice(BluetoothDevice device){
Method method;
try {
method = device.getClass().getMethod("createBond", (Class[])null);
method.invoke(device, (Object[]) null);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
mList.remove(btDevicePosition);
mList.add(device);
//mAdapter.updateAdapter(mList);
//mAdapter.updateDeviceState(btDevicePosition, device.getBondState());
}
private void unpairDevice(BluetoothDevice device){
Method method;
try {
method = device.getClass().getMethod("removeBond", (Class[])null);
method.invoke(device, (Object[])null);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
mList.remove(btDevicePosition);
mList.add(device);
//mAdapter.updateAdapter(mList);
//mAdapter.updateDeviceState(btDevicePosition, device.getBondState());
}
// Create a BroadcastReceiver for ACTION_FOUND.
private final BroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
mList.add(device);
//Set adapter
Log.i("BT", device.getName() + "\n" + device.getAddress());
progressBar.setVisibility(View.GONE);
mAdapter.updateAdapter(mList);
}
}
};
private final BroadcastReceiver mPairReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
final int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
final int prevState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, BluetoothDevice.ERROR);
if (state == BluetoothDevice.BOND_BONDED && prevState == BluetoothDevice.BOND_BONDING) {
Toast.makeText(context, "Paired", Toast.LENGTH_SHORT).show();
// mAdapter.updateAdapter(mList);
} else if (state == BluetoothDevice.BOND_NONE && prevState == BluetoothDevice.BOND_BONDED) {
Toast.makeText(context, "Unpaired", Toast.LENGTH_SHORT).show();
// mAdapter.updateAdapter(mList);
}
}
}
};
/**
* HANDLER METHODS
*/
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
unregisterReceiver(mPairReceiver);
}
}
下面是我用于回收站视图的适配器 class。这里也面临更新连接或断开更新状态的问题。
public class DeviceListAdapter extends RecyclerView.Adapter<DeviceListAdapter.MyViewHolder> {
Context context;
ArrayList<BluetoothDevice> mList;
DeviceListAdapterInterface mListener;
public interface DeviceListAdapterInterface{
void onConnect(BluetoothDevice device, int position);
}
public void updateAdapter(ArrayList<BluetoothDevice> mList){
this.mList = mList;
notifyDataSetChanged();
}
public DeviceListAdapter(Context context, ArrayList<BluetoothDevice> mList,DeviceListAdapterInterface mListener) {
this.context = context;
this.mList = mList;
this.mListener = mListener;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int position) {
View view = LayoutInflater.from(context).inflate(R.layout.row_bt_device2, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, @SuppressLint("RecyclerView") int position) {
BluetoothDevice model = mList.get(position);
myViewHolder.txtDeviceName.setText(model.getName());
if (model.getBondState() != Constants.STATE_DISCONNECTED){
myViewHolder.txtConnectionStatus.setText("Connect");
}else {
myViewHolder.txtConnectionStatus.setText("Disconnect");
}
myViewHolder.txtConnectionStatus.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mListener.onConnect(model, position);
}
});
}
@Override
public int getItemCount() {
return mList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView txtDeviceName, txtConnectionStatus;
ImageView imgIcon;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
txtDeviceName = itemView.findViewById(R.id.txt_device_name);
txtConnectionStatus = itemView.findViewById(R.id.txt_connection_status);
imgIcon = itemView.findViewById(R.id.img_icon);
}
}
}
请提出解决方案。任何帮助将不胜感激。提前致谢。
在 startDiscovery() registerReciever 之前。
public BroadcastReceiver connectionCallbacks = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case BluetoothCommands.STATE_CONNECTING:
break;
case BluetoothCommands.STATE_CONNECTED:
break;
case BluetoothCommands.STATE_DISCONNECTED:
break;
case BluetoothDevice.ACTION_FOUND:
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//From here you can add devices to your list.
break;
case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
if (intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR) == BluetoothDevice.BOND_BONDED) {
}
break;
}
}
};
在pairDevice方法中调用
device.createBond();
注册这些操作。
public IntentFilter getConnectionIntentFilter() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothCommands.STATE_CONNECTING);
intentFilter.addAction(BluetoothCommands.STATE_CONNECTED);
intentFilter.addAction(BluetoothCommands.STATE_DISCONNECTED);
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
return intentFilter;
}