Android开发蓝牙篇之蓝牙设备开启、搜索周边蓝牙设备

2 篇文章 0 订阅
1 篇文章 0 订阅

首先是此部分涉及到的类

  • BluetoothAdapter 蓝牙适配器,即该类里面包含了蓝牙使用中常用到的一些API。
  • BroadcastReceiver 广播接收者,不难猜测,蓝牙设备开启或者关闭、搜索到周边设备就要来通知应用,那么Android系统就会以广播的方式来通知。
  • BluetoothDevice 蓝牙设备,即一个相当于蓝牙设备的类,实现了Parcelable接口,用于Android的IPC通信机制。里面实在广播时发送的蓝牙的相关信息:蓝牙名称,地址,类型和uuid等。

蓝牙设备开启

public void enableBlueTooth() throws Exception {
        this.BTadapter = BluetoothAdapter.getDefaultAdapter();
        if (BTadapter == null) {
            throw new Exception("设备上没有发现有蓝牙设备");
        }
        if (!BTadapter.isEnabled()) {
            BTadapter.enable();
        }
    }

BTadapter就是BluetoothAdapter的对象,如果获取到的蓝牙适配器对象时null,就说明该设备不支持蓝牙,然后判断蓝牙是否开启,BTadapter .isEnabled()如果没有开启就返回false,BTadapter.enable()用于开启蓝牙设备。


蓝牙设备搜索

@Override
    public void searchBlueTooth(Context context,
            SearchBlueToothListener mSearchListener) throws Exception {
        // TODO Auto-generated method stub
        Log.i("info", "准备开始搜索了");
        this.mSearchListener = mSearchListener;
        enableBlueTooth();
        if (BTadapter.isDiscovering()) {
            BTadapter.cancelDiscovery();
        }
        BTadapter.startDiscovery();

        IntentFilter iFilter = new IntentFilter(
                BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        context.registerReceiver(mSearchReceiver, iFilter);

        // 创建一个查找蓝牙设备的广播意图
        iFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        // 注册一个广播接收者,开启查找蓝牙设备意图后将结果以广播的形式返回
        context.registerReceiver(mSearchReceiver, iFilter);

        // 创建一个结束查找蓝牙设备结束的广播意图

        iFilter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        context.registerReceiver(mSearchReceiver, iFilter);

    }

首先,开启蓝牙设备,然后判断蓝牙设备是否正在搜索,如果正在搜索,就取消搜索,再开启重新搜索。
其次,蓝牙搜索会有开始搜索、搜索到设备、结束搜索三个阶段:
Android系统分别都会在这三个阶段给应用发送广播,应用注册相应的广播接收者,我这里注册了开启、发现、结束三个广播接收意向;在广播接收者中进行操作,而操作每一次使用大多不相同,所以我定义了一个接口,用户实现这个接口然后做自己的响应。

SearchBlueToothListener 接口:
public interface SearchBlueToothListener {
    public void startSearch();

    public void whileSearch(BluetoothDevice device);

    public void finishSearch(Map<String, List<BlueTooth>> blueToothMap);
}

而BlueTooth类知识自己定义的蓝牙类,用于存储蓝牙信息

public class BlueTooth {

    private String name;
    private String address;
    private int type;
    private ParcelUuid[] uuid;
    }

在广播接收者当中

private List<BlueTooth> connectedBlueTooths;
private List<BlueTooth> newBlueTooths;

private BroadcastReceiver mSearchReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context arg0, Intent arg1) {
            // TODO Auto-generated method stub
            String action = arg1.getAction();
            switch (action) {
            case BluetoothAdapter.ACTION_DISCOVERY_STARTED:
                connectedBlueTooths.clear();
                newBlueTooths.clear();
                mSearchListener.startSearch();
                break;
            case BluetoothDevice.ACTION_FOUND:
                BluetoothDevice device = arg1
                        .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                BlueTooth blueTooth = new BlueTooth();
                blueTooth.setName(device.getName());
                blueTooth.setAddress(device.getAddress());
                blueTooth.setType(device.getType());
                blueTooth.setUuid(device.getUuids());
                short rssi = arg1.getExtras().getShort(
                        BluetoothDevice.EXTRA_RSSI);
                Log.i("info", "蓝牙信号强度     " + rssi);
                if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
                    for (BlueTooth blueToothPul : connectedBlueTooths) {
                        if (blueToothPul.getAddress().equals(
                                blueTooth.getAddress()))
                            return;
                    }
                    connectedBlueTooths.add(blueTooth);
                } else {
                    for (BlueTooth blueToothPul : newBlueTooths) {
                        if (blueToothPul.getAddress().equals(
                                blueTooth.getAddress())) {
                            return;
                        }
                    }
                    newBlueTooths.add(blueTooth);
                }
                mSearchListener.whileSearch(device);
                break;
            case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
                Map<String, List<BlueTooth>> blueToothMap = new HashMap<String, List<BlueTooth>>();
                // if (connectedBlueTooths != null
                // && connectedBlueTooths.size() > 0)
                blueToothMap.put(CONNECTED_BLUETOOTHS, connectedBlueTooths);
                // else
                // blueToothMap.put(CONNECTED_BLUETOOTHS, null);
                // if (newBlueTooths != null && newBlueTooths.size() > 0)
                blueToothMap.put(NEW_BLUETOOTHS, newBlueTooths);
                // else
                // blueToothMap.put(NEW_BLUETOOTHS, null);
                mSearchListener.finishSearch(blueToothMap);
                break;
            }
        }
    };

