Android 教你如何写蓝牙程序2——获取目标信息

上文讲解了如何启动蓝牙功能。现在我们已经启动了蓝牙功能,接下来要做的是获取要连接的对象的蓝牙信息。
上文连接:Android 教你如何写蓝牙程序1——消息传递、启动蓝牙

1 获取已存储的蓝牙连接对象

我们先讲简单的,现在单纯要获取已存储的蓝牙连接对象信息。

//获取蓝牙适配器
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
//获取所有已连接的蓝牙设备信息,每一个蓝牙设备信息用BluetoothDevice存储
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();

这就完了。。
BluetoothDevice类有几个重要的方法

String getName();//获取蓝牙名
String getAddress();//获取MAC地址,用于连接配对
BluetoothGatt connectGatt(Context context, boolean autoConnect,BluetoothGattCallback callback)
//最后一个方法用于与特定设备建立建立连接,该方法在BLE低功耗建立蓝牙连接的时候需要用到
//本文为了连接HC-06模块采用Socket的方式建立蓝牙连接,不用BLE的方法。

2 搜索其他设备

//开启蓝牙搜索
 mBluetoothAdapter.startDiscovery();
 //结束蓝牙搜索
 mBluetoothAdapter.cancelDiscovery();
 //判断当前是否在蓝牙搜索
 mBluetoothAdapter.isDiscovering() //返回boolean

我们希望搜索到新的设备时,可以自动运行一些程序,这可以利用广播监听功能实现,监听的动作为 BluetoothDevice.ACTION_FOUND。当搜索到新的蓝牙设备时将广播该字段。
下面是广播接收程序

class BlueToothStateChange extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if(BluetoothDevice.ACTION_FOUND.equals(action)) {
        	//下面这句话可获取搜索到的新设备信息
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            //这里更新UI界面,并把刚获得的蓝牙设备信息存好
            
        }
    }
}
//注册广播接收器
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
context.registerReceiver(mReceiver, filter);
//启动蓝牙搜索功能
if(!mBluetoothAdapter.isDiscovering()){
    mBluetoothAdapter.startDiscovery();
}

注意,mBluetoothAdapter.startDiscovery();这句话将启动蓝牙设备搜索功能,并耗费大量资源,搜索到想要的设备之后,要及时使用mBluetoothAdapter.cancelDiscovery();关闭搜索功能。

3 具体的UI设计

我们先从用户的角度想一下,作为用户,我们希望怎么选择我们想要接连的对象呢?我采取的办法是:用AlertDialog构建一个临时对话框,并加入单选列表,把所有可连接的蓝牙设备显示出来,当用户点击确定的时候,获取选择的对象,这样就能得知目标信息了,并可以执行下一步了。

在 AlertDialog 中加入一个搜索蓝牙设备的功能,当广播接收器接收到新的设备信息后,自动更新临时对话框。

以下是这一部分的完整代码

public class BlueToothTool{
//来自布局的信息
	BluetoothAdapter mBluetoothAdapter;//蓝牙适配器
	Context context;
	Handler handlerToMain;
	//客户端
	private List<MapEntry> existBlueToothMap = new ArrayList<>();//用于存储已有的蓝牙信息
	public MapEntry clientMapEntry = null;//存储客户端蓝牙信息
	BluetoothDevice mDevice;
	//对话框
	AlertDialog alertDialog = null;
	
	public BlueToothTool(BluetoothAdapter mBluetoothAdapter, Context context, Handler handler){
	    this.mBluetoothAdapter = mBluetoothAdapter;
	    this.context = context;
	    this.handlerToMain = handler;
	    //打开蓝牙功能
	    BlueToothFuctionStart();
	}
	/**
	* 1.尝试打开蓝牙功能
	*/
	private void BlueToothFuctionStart(){
	    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
	    if(mBluetoothAdapter!=null){
	        //检测是否开启了蓝牙功能,注意startActivity会开启子线程,无法在此语句后面直接判断蓝牙功能是否被开启
	        if(!mBluetoothAdapter.isEnabled()) {
	            //尝试开启蓝牙功能
	            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
	            context.startActivity(enableBtIntent);
	            //注册对蓝牙状态功能的监听事件
	            //实例化IntentFilter对象
	            IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
	            context.registerReceiver(bluetoothStateBroadcastReceive,filter);
	        }else{
	            //直接执行下一步
	            //获取过去配对过的信息
	            //2.1查找已配对的设备
	            getExistBlueTooth();
	            show();
	        }
	    }else{
	        Toast.makeText(context,"您的设备不支持蓝牙系统",Toast.LENGTH_SHORT).show();
	    }
	}
	
