android 蓝牙锁应用开发实例(三)蓝牙相关功能实现【第一部分】

本人水平有限,文章中如果出现什么不正确或者模糊的地方,还请各位小伙伴留下评论,多多指教 : )

  • 正式开始前的话
  • 蓝牙开发梳理
    • 整体思路
    • 核心API
      • BlueToothAdapter
        • 简介
        • getDefaultAdapter
        • getBondedDevices
        • isDiscovering
        • startDiscovery
        • cancelDiscovery
        • getRemoteDeviceString address
        • enable disable
        • getAddress getName getState
        • listenUsingRfcommWithServiceRecordString nameUUID uuid
      • BluetoothDevice
        • 简介
        • createRfcommSocketToServiceRecordUUIDuuid
        • getAddress getName getState
      • BluetoothServerSocket和BluetoothSocket
  • 编码阶段
    • 程序功能
    • 程序设计
    • 类详解
      • DeviceListAdapter
      • Device
      • BlueToothUnit
      • BtBrocastReceiver
      • PairingDeviceActivity
  • 总结

正式开始前的话

  之前2篇关于蓝牙的文章是很久之前写的博文,算是CSDN的开篇之作,里面存在许多的不足,而且后面也没能坚持下来,有一些小伙伴私信我要这部分的代码,刚好最近手上的一个项目也是和蓝牙有关,所以今天特意特意把这个项目又下下来,一方面总结最近一段时间关于蓝牙的开发,另一方也算把前两篇的坑给填上~~

  至于这个项目当中涉及到的其他内容,例如数据库的使用,界面的编写等都不再在这个系列的博客做详细介绍(当时写的太菜了……没啥好介绍的(:з」∠)有兴趣的小伙伴届时可以看看源码~),本系列的博客将会把重点放在蓝牙的处理上。这里附上之前写的两篇文章地址,有兴趣的小伙伴可以去看一看~~
android 蓝牙锁应用实例开发(一) 简介
android 蓝牙锁应用开发实例(二)客户端基本页面

蓝牙开发梳理

整体思路

  我一直认为,无论做什么样的开发,一定要思路先行,在了解大致的工作流程后,才便于我们后面对各种琐碎细节的研究。不仅能加深理解,还能养成良好的思维模式。接下来就带大家简单梳理一下蓝牙开发的流程。

(1)获取蓝牙开发的权限
(2)扫描附近的蓝牙设备,并将这些设备加入到devices列表
(3)选择要配对的设备,将次设备加入到已配对设备列表
(4)进行数据通信或其他操作
(5)接触配对状态

若干年之后,你可能具体的代码细节忘记 ,但是上面的步骤应该是做过一次开发就不会忘记了。

在第2步和第3部中涉及了2个列表,一个是【设备列表】,一个是【匹配设备列表】。

设备列表——是指附近的可见蓝牙设备,但是还没匹配
匹配设备列表——是指已经完成匹配的列表

大家要理解这2种列表的区别。因为列表的区别,也代表了设备状态。

即【未匹配状态】、【匹配状态】、【配对状态】

未匹配,就是指从来没有匹配过的设备。
匹配状态,就是指设备间已经相互完成了身份验证,处于待配对(待建立Socket)状态。

不知大家还记不记得,以前蓝牙配对的时候,手机会弹出一个对话框,提示输入pin码,其实也就是提前约定的一个配对码,到后来,手机与与手机之间的连接就不需要配对码了(实际上是程序内部完成了配对的过程)。

当然,手机与一些蓝牙硬件(例如单片机+蓝牙模块的组合)配对时,还是需要输入pin码(不过也能通过程序自动完成验证)

那么什么配对状态呢?

配对的过程,其实就是Socket通信的一个过程,两个蓝牙设备仅仅匹配是还不能够传递数据的,只有当二者建立了Socket通道之后,才能进行数据的传递。

好了,基本是思路差不多介绍完了,为了加深大家对蓝牙的理解,我这里再把上面的内容,通过图的形式再总结一下。同时我也会把蓝牙相关操作的核心API给列在次图中,让大家对下一节的内容有大致的了解

android 蓝牙锁应用开发实例(三)蓝牙相关功能实现【第一部分】_第1张图片

接下来,将对涉及蓝牙操作的几个核心API进行介绍。

核心API

本节内容将讲解蓝牙操作的核心API,这里说明一下,android的蓝牙开发有涉及到不同的蓝牙种类,例如低功耗蓝牙(BluetoothGatt)、蓝牙健康(BlueToothHealth)等,这里介绍的依然是常规的蓝牙开发API