周边的蓝牙设备一般会有两种,一种是未配对的、还有就是已配对的,Android系统中以BondState绑定状态,来辨别蓝牙是否已经配对,所以我这里创建两个集合:connectedBlueTooths、newBlueTooths来保存搜索的蓝牙设备。

首先在接收到开始搜索广播的时候
    connectedBlueTooths.clear();
    newBlueTooths.clear();
    mSearchListener.startSearch();

将集合进行清零,避免在第二次搜索的时候加入了相同的两个设备。然后调用mSearchListener.startSearch();通知用户开始搜索了,用户所处相关的相应,比如告诉试用者开始搜索、正在搜索。

在接受到found广播的时候:
BluetoothDevice device = arg1
                        .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
        BlueTooth blueTooth = new BlueTooth();
        blueTooth.setName(device.getName());
        blueTooth.setAddress(device.getAddress());
        blueTooth.setType(device.getType());
        blueTooth.setUuid(device.getUuids());
        short rssi = arg1.getExtras().getShort(
        BluetoothDevice.EXTRA_RSSI);

BlueToothDevice实现了Parcelable接口,用于Android的IPC通信机制,也就可以用于在intent中传输数据,当蓝牙设备发现周边一个蓝牙设备时就会发送来一个found的广播intent,并将蓝牙的相关信息以BlueToothDevice对象的形式发送过来,在intennt中获得该对象,就可以获得该蓝牙设备的相关信息了,然后我将它的信息保存到自己的BlueTooth类的对象中。并且,最后也多余的获得了一下蓝牙的信号强度。当然如果没有发现新设备就不会发送found广播了。

        if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
            for (BlueTooth blueToothPul : connectedBlueTooths) {
                if (blueToothPul.getAddress().equals(
                        blueTooth.getAddress()))
                    return;
            }
            connectedBlueTooths.add(blueTooth);
        } else {
            for (BlueTooth blueToothPul : newBlueTooths) {
                if (blueToothPul.getAddress().equals(
                        blueTooth.getAddress())) {
                    return;
                }
            }
            newBlueTooths.add(blueTooth);
        }
        mSearchListener.whileSearch(device);

这里依据该蓝牙设备的BondState来判断该蓝牙设备是否已经配对过,再通过遍历相应的集合来判断该设备是否已经找到过并添加到集合中过,避免重复添加,然后将该蓝牙设备信息添加到相应的集合当中。最后再通知用户找到一个蓝牙设备,并直接将广播发送来的蓝牙设备BlueToothDevice发给用户,做出相关相应。

最后接收到搜索结束广播
Map<String, List<BlueTooth>> blueToothMap = new HashMap<String, List<BlueTooth>>();
        // if (connectedBlueTooths != null
        // && connectedBlueTooths.size() > 0)
        blueToothMap.put(CONNECTED_BLUETOOTHS, connectedBlueTooths);
        // else
        // blueToothMap.put(CONNECTED_BLUETOOTHS, null);
        // if (newBlueTooths != null && newBlueTooths.size() > 0)
        blueToothMap.put(NEW_BLUETOOTHS, newBlueTooths);
        // else
        // blueToothMap.put(NEW_BLUETOOTHS, null);
        mSearchListener.finishSearch(blueToothMap);

这里通过一个Map的方式保存两种蓝牙设备的集合key值分别为:

    public final static String CONNECTED_BLUETOOTHS = "connectedBlueTooths";
    public final static String NEW_BLUETOOTHS = "newBlueTooths";

然后将map传递给用户,用户通过map提取相应的数据,就能知道附近的未配对和已经配的蓝牙设备有哪些了。

至此结束第一篇获取周边的蓝牙设备

下面贴出整合蓝牙操作的Java源代码:
码云链接:https://gitee.com/D_inasour/codes/8c5yt4nd2xb9uzml10h7e16
csdn资源链接:http://download.csdn.net/download/d_inosaur/9946750

欢迎入门学习交流,系统收费0.1,勿在意:
欢迎入门学习交流,系统收费0.1,勿在意

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值