	/**
	* 1.1通过广播对蓝牙状态进行监听
	*/
	private BluetoothStateBroadcastReceive bluetoothStateBroadcastReceive = new BluetoothStateBroadcastReceive();
	private class BluetoothStateBroadcastReceive extends BroadcastReceiver {
	    @Override
	    public void onReceive(Context context, Intent intent) {
	        String action = intent.getAction();
	        BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
	        switch (action) {
	            case BluetoothAdapter.ACTION_STATE_CHANGED:
	                int blueState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0);
	                if (blueState == BluetoothAdapter.STATE_ON) {
	                    try {
	                        //注销对象
	                        context.unregisterReceiver(bluetoothStateBroadcastReceive);
	                    } catch (Exception e){
	                        Log.d("蓝牙状态","注销监听失败,监听对象不存在");
	                    }
	                }
	                //执行下一步
	                //获取过去配对过的信息
	                //2.1查找已配对的设备
	                getExistBlueTooth();
	                show();
	            }
	        }
		}
	}
	
	/**
	* 1.2 查询已配对过的设备,并重置blueExistToothName数组
	*/
	public void getExistBlueTooth(){
	    Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
	    if (pairedDevices.size() > 0) {
	        int i = 0;
	        for (BluetoothDevice device : pairedDevices) {
	            //2.1把名字和地址取出来
	            existBlueToothMap.add(device);
	        }
	    }
	}
	//用于获取所有蓝牙设备信息的名称和MAC地址
	public ArrayList<MapEntry> getExistBlueToothNameAndValue(){
	    ArrayList<MapEntry> arr = new ArrayList<>();
	    for (int i = 0; i < existBlueToothMap.size(); i++) {
	        arr.add(new MapEntry(existBlueToothMap.get(i).getName(),existBlueToothMap.get(i).getAddress()));
	    }
	    return arr;
	}
	
	/*
	用于存储名称和地址
	*/
	public class MapEntry{
	    private String key;
	    private String value;
	    private MapEntry(){}
	    public MapEntry(String e,String v){
	        this.key = e;
	        this.value = v;
	    }
	    public String getKey() {
	        return key;
	    }
	    public String getValue() {
	        return value;
	    }
	    public String toString(){
	        return key + " :" + value;
	    }
	}
	/**
	* 2.尝试配对设备
	*  根据已经获得的蓝牙设备信息建立对话框
	*/
	public void show() {
	    if (mBluetoothAdapter.isEnabled()) {
	        if (existBlueToothMap.size() > 0) {
	            //2.2弹出对话框
	            AlertDialog.Builder builder = new AlertDialog.Builder(context);
	            builder.setTitle("蓝牙配对");
	            final ArrayList<MapEntry> tempArr = getExistBlueToothNameAndValue();
	            String[] showArr = new String[existBlueToothMap.size()];
	            for (int i = 0; i < tempArr.size(); i++) {
	                showArr[i] = tempArr.get(i).getKey() + " :" + tempArr.get(i).getValue();
	            }
	            final int[] choose = new int[1];
	            final Boolean[] isChoose = {false};
	            //蓝牙的信息列表
	            builder.setSingleChoiceItems(showArr, -1, new DialogInterface.OnClickListener() {
	                @Override//第二个参数指的是默认第几项被选中
	                public void onClick(DialogInterface dialog, int which) {
	                    //选中了哪个
	                    choose[0] = which;
	                    isChoose[0] = true;
	                }
	            });
	            //搜索设备
	            builder.setNeutralButton("搜索其他设备", new DialogInterface.OnClickListener() {
	                @Override
	                public void onClick(DialogInterface dialog, int which) {
	                    //3.在此处进行其他设备的搜索
	                    //注册广播
	                    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
	                    context.registerReceiver(mReceiver, filter);
	                    //启动蓝牙搜索功能
	                    if(!mBluetoothAdapter.isDiscovering()){
	                        mBluetoothAdapter.startDiscovery();
	                    }
	                    Toast.makeText(context,"正在进行蓝牙搜索",Toast.LENGTH_SHORT).show();
	                    show();
	                }
	            });
	            //确定
	            builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
	                @Override
	                public void onClick(DialogInterface dialog, int which) {
	                    if(isChoose[0]) {
	                        if (mBluetoothAdapter.isDiscovering())
	                            mBluetoothAdapter.cancelDiscovery();
	                        //注销广播监听
	                        try {
	                            context.unregisterReceiver(mReceiver);
	                        } catch (Exception e) {
	                            Log.d("蓝牙搜索接收器", "注销失败,不存在该接收器");
	                        }
	                        Toast.makeText(context, "正在尝试连接蓝牙设备", Toast.LENGTH_SHORT).show();
	                        //存储客户端蓝牙信息
	                        clientMapEntry = new MapEntry(tempArr.get(choose[0]).getKey(), tempArr.get(choose[0]).getValue());
	                        //获取目标蓝牙设备信息
	                        mDevice = existBlueToothMap.get(choose[0]);
	                        //此处可进行下一步
	                        
	                    }
	                }
	            });
	            //取消
	            builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
	                @Override
	                public void onClick(DialogInterface dialog, int which) {
	                    close();
	                }
	            });
	            alertDialog = builder.show();
	        }
	    }
	}
	
	/**
	* 2.1广播搜索其他的蓝牙设备
	* 下列语句用于注册广播接收
	*/
	// 新建一个 BroadcastReceiver来接收ACTION_FOUND广播
	private BlueToothStateChange mReceiver = new BlueToothStateChange();
	class BlueToothStateChange extends BroadcastReceiver{
	    @Override
	    public void onReceive(Context context, Intent intent) {
	        String action = intent.getAction();
	        if(BluetoothDevice.ACTION_FOUND.equals(action)) {
	            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
	            existBlueToothMap.add(new MapEntry(device.getName(), device.getAddress()));
	            if (alertDialog.isShowing())
	                alertDialog.dismiss();
	            show();//重新弹出对话框
	        }
	    }
	}
	
	/**
     * 关闭连接
     */
    public void close(){
         //关闭广播搜索
        try {
            if (!mBluetoothAdapter.isDiscovering()) {
                mBluetoothAdapter.cancelDiscovery();
            }
        }catch (Exception e){
            Log.d("蓝牙搜索","关闭失败,可能尚未开启,或者谁没没有蓝牙功能");
        }
        //注销广播监听
        try {
            context.unregisterReceiver(mReceiver);
        }catch (Exception e){
            Log.d("蓝牙搜索接收器","注销失败,不存在该接收器");
        }
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值