再多啰嗦一句……API查看哪家强……那肯定是官方文档啦~当然是对于英文基础不错的小伙伴,不过英语一般的小伙伴也不用太担心,毕竟有很多优秀的翻译软件及API中文站,这里我提供一个传送们,希望深入理解的BlueTooth或者其他API的小伙伴有空可以经常去看看。

Bluetooth www.android-doc.com

BlueToothAdapter

简介

这个类代表着本地的蓝牙适配器,让你可以从事各种与蓝牙相关的操作,例如开始和停止设备的查找;查询已匹配的设备并以集合的形式返回;通过已知的设备地址,实例化一个BlueToothDevice;创建一个BluetoothServerSocket来监听来自其他设备的链接请求等等,总之要想使用本机的蓝牙,这个类是极其重要的。

getDefaultAdapter()

获取本地的蓝牙适配器,一般的调用代码如下:

        //获取本地蓝牙适配器
        bluetoothAdapter=BluetoothAdapter.getDefaultAdapter();

getBondedDevices()

获取已经匹配的设备列表,并以set集合的方式返回
调用代码如下:

    /*
    *获取已经配对的设备
    * */
        private void setPairingDevice() {
        Set devices=bluetoothAdapter.getBondedDevices();
        if(devices.size()>0){ //存在已配对过的设备
           //利用for循环读取每一个设备的信息
            for(Iterator it = devices.iterator(); it.hasNext();){
                BluetoothDevice btd=it.next();
                ```````
            }
        }else{   
        //不存在已经配对的蓝牙设备
                    }
    }

isDiscovering()

判断当前是否正在查找设备,是返回true

startDiscovery()

这里需要注意一下,由于搜素是一个耗时操作,所以这个方法应该在线程中去调用,同时需要配合着广播去使用,关于广播的内容,将在下一个小节中详细讲解。
开始查找设备,一般的调用代码如下:

/**
     * 开始附加设备的查找
     */
    private void doDiscovery() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                //如果adapter正在查询,停止查询
                if(bluetoothAdapter.isDiscovering()){
                    bluetoothAdapter.cancelDiscovery();
                }
                bluetoothAdapter.startDiscovery();
            }
        }).start();
    }

这里再注意一个细节,那就是如果当前的adapter正在查找,那么必须停止当前查找,然后再重新查找,这是因为查找操作占用很多的系统资源,我们需要避免重复的查找

cancelDiscovery()

取消查找设备,在上面的已经调用过

getRemoteDevice(String address)

根据一个蓝牙设备的地址来获取该地址,这个方法返回一个BlueToothDevice的实例

enable() | disable()

字面意思,打开或者关闭本机的蓝牙。
一般的调用代码如下:

//获取蓝牙适配器
        mBluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
        //如果蓝牙没有打开则打开蓝牙
        if (!mBluetoothAdapter.isEnabled()) {
            //请求用户开启
            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(intent, REQUEST_COMMUNICATE);
        }

getAddress() | getName() | getState()

getAddress()获取本地蓝牙地址
getName()获取本地蓝牙名称
getState()获取本地蓝牙适配器当前状态

listenUsingRfcommWithServiceRecord(String name,UUID uuid)

listenUsingRfcommWithServiceRecord(String name,UUID uuid)根据名称,UUID创建并返回BluetoothServerSocket。这个方法是创建BluetoothSocket服务器端不可缺少的一步。

BluetoothDevice

简介

这个类代表一个远程设备,它能够让我们与一个其他相关设备创建连接,或者查询与此设备相关的信息,例如名称(name)、地址(address)、连接状态(boud state)

createRfcommSocketToServiceRecord(UUIDuuid)

根据UUID创建并返回一个BluetoothSocket。

getAddress() | getName() | getState()

getAddress()获取Address设备的蓝牙地址
getName()获取Address设备的地蓝牙名称
getState()获取Address设备的蓝牙适配器当前状态

BluetoothServerSocket和BluetoothSocket

这里把这两个API放在一起说,这两个方法相互对应,ServerSocket对应的服务端,Socket对应的是客户端,具体内容在下一节中介绍

至此,所有的比较重要的API都已经介绍完毕了,现在正式进入代码编写的阶段。

编码阶段

程序功能

本篇文章只完成附近蓝牙设备的搜索和链接,关于数据通信的部分将在下一篇文章中介绍
功能:
(1)搜索附近蓝牙设备
(2)与附近蓝牙设备配对

程序设计

代码目录如下
android 蓝牙锁应用开发实例(三)蓝牙相关功能实现【第一部分】_第2张图片

类详解

DeviceListAdapter

这个类是自定义的BaseAdapter,作为用来显示蓝牙设备的listView的适配器

源码:

/**
 * Created by dell on 2016/9/22.
 * 存放以匹配蓝牙设备的ListView的Adapter
 */
public class DeviceListAdapter extends BaseAdapter {
    //标识符,详见【说明1】
    private final int NEAR_DEVICE=1;
    private final int PAIRING_DEVICE=2;
    //存储设备的容器
    private DeviceListListener deviceListListener;
    private ArrayList devices;
    private BluetoothAdapter mBluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
    private LayoutInflater inflater;
    private Context context;
    //用于标示附近设备和以配对设备的标识
    private int flag;
    //接口
    public interface DeviceListListener{
        //更新ArrayList
         void notifyArrayList();
        //提示取消配对成功
        void cancelSuccess();
        //配对成功
        void bindSuccess();
    }

    public DeviceListAdapter(Context context, ArrayList devices){
        this.devices=devices;
        this.context=context;
        inflater=LayoutInflater.from(context);

    }

    //为adapter设置一个flag
    public void setFlag(int i ){
        flag=i;
    }
    public void setDeviceListListener(DeviceListListener deviceListListener){
        this.deviceListListener=deviceListListener;
    }

    @Override
    public int getCount() {
        return devices.size();
    }

    @Override
    public Object getItem(int i) {
        return devices.get(i);
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        ViewHolder viewHolder;
        //如果View是空,则实例化viewHolder
        if(view==null){
            viewHolder=new ViewHolder();
            view=inflater.inflate(R.layout.binding_device_list_item,null);
            viewHolder.deviceAddress= (TextView) view.findViewById(R.id.device_address);
            viewHolder.deviceName= (TextView) view.findViewById(R.id.device_name);
            view.setTag(viewHolder);
        }else{
            viewHolder= (ViewHolder) view.getTag();
        }
        final Device device=devices.get(i);
        //设置设备名称和地址
        viewHolder.deviceAddress.setText(device.getAddress());
        viewHolder.deviceName.setText(device.getDevName());
        //为view设置点击事件
        switch (flag){
            case NEAR_DEVICE:
                setNearDeViceEvent(view,device);
                break;
            case PAIRING_DEVICE:
                setPairingDeviceEvent(view,device);
                break;
        }
        return view;
    }


    /**
     * 为配对设备ListView设置相关事件
     */
    private void setPairingDeviceEvent(View view,final Device device) {
        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

            }
        });
        view.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                final AlertDialog.Builder builder =new AlertDialog.Builder(context);
                builder.setTitle("提示").
                        setMessage("您确定要与该设备取消配对吗?").
                        setPositiveButton("确定", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                BlueToothUnit.unBindDevice(mBluetoothAdapter,device,deviceListListener);

                            }
                        }).show();
                return false;
            }
        });
    }


    /**
     * 为附近设备ListView设置相关事件
     */
    private void setNearDeViceEvent(View view,final Device device) {
        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final AlertDialog.Builder builder=new AlertDialog.Builder(context);
                 builder.setTitle("提示").
                        setMessage("您确定要和此设备配对吗?")
                        .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                try {
                                    BlueToothUnit.bindTargetDevice(mBluetoothAdapter,device,deviceListListener);
                                } catch (NoSuchMethodException e) {
                                    e.printStackTrace();
                                } catch (InvocationTargetException e) {
                                    e.printStackTrace();
                                } catch (IllegalAccessException e) {
                                    e.printStackTrace();
                                }
                            }
                        }).
                        setNegativeButton("取消",null).
                        show();
            }
        });

    }
    class ViewHolder
    {
        TextView deviceName;
        TextView deviceAddress;
    }
}

【说明1】
因为这个adapter既要被已匹配设备的listView使用,也要被附近设备的listView使用,而两个listView对应 item点击事件又是不一样的,所以,在一开始设置了2个标识符,用以区分。
【说明2】
与蓝牙有关的操作,都封装在了BluetoothUnit当中
【说明3】
此类是一个标准BaseAdapter的写法,getView()当中通过LayoutInfater加载了一个自定义的布局,同时使用了viewHolder对listView进行优化。

Device

一个标准的Java Bean,表示一个蓝牙设备的实例

public class Device {
    //蓝牙地址
    private String address;
    //设备名称
    private String devName;

    public Device(String devName, String address) {
        this.address = address;
        this.devName = devName;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getDevName() {
        return devName;
    }

    public void setDevName(String devName) {
        this.devName = devName;
    }
}

BlueToothUnit

封装了与蓝牙操作相关的方法

public class BlueToothUnit {
    private final String TAG = "--BlueToothUnit--";
    public static void unBindDevice(BluetoothAdapter mBluetoothAdapter, Device device, DeviceListAdapter.DeviceListListener  deviceListListener){
        //利用反射的方法取消配对
        BluetoothDevice device0 = mBluetoothAdapter.getRemoteDevice(device.getAddress());
        try {
            Boolean returnValue ;
            Method m = device0.getClass().getMethod("removeBond");
            returnValue = (Boolean) m.invoke(device0);
            if (returnValue)
                deviceListListener.cancelSuccess();
        } catch (Exception e) {
            e.printStackTrace();
        }
        //成功取消配对后更新listView
        deviceListListener.notifyArrayList();
    }
    /**
     * 配对指定的设备
     */
    public static void bindTargetDevice(BluetoothAdapter localBluetoothAdapter, Device device, DeviceListAdapter.DeviceListListener deviceListListener) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //在配对之前,一定要停止搜搜
        if (localBluetoothAdapter.isDiscovering()) {
            localBluetoothAdapter.cancelDiscovery();
        }
        //获取配对的设备
        BluetoothDevice btDev = localBluetoothAdapter.getRemoteDevice(device.getAddress());
        Boolean returnValue;
        if (btDev.getBondState() == BluetoothDevice.BOND_NONE) {
            //利用反射方法调用BluetoothDevice.createBond(BluetoothDevice remoteDevice);
            Method createBondMethod = BluetoothDevice.class.getMethod("createBond");
            Log.d("---", "开始配对");
            returnValue = (Boolean) createBondMethod.invoke(btDev);
            if (returnValue){
                Log.d("---", "bindTargetDevice "+"配对成功");
                deviceListListener.bindSuccess();

            }
        }
    }

    /**
     * @param bluetoothAdapter 本地蓝牙适配器
     * 开始蓝牙设备的搜索
     */
    public static void findAvailableDevices(final BluetoothAdapter bluetoothAdapter) {
        //开始搜索工作
        new Thread(new Runnable() {
            @Override
            public void run() {
                //如果蓝牙正在搜索,则停止搜索,然后再重新开始搜索
                if (bluetoothAdapter.isDiscovering()) {
                    bluetoothAdapter.cancelDiscovery();
                }
                //调用此方法会不断的发送广播,用户只需自定义一个receiver接受即可
                bluetoothAdapter.startDiscovery();
            }
        }).start();
    }
}

通过反射的方法完成连接或取消配对

BtBrocastReceiver

接受蓝牙相关的广播,并作出相应的操作

public class BtBroadcastReceiver extends BroadcastReceiver {
    private final String TAG="--broadcastReceiver--";
    private ArrayList nearDevices;
    private DeviceListAdapter adapter;
    private ProgressDialog progressDialog;
    public interface  BroadcastListener{
         void finishSearch();
         void bindSuccess();
    }
    private BroadcastListener broadcastListener;
    public BtBroadcastReceiver(Context context, ArrayList nearDevices,DeviceListAdapter adapter,BroadcastListener broadcastListener){
        this.nearDevices=nearDevices;
        this.broadcastListener=broadcastListener;
        this.adapter=adapter;
        progressDialog=new ProgressDialog(context);
        progressDialog.setTitle("正在查询附近设备");
        progressDialog.setCancelable(false);
        progressDialog.setMessage("请稍等……");
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        switch (action){
            case BluetoothAdapter.ACTION_DISCOVERY_STARTED: //索索开始
                Log.w(TAG,"--开始寻找设备");
                progressDialog.show();
                //清空nearList里面的数据
                nearDevices.clear();
                break;

            case BluetoothDevice.ACTION_FOUND: //发现设备
                Log.w(TAG,"--找到设备");
                //拿到蓝牙设备
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                //如果此设备的状态是还未匹配,则把它加入到设备列表当中
                if(device.getBondState()==BluetoothDevice.BOND_NONE) {
                    Device d=new Device(device.getName(),device.getAddress());
                    nearDevices.add(d);
                    adapter.notifyDataSetChanged();
                }
                progressDialog.setMessage("已找到"+nearDevices.size()+"台设备……");
                break;

            case BluetoothDevice.ACTION_BOND_STATE_CHANGED: //状态改变
                device=intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                switch (device.getBondState()) {
                    case BluetoothDevice.BOND_BONDING:
                        Log.w("BlueToothTestActivity", "正在配对......");
                        progressDialog.setTitle("正在配对");
                        progressDialog.setMessage("请稍等……");
                        progressDialog.show();
                        break;
                    case BluetoothDevice.BOND_BONDED:
                        Log.w("BlueToothTestActivity", "配对完成");
                        broadcastListener.bindSuccess();
                        progressDialog.dismiss();
                        break;
                    case BluetoothDevice.BOND_NONE:
                        Log.w("BlueToothTestActivity", "取消配对");
                    default:
                        break;
                }

                break;

            case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:// 搜索完成
                Log.w("finish:----", "搜索完成!");

                progressDialog.dismiss();
                if(nearDevices.size()==0){
                    Toast.makeText(context,"附近没有可用设备",Toast.LENGTH_SHORT).show();
                }else{
                    Toast.makeText(context,"搜索到"+nearDevices.size()+"台设备",Toast.LENGTH_SHORT).show();
                }
                broadcastListener.finishSearch();

                break;

        }
    }
}

这个类主要是监听蓝牙相关的广播,这些广播的注册逻辑放在了PairingDeviceActivity当中

PairingDeviceActivity

显示已配对设备的listView,以及搜索附近的设备和广播的注册

/**
 * Created by dell on 2016/9/22.
 * 本类用于显示已经和手机匹配了的设备,并且可以搜寻附近的设备
 */
public class PairingDeviceActivity extends AppCompatActivity implements BtBroadcastReceiver.BroadcastListener {
    private final String TAG="--Pairing--";
    //状态标识符
    private final int NEAR_DEVICE=1;
    private final int PAIRING_DEVICE=2;
    private TextView emptyView;
    //显示已经匹配的设备
    private ListView pairingListView;
    //蓝牙适配器
    private BluetoothAdapter bluetoothAdapter;
    //存储以匹配设备的容器
    private ArrayList pairingDevices=new ArrayList<>();
    //存储附近设备的容器
    private ArrayList nearDevices=new ArrayList<>();

    //已匹配设备的Adapter
    private DeviceListAdapter pairingDeviceListAdapter;
    //附近设备的Adapter
    private DeviceListAdapter nearDeviceListAdapter;

    //匹配附近设备时弹出的alter
    private AlertDialog alertDialog;

    private LayoutInflater inflater;
    //是否进行了广播接收器注册的标识符
    private boolean hasRegister=false;
    //广播接收器
    private BtBroadcastReceiver mReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.pairing_device_activity);

        //初始化控件
        init();

        //初始化适配器
        initAdapter();

        //获取当前匹配的数据
        setPairingDevice();

        nearDeviceListAdapter.setDeviceListListener(new DeviceListAdapter.DeviceListListener() {
            @Override
            public void notifyArrayList() {
            }

            @Override
            public void cancelSuccess() {
            }

            @Override
            public void bindSuccess() {
              //  Toast.makeText(PairingDeviceActivity.this,"配对成功!",Toast.LENGTH_SHORT).show();
            }
        });
        //添加更新ListView的方法
        pairingDeviceListAdapter.setDeviceListListener(new DeviceListAdapter.DeviceListListener() {
            @Override
            public void notifyArrayList() {
                pairingDevices.clear();
                //让adapter获得以匹配的设备
                setPairingDevice();
                pairingDeviceListAdapter.notifyDataSetChanged();
            }

            @Override
            public void cancelSuccess() {
                Toast.makeText(PairingDeviceActivity.this,"已取消配对",Toast.LENGTH_SHORT).show();
            }

            @Override
            public void bindSuccess() {
                Toast.makeText(PairingDeviceActivity.this,"配对成功!",Toast.LENGTH_SHORT).show();
            }
        });
}
    /*
        * 初始化ui及其他组件
        * */
    private void init() {
        pairingListView= (ListView) findViewById(R.id.list_binding_devices);
        emptyView= (TextView) findViewById(R.id.tv_empty);
        inflater=LayoutInflater.from(PairingDeviceActivity.this);


    }

    /**
     * 初始化适配器
     */
    private void initAdapter() {
        //获取本地蓝牙适配器
        bluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
        //匹配设备和附加设备list的适配器
        nearDeviceListAdapter=new DeviceListAdapter(this,nearDevices);
        pairingDeviceListAdapter=new DeviceListAdapter(this,pairingDevices);
        //设置adapter的标识符
        pairingDeviceListAdapter.setFlag(PAIRING_DEVICE);
        nearDeviceListAdapter.setFlag(NEAR_DEVICE);
        //list与adapter绑定
        pairingListView.setAdapter(pairingDeviceListAdapter);

        //初始化接收器
        mReceiver=new BtBroadcastReceiver(PairingDeviceActivity.this,nearDevices,nearDeviceListAdapter,this);

    }

    //寻找附近设备
    public void onClickFindNearDevices(View view){
        //开始查询工作
        doDiscovery();
    }

    /**
     * 开始附加设备的查找
     */
    private void doDiscovery() {
        BlueToothUnit.findAvailableDevices(bluetoothAdapter);
    }

    @Override
    protected void onStart() {
        super.onStart();
        //注册广播
        if(!hasRegister) {
            hasRegister = true;
            //寻找到设备的过滤器
            IntentFilter filterStar = new IntentFilter(BluetoothDevice.ACTION_FOUND);
            //绑定状态改变
            IntentFilter changeFilter= new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
            //搜索完成
            IntentFilter filterFinish = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
            //开始搜搜
            IntentFilter startSearch=new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
            registerReceiver(mReceiver,startSearch);
            registerReceiver(mReceiver, filterFinish);
            registerReceiver(mReceiver, filterStar);
            registerReceiver(mReceiver, changeFilter);
        }
        //注册的广播在活动结束时需要注销
    }



    /*
    *获取已经配对的设备
    * */

    private void setPairingDevice() {
        Set devices=bluetoothAdapter.getBondedDevices();
        if(devices.size()>0){ //存在已配对过的设备
            emptyView.setVisibility(View.GONE);
            pairingListView.setVisibility(View.VISIBLE);
            pairingDevices.clear();
            for(Iterator it = devices.iterator(); it.hasNext();){
                BluetoothDevice btd=it.next();
                Device device =new Device(btd.getName(),btd.getAddress());
                Log.d("---", "setPairingDevice: name "+btd.getName()+" address is "+btd.getAddress());
                //将device添加到PairingDeviceActivity当中的devices,注意this
                pairingDevices.add(device);
            }
        }else{   //不存在已经配对的蓝牙设备
            emptyView.setVisibility(View.VISIBLE);
            pairingListView.setVisibility(View.GONE);
            Toast.makeText(this,"不存在已配对设备",Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //如果蓝牙适配器正在扫描,则停止扫描
        if(bluetoothAdapter!=null&&bluetoothAdapter.isDiscovering())
            bluetoothAdapter.cancelDiscovery();

        //注销广播
        if(hasRegister){
            hasRegister=false;
            unregisterReceiver(mReceiver);
        }
    }


    @Override
    public void bindSuccess() {
        Log.d(TAG, "bindSuccess: ");
        alertDialog.dismiss();
        Toast.makeText(PairingDeviceActivity.this,"配对成功",Toast.LENGTH_SHORT).show();
        //更新数据
        setPairingDevice();
        pairingDeviceListAdapter.notifyDataSetChanged();
    }

    //广播完成搜索时
    @Override
    public void finishSearch() {
        //停止查询
        //如果蓝牙适配器正在扫描,则停止扫描
        if(bluetoothAdapter!=null&&bluetoothAdapter.isDiscovering()){
            Log.d("---", "finishSearch: " +"停止扫描");
            bluetoothAdapter.cancelDiscovery();
        }
        AlertDialog.Builder builder=new AlertDialog.Builder(PairingDeviceActivity.this);
        View view1=inflater.inflate(R.layout.near_devices_alertdialog,null);
        ListView nearAvailableListView= (ListView) view1.findViewById(R.id.list_near_devices);
        //为附近可用设备的list绑定adaper
        nearAvailableListView.setAdapter(nearDeviceListAdapter);
        alertDialog=builder.setTitle("附近的设备")
                .setView(view1)
                .create();
        alertDialog.show();
    }
}

【说明1】PairingDeviceActivity实现了BtBroadcastReceiver的接口,这个接口中需要重写三个方法,finishSearch()和bindSuccess()表示完成搜索和绑定成功。

总结

至此,就完成了蓝牙的搜索和配对,上面的代码还请大家更多关注逻辑上的处理,完整的项目代码,会在下此写蓝牙数据通信时一并贴出。

你可能感兴趣的:(总结篇)