Android广播接收器蓝牙事件捕捉

时间:2015-05-13 18:16:04

标签: android bluetooth android-broadcast android-bluetooth

我正试图通过广播接收器捕捉蓝牙状态变化。

我的清单:

<uses-permission android:name="android.permission.BLUETOOTH" />
<application>
     <activity
        android:name=".MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <receiver android:name=".BluetoothBroadcastReceiver"
              android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.bluetooth.adapter.action.STATE_CHANGED" />
            <action android:name="android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED" />
            <action android:name="android.bluetooth.device.action.ACL_CONNECTED" />
            <action android:name="android.bluetooth.device.action.ACL_DISCONNECTED" />
        </intent-filter>
    </receiver>
</application>

接收方onReceive方法:

public void onReceive(Context context, Intent intent) {

    String action = intent.getAction();
    Log.d("BroadcastActions", "Action "+action+"received");
    int state;
    BluetoothDevice bluetoothDevice;

    switch(action)
    {
        case BluetoothAdapter.ACTION_STATE_CHANGED:
            state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
            if (state == BluetoothAdapter.STATE_OFF)
            {
                Toast.makeText(context, "Bluetooth is off", Toast.LENGTH_SHORT).show();
                Log.d("BroadcastActions", "Bluetooth is off");
            }
            else if (state == BluetoothAdapter.STATE_TURNING_OFF)
            {
                Toast.makeText(context, "Bluetooth is turning off", Toast.LENGTH_SHORT).show();
                Log.d("BroadcastActions", "Bluetooth is turning off");
            }
            else if(state == BluetoothAdapter.STATE_ON)
            {
                Log.d("BroadcastActions", "Bluetooth is on");
            }
            break;

        case BluetoothDevice.ACTION_ACL_CONNECTED:
            bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            Toast.makeText(context, "Connected to "+bluetoothDevice.getName(),
                    Toast.LENGTH_SHORT).show();
            Log.d("BroadcastActions", "Connected to "+bluetoothDevice.getName());
            break;

        case BluetoothDevice.ACTION_ACL_DISCONNECTED:
            bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            Toast.makeText(context, "Disconnected from "+bluetoothDevice.getName(),
                    Toast.LENGTH_SHORT).show();
            break;
    }
}

我启动应用,然后按主页按钮将其最小化。转到设置并打开蓝牙但没有任何反应。虽然我期待吐司和logcat消息。这有什么不对?

2 个答案:

答案 0 :(得分:43)

为了捕捉蓝牙状态更改(STATE_OFFSTATE_TURNING_ONSTATE_ONSTATE_TURNING_OFF),请在您的活动中执行以下操作:

首先,为您的AndroidManifest文件添加蓝牙权限:

<uses-permission android:name="android.permission.BLUETOOTH" />

在您的活动或服务中创建一个BroadcastReceiver:

    private final BroadcastReceiver mBroadcastReceiver1 = 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:
                    ..
                    break;
                case BluetoothAdapter.STATE_TURNING_OFF:
                    ..
                    break;
                case BluetoothAdapter.STATE_ON:
                    ..
                    break;
                case BluetoothAdapter.STATE_TURNING_ON:
                    ..
                    break;
            }

        }
    }
};

创建一个IntentFilter并使用您的onCreate()方法将BroadcastReceiver注册到Activity / Service:

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

    IntentFilter filter1 = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
    registerReceiver(mBroadcastReceiver1, filter1);

    ...
}

onDestroy()方法中取消注册BroadcastReceiver:

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

    unregisterReceiver(mBroadcastReceiver1);
}

为了捕捉设备(SCAN_MODE_NONESCAN_MODE_CONNECTABLESCAN_MODE_CONNECTABLE_DISCOVERABLE)的可发现性变化,创建另一个BroadcastReceiver并注册/取消注册到您的活动,如上所述。只有那些BroadcastReceiver之间的区别是第一个使用BluetoothAdapter.EXTRA_STATE而另一个使用BluetoothAdapter.EXTRA_SCAN_MODE。以下是BroadcastReceiver捕获可发现性更改的示例代码:

创建过滤器并在onCreate()方法中注册:

IntentFilter filter2 = new IntentFilter();
filter2.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter2.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
filter2.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
registerReceiver(mBroadcastReceiver2, filter2);

在Activity / Service中创建BroadcastReciver以捕获可发现性更改:

    private final BroadcastReceiver mBroadcastReceiver2 = new BroadcastReceiver() {

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

        if(action.equals(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED)) {

            int mode = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE, BluetoothAdapter.ERROR);

            switch(mode){
                case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
                    ..
                    break;
                case BluetoothAdapter.SCAN_MODE_CONNECTABLE:
                    ..
                    break;
                case BluetoothAdapter.SCAN_MODE_NONE:
                    ..
                    break;
            }
        }
    }
};

最后在onDestroy()中取消注册:

unregisterReceiver(mBroadcastReceiver2);

请注意,您不需要在AndroidManifest文件中添加任何<intent-filter><receiver>,除非您需要添加蓝牙权限。

如果你想抓住(ACTION_ACL_CONNECTEDACTION_ACL_DISCONNECTEDACTION_ACL_DISCONNECT_REQUESTED),现在需要在AndroidManifest文件中添加<intent-filter>

<intent-filter>
    <action android:name="android.bluetooth.device.action.ACL_CONNECTED" />
    <action android:name="android.bluetooth.device.action.ACL_DISCONNECTED" />
</intent-filter>

创建过滤器并在onCreate()方法中注册:

IntentFilter filter3 = new IntentFilter();
filter3.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
filter3.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
registerReceiver(mBroadcastReceiver3, filter3);

然后在您的活动/服务中创建BroadcastReceiver:

    private final BroadcastReceiver mBroadcastReceiver3 = new BroadcastReceiver() {

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

        switch (action){
            case BluetoothDevice.ACTION_ACL_CONNECTED:
                ..
                break;
            case BluetoothDevice.ACTION_ACL_DISCONNECTED:
                ..
                break;
        }
    }
};

最后,取消注册:

unregisterReceiver(mBroadcastReceiver3);

如果您想了解有关状态常量的更多信息,请参阅文档:

  

public static final String EXTRA_STATE

     

用作请求的ACTION_STATE_CHANGED意图中的int额外字段   当前的电力状态。可能的值有:STATE_OFF,   STATE_TURNING_ON,STATE_ON,STATE_TURNING_OFF

     

public static final String EXTRA_SCAN_MODE

     

用作ACTION_SCAN_MODE_CHANGED意图中的int额外字段   请求当前的扫描模式。可能的值有:SCAN_MODE_NONE,   SCAN_MODE_CONNECTABLE,SCAN_MODE_CONNECTABLE_DISCOVERABLE

答案 1 :(得分:-1)

您的主要问题;)您不能使用“switch”进行字符串比较。

至少在VERSION_INT 18(含)之前。版本19以Java 7开头。