在为配对/未配对的蓝牙设备配对和取消配对时没有收到广播接收器的回调

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;
}