1. 权限配置

在使用蓝牙技术之前,首先需要在AndroidManifest.xml中配置蓝牙的使用权限:

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

BLUETOOTH权限用于检测蓝牙是否开启、请求连接、接受连接、数据交换等相关权限,而BLUETOOTH_ADMIN用来搜索蓝牙设备以及相关蓝牙设置操作权限,目前大多数情况下都需要配置这两种权限。

1.1 检测设备是否支持蓝牙

配置好使用权限之后,那么接下来就可以在代码中使用设备蓝牙进行通信了,为了更好的用户体验我们会使用如下代码来检测设备是否支持蓝牙技术(有可能设备本身压根儿就没蓝牙)

BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null){
    // 设备不支持,没戏!
}

我们通过调用BluetoothAdapter的静态方法getDefaultAdater()用来获取当前设备的蓝牙适配器。如果getDefaultAdapter()返回null那说明设备蓝牙蓝牙存在问题,就不能再往下玩了,就此打住。

1.2 检测蓝牙设备是否可用

当前设备蓝牙有可能处于关闭状态,因此在使用蓝牙技术前,首先还需要检测蓝牙是否开启,如果没有开启那么应该提示用户开启蓝牙设备,可以调用BluetoothAdapterisEnabled()来判断:

// REQUEST_ENABLE_BLUETOOTH 是本地一个ActivityResult整型变量
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter != null){
    // 设备不支持,没戏!
    if (!bluetoothAdapter.isEnabled()){
        // 提示用户,去设置蓝牙
        Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBtIntent, REQUEST_ENABLE_BLUETOOTH);
    }
}

Android官方建议使用发送一个提示用户设置蓝牙的Activity而不是直接强制用户绑定蓝牙,这样的用户体验更好,当用户文成功开启了蓝牙,你的Activity将收到RESULT_OK作为resultCode。如果蓝牙不能成功开启(例如用户选择“取消”),则resultCodeRESULT_CANCELED

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_ENABLE_BLUETOOTH){
        if (resultCode == Activity.RESULT_CANCELED){
            // 用户取消
        }
    }
}

1.3 蓝牙状态变化监听

当蓝牙状态发生变化时,系统会以广播形式向App发送通知,比如蓝牙状态变化,正在扫描设备,扫描结束等,我们可以注册一个广播监听来获取当前蓝牙的变化:

注册监听可以静态写入AndroidManifest.xml文件中,也可以使用代码方式注册一个监听,下面使用代码方式监听蓝牙相关状态:

public class BluetoothReceiver extends BroadcastReceiver {

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

        switch (action){
            case BluetoothAdapter.ACTION_SCAN_MODE_CHANGED:
                Log.e("bluetooth","ACTION_SCAN_MODE_CHANGED");
                break;
            case BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED:
                Log.e("bluetooth","ACTION_CONNECTION_STATE_CHANGED");
                break;
            case BluetoothAdapter.ACTION_DISCOVERY_STARTED:
                Log.e("bluetooth","ACTION_DISCOVERY_STARTED");
                break;
            case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
                Log.e("bluetooth","ACTION_DISCOVERY_FINISHED");
                break;
            case BluetoothAdapter.ACTION_STATE_CHANGED:
                Log.e("bluetooth","ACTION_STATE_CHANGED");
                // 额外的状态, STATE_OFF, STATE_TURNING_ON, STATE_ON, STATE_TURNING_OFF
                int newExtra = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,0);

                // 之前的额外数据
                int oldExtra = intent.getIntExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE,0);

                Log.e("bluetooth","ACTION_STATE_CHANGED--"+ String.valueOf(oldExtra));
                Log.e("bluetooth","ACTION_STATE_CHANGED--"+ String.valueOf(newExtra));

                break;
        }
    }
}

// 在需要使用的地方,例如Activity注册一个广播的监听
BluetoothReceiver receiver = new BluetoothReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
filter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
registerReceiver(receiver,filter);

注意:动态注册的广播监听在使用结束后,需要使用unregisterReceiver(BluetoothReceiver)移除监听。需要注意的是在ACTION_STATE_CHANGED状态里,还会传递额外的蓝牙信息字段EXTRA_STATEEXTRA_PREVIOUS_STATE代表改变后的状态和之前的蓝牙状态的具体信息,例如蓝牙正在打开、已打开、正在关闭等,具体可以参考: http://developer.android.com/intl/zh-cn/reference/android/bluetooth/BluetoothAdapter.html#STATE_OFF