Android通信——蓝牙连接

一 传统蓝牙

Demo地址:Github 你省金币的选择~

基础功能

1.首先要在 manifests配置好蓝牙权限。

由于蓝牙权限非危险权限,所以不需要再动态注册了。

    <!-- 声明蓝牙权限 -->
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <!-- 允许程序发现和配对蓝牙设备 -->
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <!-- true=只能在支持BLE的Android设备上安装运行 false=无限制 -->
    <uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />

2.获取蓝牙适配器

BluetoothAdapter 用于基础的蓝牙操作,比如初始化搜索设备,对已配对设备进行检索等功能。

调用静态方法getDefaultAdapter()获取蓝牙适配器bluetoothadapter,如果返回为空,则表明此设备不支持蓝牙。

        BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        //1.检测蓝牙支持
        if (mBluetoothAdapter == null) {
            // Device does not support Bluetooth
            Toast.makeText(this, "设备不支持蓝牙", Toast.LENGTH_SHORT).show();
            return;
        }

3.蓝牙状态

isEnable()查看蓝牙是否打开

        if (!mBluetoothAdapter.isEnabled()) {//若果没有打开,则开启蓝牙
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, 1);
        }
  /**
     * 关闭蓝牙
     */
    private void closeBlueTooth() {
        if (mBluetoothAdapter.isEnabled()) {
            mBluetoothAdapter.disable();
        }
    }

4.获取已经配对设备

BluetoothAdapter的getBondedDevices()方法可以获取已经预先配对好的蓝牙设备集合。

获取的device的name和adress信息放入一个List并通过ArrayAdapter展示在ListView上。

        Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
        // If there are paired devices
        if (pairedDevices.size() > 0) {
            // Loop through paired devices
            for (BluetoothDevice device : pairedDevices) {
                pairString=device.getName() + "---" + device.getAddress();
                list_pair_device.add(pairString);
            }
            lv_show_pair.setAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,list_pair_device));
        }

5.激活设备蓝牙可见

如果想让本地设备对其他设备蓝牙可见,调用startActivityForResult(Intent, int),传入ACTION_REQUEST_DISCOVERABLE
这会请求激活系统设置。默认激活120秒,时间可设,但是最长时间是300秒。0表示设备永远可见。在0~300外的数字会被设置为120秒。

        //设置蓝牙可见Intent
        Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
        //设置蓝牙可见性的时间,方法本身规定最多可见300秒
        discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
        startActivity(discoverableIntent);

6.发现设备

调用BluetoothAdapter的startDiscovery()方法搜索设备。这个异步线程返回值=是否启动成功的boolean值。同时注意,不要在搜索过程中再次开启搜索。不要在与设备连接时启动搜索。搜索设备会减小连接的带宽。

                    if (mBluetoothAdapter.isDiscovering()) { //如果当前在搜索,就先取消搜索
                        mBluetoothAdapter.cancelDiscovery();
                    }
                    mBluetoothAdapter.startDiscovery();//开启搜索

请求Discovery后,系统开始搜索蓝牙设备,在这个过程中,系统会发送以下三个广播:

ACTION_DISCOVERY_START:开始搜索

ACTION_DISCOVERY_FINISHED:搜索结束

ACTION_FOUND:找到设备,这个Intent中包含两个extra fields:EXTRA_DEVICE和EXTRA_CLASS,分别包含BluetooDevice和BluetoothClass。

我们通过自己配置广播接收器来实现Android蓝牙的搜索。

    private final BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Log.i(TAG, "onReceive: action=" + action);
            if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_STARTED)) {
                Log.i(TAG, "onReceive:  扫描开始");

            } else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
                Log.i(TAG, "onReceive:  扫描完成");

            } else if (action.equals(BluetoothDevice.ACTION_FOUND)) {
                Log.i(TAG, "onReceive:  发现周围设备广播");
                BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                String name = bluetoothDevice.getName();
                String address = bluetoothDevice.getAddress();
                Log.i(TAG, "onReceive:  name=" + name + " address=" + address);

                bluetoothDevices.add(name + ":" + address);
                arrayAdapter_serach.notifyDataSetChanged();
            }
        }
    };

同时也要注册广播来监听蓝牙搜索状态。

        IntentFilter filters = new IntentFilter();
        filters.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        filters.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        filters.addAction(BluetoothDevice.ACTION_FOUND);
        registerReceiver(receiver, filters);

蓝牙的基础功能大概也就这么多了,没有什么难点。

蓝牙通信

蓝牙的使用目的就在于设备间数据通信,把传统蓝牙的通信思路以及代码整理下。

思路很清晰,我们需要一个蓝牙服务器与蓝牙客户端来接收与发送消息。

1.客户端

如上所示,首先进行搜索设备。然后连接设备,通过BlueToothDevice的createRfcommSocketToServiceRecord()方法获得一个BluetoothSocket对象。注意在设备在进行设备的时候,需要关闭蓝牙搜索。

BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
BluetoothSocketsocket =serverDevice.createRfcommSocketToServiceRecord(BluetoothTools.PRIVATE_UUID);
socket.connect();

如果这个过程不报错,然后通过这个socke对象就能会的输入输出流,从而进行读写操作。

this.outStream = new ObjectOutputStream(socket.getOutputStream());
this.inStream = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));

2.服务端

同理,首先通过BluetoothAdapter的listenUsingRfcommWithServiceRecord方法创建一个BluetoothServiceSocket,其中第一个参数随便洗个字符串,第二个参数为UUID,需要保证服务和客户端UUID一致。然后通过其accept方法
获得一个BluetoothSocket,通过这个socket获取输入输出流进行数据通信。

public static final UUID PRIVATE_UUID = UUID.fromString("0f3561b9-bda5-4672-84ff-ab1f98e349b6");

serverSocket = adapter.listenUsingRfcommWithServiceRecord("Server", BluetoothTools.PRIVATE_UUID);
socket = serverSocket.accept();

基本过程如上所示。我找了个demo做了参考,修改了一下,可以直接使用。关于传统蓝牙的数据通信的Demo直接去看代码。

猜你喜欢

转载自blog.csdn.net/ma598214297/article/details/80727159