简体   繁体   中英

The method onReceive in BroadcastReceiver is never called

My task is to turn the Bluetooth ON & OFF from my app and then search for any paired devices. If any paired device is found, connect to it; otherwise, discover the available devices in vicinity and list them along with their signal strengths; update these signals strengths every N seconds. When the user selects a particular device, connection should be established.

package surendra.example.com.mybluetooth;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.hardware.camera2.params.BlackLevelPattern;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import org.w3c.dom.Text;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class MainActivity extends AppCompatActivity {

    protected static final int DISCOVERY_REQUEST = 1;

    private BluetoothDevice device;

    //Variable for text display
    public TextView statusUpdate;
    public TextView BTHostDetails;
    public TextView BTDevicesAvailable;

    //List of buttons
    public Button turnONBT;
    public Button turnOFFBT;
    public Button scanBTDevices;
    public Button seeRSSI;
    public Button back;

    ArrayAdapter<String> btArrayAdapter;
    //BluetoothAdapter object that initializes the BT hardware on the device
    private BluetoothAdapter mBluetoothAdapter;

    //Broadcast the Bluetooth activities
    BroadcastReceiver bluetoothState = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String prevStateExtra  = BluetoothAdapter.EXTRA_PREVIOUS_STATE;
            String stateExtra = BluetoothAdapter.EXTRA_STATE;

            int state = intent.getIntExtra(stateExtra, -1);
            int previousState = intent.getIntExtra(prevStateExtra, -1);

            String toastText = "";

            switch (state) {
                case(BluetoothAdapter.STATE_TURNING_ON) : {
                    //Already turned ON
                    toastText = "Turning ON Bluetooth";
                    Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT).show();
                    break;
                }
                case(BluetoothAdapter.STATE_ON): {
                    //Turned ON
                    toastText = "Bluetooth turned ON";
                    Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT).show();
                    setupUI();
                    break;
                }
                case(BluetoothAdapter.STATE_TURNING_OFF) : {
                    //Already turned OFF
                    toastText = "Turning OFF Bluetooth";
                    Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT).show();
                    break;
                }
                case(BluetoothAdapter.STATE_OFF) : {
                    //Turned OFF
                    toastText = "Bluetooth turned OFF";
                    Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT).show();
                    setupUI();
                    break;
                }
            }
        }
    };

    //Represents a remote BT device
    private BluetoothDevice remoteDevice;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Get default BT adapter
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        setupUI();
    } //end onCreate method

    //Method to setup UI
    private void setupUI() {
        //Get references of each button and text view from the UI
        final TextView statusUpdate = (TextView) findViewById(R.id.statusUpdate);
        final TextView BTHostDetails = (TextView) findViewById(R.id.BTHostDetails);
        final Button turnONBT = (Button) findViewById(R.id.turnONBT);
        final Button turnOFFBT = (Button) findViewById(R.id.turnOFFBT);
        final Button scanBTDevices = (Button) findViewById(R.id.scanBTDevices);
        final Button seeRSSI = (Button) findViewById(R.id.seeRSSI);
        final Button back = (Button) findViewById(R.id.back);

        //Set visibilities of each button
        turnOFFBT.setVisibility(View.GONE);
        seeRSSI.setVisibility(View.GONE);
        back.setVisibility(View.GONE);
        scanBTDevices.setVisibility(View.GONE);
        BTHostDetails.setVisibility(View.GONE);

        //Check if the BT adapter is enabled
        if(mBluetoothAdapter.isEnabled()) {

            //If the BT adapter is enabled, get the name & address of the device
            String devName = mBluetoothAdapter.getName();
            String devAddr = mBluetoothAdapter.getAddress();

            String statusText = devName + " : " + devAddr;
            BTHostDetails.setText(statusText);

            //set the visibilities of the buttons based upon BT status
            BTHostDetails.setVisibility(View.VISIBLE);
            turnONBT.setVisibility(View.GONE);
            turnOFFBT.setVisibility(View.VISIBLE);
            seeRSSI.setVisibility(View.GONE);
            back.setVisibility(View.VISIBLE);
            scanBTDevices.setVisibility(View.VISIBLE);
        } else {
            String tmp = "Bluetooth turned OFF";
            statusUpdate.setText(tmp);
        }

        // We should keep on listening to the TURN ON BLUETOOTH button.
        // When the button turn on bluetooth is clicked, we should proceed to turn Bluetooth ON
        turnONBT.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                //This makes our device discoverable
                String beDiscoverable = BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE;

                //Intent is the pop up that we see when requesting for permission to use
                //certain interface on the device just like permission for location access etc.
                //Using the intent filter, we can filter the devices whose permissions are changed
                //when the user updates on the intent
                IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);

                //This registers a broadcast receiver
                registerReceiver(bluetoothState, filter);

                //If the intent changes from non-discoverable to discoverable, with the filter
                // DISCOVERY_REQUEST, then start the activity.
                startActivityForResult(new Intent(beDiscoverable), DISCOVERY_REQUEST);

                //Change the buttons views
                BTHostDetails.setVisibility(View.VISIBLE);
                turnOFFBT.setVisibility(View.VISIBLE);
                turnONBT.setVisibility(View.INVISIBLE);
                scanBTDevices.setVisibility(View.VISIBLE);
                seeRSSI.setVisibility(View.VISIBLE);
                back.setVisibility(View.INVISIBLE);

                String tmp = "Bluetooth turned ON";
                statusUpdate.setText(tmp);
            }
        });

        //scan devices
        scanBTDevices.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                //start discovery of new devices
                mBluetoothAdapter.startDiscovery();

                //see if this device is in a list of paired available devices
                Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
                //Toast.makeText(MainActivity.this, "Debug text 0", Toast.LENGTH_SHORT).show();
                if(pairedDevices.size() > 0) {
                    //This means that there are paired devices.
                    // Get the name & address of each device.
                    for(BluetoothDevice device : pairedDevices) {
                        String devName = device.getName();
                        String devAddr = device.getAddress();
                    }

                    List<String> s = new ArrayList<String>();
                    for(BluetoothDevice bt : pairedDevices) {
                        s.add(bt.getName());
                    }
                }
                BroadcastReceiver discoveryResult = new BroadcastReceiver() {

                    @Override
                    public void onReceive(Context context, Intent intent) {
                        String action = intent.getAction();

                        if(BluetoothDevice.ACTION_FOUND.equals(action)) {

                            //BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                            device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                            short rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, Short.MIN_VALUE);
                            String devName = device.getName();
                            String devAddr = device.getAddress();

                            String tmp = devName + " : " + devAddr + " - " + rssi;
                            statusUpdate.setText(tmp);
                        }
                    }
                };
            }
        });

        //Setup a listener for turning of Bluetooth i.e., for TURN OFF BLUETOOTH button
        turnOFFBT.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                //Change the buttons views
                BTHostDetails.setVisibility(View.INVISIBLE);
                turnOFFBT.setVisibility(View.INVISIBLE);
                turnONBT.setVisibility(View.VISIBLE);
                scanBTDevices.setVisibility(View.INVISIBLE);
                seeRSSI.setVisibility(View.INVISIBLE);
                back.setVisibility(View.INVISIBLE);

                String tmp = "Bluetooth turned OFF";
                statusUpdate.setText(tmp);

                mBluetoothAdapter.disable();
            }
        });

        //Back button activity
        back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                setupUI();
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode == DISCOVERY_REQUEST) {
            String tmp = "Discovery is in progress";
            Toast.makeText(MainActivity.this, tmp , Toast.LENGTH_SHORT).show();
            setupUI();
        }
    }
}

Upon debug, I found that the onReceive method of BroadcastReceiver is never called. However, Bluetooth is enabled. What am I missing?

PS: I want to confine all the BT activities into MainActivity alone.

Upon debug, I found that the onReceive method of BroadcastReceiver is never called. However, Bluetooth is enabled.

First, if Bluetooth is enabled, and nothing is changing the state of Bluetooth, I would not expect to receive any broadcast. The BluetoothAdapter.ACTION_STATE_CHANGED broadcast is documented to be sent when "The state of the local Bluetooth adapter has been changed." No changes means no broadcast.

Second, you only register bluetoothState as a BroadcastReceiver if the user clicks turnONBT . So, if there is a state change before that, you would not receive the broadcast.

Third, you register bluetoothState for the wrong action. You are registering it for BluetoothDevice.ACTION_FOUND . That action is for Bluetooth discovery, as is covered in the documentation . The action for changes in the Bluetooth state is BluetoothAdapter.ACTION_STATE_CHANGED . Your discoveryResult would seem to be for discovery, and you never seem to register that receiver.

as this is the first ever code I'm doing either in Java or Android

I would not recommend anything involving Bluetooth be your first project in Java or Android.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM