为了账号安全,请及时绑定邮箱和手机立即绑定

android-蓝牙相关功能实现【第一部分】

标签:
Android

·         蓝牙开发梳理

o    整体思路

o    核心API

§  BlueToothAdapter

§  简介

§  getDefaultAdapter

§  getBondedDevices

§  isDiscovering

§  startDiscovery

§  cancelDiscovery

§  getRemoteDeviceString address

§  enable disable

§  getAddress getName getState

§  listenUsingRfcommWithServiceRecordString nameUUID uuid

§  BluetoothDevice

§  简介

§  createRfcommSocketToServiceRecordUUIDuuid

§  getAddress getName getState

§  BluetoothServerSocket和BluetoothSocket

·         编码阶段

o    程序功能

o    程序设计

o    类详解

§  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给列在次图中,让大家对下一节的内容有大致的了解


接下来,将对涉及蓝牙操作的几个核心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<BluetoothDevice> devices=bluetoothAdapter.getBondedDevices();

        if(devices.size()>0){ //存在已配对过的设备

           //利用for循环读取每一个设备的信息

            for(Iterator<BluetoothDevice> 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)与附近蓝牙设备配对

程序设计

代码目录如下 
 

类详解

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<Device> 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<Device> 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<Device> nearDevices;

    private DeviceListAdapter adapter;

    private ProgressDialog progressDialog;

    public interface  BroadcastListener{

         void finishSearch();

         void bindSuccess();

    }

    private BroadcastListener broadcastListener;

    public BtBroadcastReceiver(Context context, ArrayList<Device> 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<Device> pairingDevices=new ArrayList<>();

    //存储附近设备的容器

    private ArrayList<Device> 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);

        //listadapter绑定

        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<BluetoothDevice> devices=bluetoothAdapter.getBondedDevices();

        if(devices.size()>0){ //存在已配对过的设备

            emptyView.setVisibility(View.GONE);

            pairingListView.setVisibility(View.VISIBLE);

            pairingDevices.clear();

            for(Iterator<BluetoothDevice> 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()表示完成搜索和绑定成功。

总结

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

原文链接:http://www.apkbus.com/blog-842055-62034.html

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消