简体   繁体   English

从不调用BroadcastReceiver中的onReceive方法

[英]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. 每N秒更新一次这些信号强度。 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. 在调试时,我发现从不调用BroadcastReceiver的onReceive方法。 However, Bluetooth is enabled. 但是,启用了蓝牙。 What am I missing? 我想念什么?

PS: I want to confine all the BT activities into MainActivity alone. PS:我想将所有BT活动限制在MainActivity中。

Upon debug, I found that the onReceive method of BroadcastReceiver is never called. 在调试时,我发现从不调用BroadcastReceiver的onReceive方法。 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." BluetoothAdapter.ACTION_STATE_CHANGED广播被记录发送时“本地蓝牙适配器的状态已经改变了。” No changes means no broadcast. 没有变化就意味着没有广播。

Second, you only register bluetoothState as a BroadcastReceiver if the user clicks turnONBT . 其次,仅当用户单击turnONBT ,才将bluetoothState注册为BroadcastReceiver So, if there is a state change before that, you would not receive the broadcast. 因此,如果在此之前有状态更改,您将不会收到广播。

Third, you register bluetoothState for the wrong action. 第三,您为错误的操作注册了bluetoothState You are registering it for BluetoothDevice.ACTION_FOUND . 您正在为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 . 更改蓝牙状态的操作为BluetoothAdapter.ACTION_STATE_CHANGED Your discoveryResult would seem to be for discovery, and you never seem to register that receiver. 您的discoveryResult似乎是为了发现,您似乎从未注册过该接收者。

as this is the first ever code I'm doing either in Java or Android 因为这是我用Java或Android执行的第一个代码

I would not recommend anything involving Bluetooth be your first project in Java or Android. 建议将涉及蓝牙的任何内容作为Java或Android中的第一个项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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