是否检测到BluetoothAdapter的状态更改?


74

我有一个带有按钮的应用程序,用于打开和关闭BT。我的代码如下:

public void buttonFlip(View view) {
    flipBT();
    buttonText(view);
}

public void buttonText(View view) {  
    Button buttonText = (Button) findViewById(R.id.button1);
    if (mBluetoothAdapter.isEnabled() || (mBluetoothAdapter.a)) {
        buttonText.setText(R.string.bluetooth_on);  
    } else {
        buttonText.setText(R.string.bluetooth_off);
    }
}

private void flipBT() {
    if (mBluetoothAdapter.isEnabled()) {
        mBluetoothAdapter.disable();    
    } else {
        mBluetoothAdapter.enable();
    }
}

我叫按钮Flip,它会翻转BT状态,然后叫ButtonText,它应该更新UI。但是,我遇到的问题是,打开BT需要花费几秒钟的时间-在这几秒钟中,BT状态未启用,即使我的按钮在2秒钟内打开,我的按钮也会关闭蓝牙。

STATE_CONNECTING在BluetoothAdapter android文档中找到了该常量,但是...我只是不知道如何使用它,无论是新手还是所有人。

因此,我有两个问题:

  1. 有没有一种方法可以将UI元素(例如按钮或图像)动态地绑定到BT状态,以便当BT状态更改时,按钮也将更改?
  2. 否则,我想按下按钮并获得正确的状态(我希望它说BT处于打开状态,即使它只是在连接,因为它会在2秒钟内打开)。我该怎么做呢?

BT开始开启后,您能否使用布尔值并将其设置为true,然后检查布尔值状态以更改按钮?
比尔·加里

看看下面的AOSP代码,以了解他们如何跟踪蓝牙的开/关变化:androidxref.com/5.1.0_r1/xref/frameworks/base/services/core/…–
IgorGanapolsky

Answers:


202

您将需要注册一个BroadcastReceiver来监听状态的任何变化BluetoothAdapter

作为您的私有实例变量Activity(或在单独的类文件中,...首选):

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();

        if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
            final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
                                                 BluetoothAdapter.ERROR);
            switch (state) {
            case BluetoothAdapter.STATE_OFF:
                setButtonText("Bluetooth off");
                break;
            case BluetoothAdapter.STATE_TURNING_OFF:
                setButtonText("Turning Bluetooth off...");
                break;
            case BluetoothAdapter.STATE_ON:
                setButtonText("Bluetooth on");
                break;
            case BluetoothAdapter.STATE_TURNING_ON:
                setButtonText("Turning Bluetooth on...");
                break;
            }
        }
    }
};

请注意,这是假设您Activity实现的方法setButtonText(String text)将相应地更改Button的文本。

然后在您的中Activity,注册和注销BroadcastReceiver以下内容,

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    /* ... */

    // Register for broadcasts on BluetoothAdapter state change
    IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
    registerReceiver(mReceiver, filter);
}

@Override
public void onDestroy() {
    super.onDestroy();

    /* ... */

    // Unregister broadcast listeners
    unregisterReceiver(mReceiver);
}

亚历克斯,这几乎可行。一些东西。首先,我认为您打算注册BluetoothAdapter而不是BluetoothDevice,因为BluetoothDevice是在您与设备配对时,并且它仅具有BluetoothDevice.ACTION_BOND_STATE_CHANGED,在此将不适用。我还加了一个; 在broadcastReceiver代码之后(我只是为将来会有相同问题并阅读此内容的人们编写此代码),但是,我得到了“ Java.lang.RuntimeException:无法实例化活动ComponentInfo”,这通常意味着我的活动未在清单中注册-我需要在那里注册接收者吗?
Raingod 2012年

哈!我是个白痴:)我想出了我的问题。所以,是的,除了我在上面提到的代码之外,这很不错:)感谢Alex!
Raingod 2012年

没问题!对错别字感到抱歉...当我输入时,我知道一定有几个:)。
亚历克斯·洛克伍德

我个人认为Alex的答案是迄今为止最好的答案。请记住,您也可以在AndroidManifest.xml中注册广播接收器。请小心放入广播接收器中的代码,因为它有时会在创建应用程序实例之前执行,至少以我个人的经验而言。
丹尼尔·伊格尔

11
您应该在onStart和onStop中注册和注销。不保证可以调用onDestroy!
MobileMon

-3
public void discoverBluetoothDevices(View view)
    {
        if (bluetoothAdapter!=null)

            bluetoothAdapter.startDiscovery();
            Toast.makeText(this,"Start Discovery"+bluetoothAdapter.startDiscovery(),Toast.LENGTH_SHORT).show();
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.