[AS3.0.1]蓝牙的基本使用,搜索和配对

蓝牙的最基本的用法,搜索和配对!
首先看下效果如下


开启蓝牙

开启蓝牙需要注册清单文件,初始化蓝牙适配器,添加广播监听,最后才是正式开启蓝牙。

清单文件加权限

    
    
    

5.0以上的版本需要加入gps权限

    
    

6.0以上的版本需要手动申请定位权限

    
    

注:6.0加入权限之后记得手动获取权限!不然蓝牙功能无法正常使用

初始化蓝牙(BluetoothAdapter)

初始化相当简单直接调用getDefaultAdapter方法就可以了

        //初始化蓝牙
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (bluetoothAdapter == null) {
            Toast.makeText(this, "设备不存在蓝牙", Toast.LENGTH_SHORT).show();
            return;
        }

初始化之后就可以用BluetoothAdapter对象进行对蓝牙的操作


BluetoothAdapter常用方法表格如下

方法 说明
getDefaultAdapter 默认本地适配器,如果此硬件平台不支持蓝牙,则为空。
isEnabled 如果蓝牙当前已启用并准备好使用,则返回true。
getState 获取本地蓝牙适配器的当前状态。STATE_OFF(关闭)、STATE_TURNING_ON(正在打开)、STATE_ON(开启)、STATE_TURNING_OFF(正在关闭)
enable 强制开启蓝牙
disable 强制关闭蓝牙
disable(boolean persist) 强制关闭蓝牙,是否保留设置。
getAddress 获取蓝牙地址
getName 获取蓝牙名字
factoryReset 出厂重置蓝牙
setName(String name) 设置蓝牙名字
getScanMode 获取蓝牙的扫描模式,扫描模式确定是否可以连接或被发现。SCAN_MODE_NONE(蓝牙未开启)、SCAN_MODE_CONNECTABLE(不可见)、SCAN_MODE_CONNECTABLE_DISCOVERABLE(可见)
setScanMode(@ScanMode int mode, int duration) (需要使用反射)设置蓝牙的扫描模式,单独的setScanMode(int mode)改变状态设置默认蓝牙可见时间
getDiscoverableTimeout、setDiscoverableTimeout(int timeout) (需要使用反射)获取和设置默认蓝牙可见时间
startDiscovery 开始扫描其他蓝牙
cancelDiscovery 取消扫描
isDiscovering 是否在扫描中
getBondedDevices 获取已绑定蓝牙
getConnectionState 获取蓝牙连接状态。STATE_CONNECTED(已连接)、STATE_DISCONNECTED(未连接)、STATE_CONNECTING(连接中)

添加广播

初始化之后就需要监听蓝牙的广播,不然无法获取搜索到了蓝牙设备

        //绑定广播
        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothDevice.ACTION_FOUND);//找到设备的广播
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索完成的广播
        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);//蓝牙状态改变的广播
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);//开始扫描的广播
        filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);//配对状态改变
        registerReceiver(mReceiver, filter);


    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//            Log.e("-s-", "action = " + action);
            switch (action) {
                //蓝牙状态改变
                case BluetoothAdapter.ACTION_STATE_CHANGED:
                    Log.e("-s-", "蓝牙状态改变");
                    checkBluetooth();
                    break;
                //开始扫描
                case BluetoothAdapter.ACTION_DISCOVERY_STARTED:
                    Log.e("-s-", "开始扫描蓝牙");
                    allAdapter.clear();
                    changeText("开始扫描蓝牙");
                    showToast("开始扫描蓝牙");
                    break;
                //搜索完成
                case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
                    Log.e("-s-", "搜索完成");
                    changeText("搜索完成");
                    showToast("搜索完成");
                    break;
                //找到设备
                case BluetoothDevice.ACTION_FOUND:
                    Log.e("-s-", "找到设备");
                    changeText("搜索中...");
                    printDevice(bluetoothDevice);
                    allAdapter.add(bluetoothDevice);
                    break;
                //配对状态改变
                case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
                    Log.e("-s-", "配对状态改变");
                    if (bluetoothDevice.getBondState() == BluetoothDevice.BOND_BONDING) {
                        changeText(bluetoothDevice.getName() + " 配对中");
                        Log.e("-s-", "配对中");
                    } else if (bluetoothDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
                        changeText(bluetoothDevice.getName() + " 已配对成功");
                        Log.e("-s-", "已配对成功");
                    } else {
                        changeText(bluetoothDevice.getName() + " 已取消配对");
                        Log.e("-s-", "已取消配对");
                    }
                    printDevice(bluetoothDevice);
                    updataBonds();
                    break;
                default:
            }
        }
    };

以上代码有常用的几个蓝牙相关的广播,这边主要讲下另一个比较需要注意的APIBluetoothDevice

以下表格是常用的BluetoothDevice方法

方法 说明
getAddress 获取蓝牙设备的地址
getName 获取蓝牙设备的名称(可能会空)
getType 获得蓝牙的设备类型。DEVICE_TYPE_UNKNOWN(未知)、DEVICE_TYPE_CLASSIC(br/edr设备)、DEVICE_TYPE_LE(低能量-仅限LE)、DEVICE_TYPE_DUAL(双模,BR/EDR/LE)
getAlias (需要反射调用)获取蓝牙设备的别名(可能会空)
getAliasName (需要反射调用)获取蓝牙的名称,优先别名,别名为空则返回名称,名称也有可能为空
createBond 启动与远程设备的连接(配对)过程。
createBond(int transport) (需要反射调用)使用指定的传输启动与远程设备的绑定(配对)过程。TRANSPORT_AUTO(没有偏好的GATT连接)、TRANSPORT_BREDR(优先和BR/EDR设备GATT连接)、TRANSPORT_LE(优先和LE设备GATT连接)
cancelBondProcess (需要反射调用)取消createBond创建的配对请求
removeBond (需要反射调用)取消设备配对
getBondState 获取设备的绑定状态。BOND_NONE(未绑定)、BOND_BONDING(绑定中)、BOND_BONDED(已绑定)
isConnected 返回是否有与此设备的打开连接。
getBluetoothClass 获取远程设备的蓝牙类。

正式开启蓝牙

有了BluetoothAdapter的初始化对象和广播监听蓝牙之后就可以开启蓝牙了!

  1. 强制开启

上面BluetoothAdapter的常用方法里面有一个强制开启蓝牙的方法

	//强制开启蓝牙
	bluetoothAdapter.enable();

在低于5.0以下的手机会直接打开蓝牙,以上就会以弹窗的形式提示是否允许。

  1. 正常打开蓝牙
	if (!bluetoothAdapter.isEnabled()) {
	    //单独打开蓝牙 可以连接 默认不可见
	    Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
	    startActivityForResult(intent, REQUEST_ENABLE);
	}

首先判断了蓝牙是否可用并且没有打开,在正常打开蓝牙。这样打开的蓝牙默认是可连接但不会被其他设备发现。

  1. 可见打开蓝牙
	if (!bluetoothAdapter.isEnabled()) {
	    //打开蓝牙并且自己蓝牙可见
	    Intent discoveryIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);//默认是120秒
	    discoveryIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);//设置持续时间(最多300秒)
	    startActivityForResult(discoveryIntent, REQUEST_ENABLE);
	}

还是一样首先判断了蓝牙是否可用并且没有打开,在正常打开蓝牙。这样打开的蓝牙可以连接并且可以被其他设备发现。

关闭蓝牙

上面BluetoothAdapter的常用方法里面有一个强制关闭蓝牙的方法,正常我们直接使用这个方法就可以了,因为没有其他的方法了。

	if (bluetoothAdapter.isEnabled()) {
	    bluetoothAdapter.disable();
	}

搜索蓝牙

  1. 全部搜索蓝牙
	//是否可用并开启蓝牙
	if (bluetoothAdapter.isEnabled()) {
		//是否在扫描状态
	    if (bluetoothAdapter.isDiscovering()) {
	        bluetoothAdapter.cancelDiscovery();
	    }
	    //开始扫描
	    bluetoothAdapter.startDiscovery();
	}

调用搜索之后 结果都是在广播中回调的
搜索广播片段如下 添加广播中有完整的片段

	String action = intent.getAction();
	//获取获得的设备
	BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
	switch (action) {
		//开始扫描
		case BluetoothAdapter.ACTION_DISCOVERY_STARTED:
		    Log.e("-s-", "开始扫描蓝牙");
		    ...
		    break;
		//搜索完成
		case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
		    Log.e("-s-", "搜索完成");
		    ...
		    break;
		//找到设备
		case BluetoothDevice.ACTION_FOUND:
		    Log.e("-s-", "找到设备");
		    //每次会获取到一个设备,可以加入到自己的listview中作为展示
		    ...
		    break;
	}
  1. 已配对蓝牙

直接取上面的方法getBondedDevices就可以了。

	//清空已配对listview的适配器
	bondAdapter.clear();
	//遍历已配对的Set
	for (BluetoothDevice device : bluetoothAdapter.getBondedDevices()) {
		//加入已配对listview的适配器
	    bondAdapter.add(device);
	}

配对蓝牙

由于createBond方法其实没有隐藏,所以可以直接调用方法进行配对,然后再广播中进行监听实现配对成功和失败的提示。

	//正常配对
	if (device.createBond()) {
	    Log.e("-s-", "开始配对");
	    ...
	} else {
	    Log.e("-s-", "配对失败");
	    ...
	}

或者调用反射来实现配对,网上找到的资料一般都是下面这个。但是上面的正常配对其实也是可以的。

	//反射配对
	try {
	    Method method = BluetoothDevice.class.getMethod("createBond");
	    boolean result = (boolean) method.invoke(device);
	    if (result) {
	        Log.e("-s-", "开始配对");
	        ...
	    }else {
	        Log.e("-s-", "配对失败");
	        ...
	    }
	} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
		Log.e("-s-", "配对失败");
		...
	}

取消配对蓝牙

由于没有取消方法被隐藏了,就必须用反射来实现取消了

	//反射取消配对
	try {
	    Method method = BluetoothDevice.class.getMethod("removeBond");
	    boolean result = (boolean) method.invoke(device);
	    if (result) {
	        Log.e("-s-", "取消成功");
	        ....
	    } else {
	        Log.e("-s-", "取消失败");
	        ...
	    }
	} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
		Log.e("-s-", "取消失败");
		...
	}

全部代码

BlueActivity.class
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.ParcelUuid;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

import com.gjn.baserecycleradapterlibrary.BaseRecyclerAdapter;
import com.gjn.baserecycleradapterlibrary.RecyclerViewHolder;
import com.gjn.permissionlibrary.PermissionUtils;
import com.gjn.testproject.R;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class BlueActivity extends AppCompatActivity {

    private static final int REQUEST_ENABLE = 0x1001;
    private static final int REQUEST_DISABLE = 0x1002;

    Button btn1, btn2, btn3, btn4, btn5, btn6;
    TextView tv;
    RecyclerView rv, rv2;
    Switch sw;

    private BluetoothAdapter bluetoothAdapter;

    private BaseRecyclerAdapter allAdapter;
    private BaseRecyclerAdapter bondAdapter;

    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//            Log.e("-s-", "action = " + action);
            switch (action) {
                //蓝牙状态改变
                case BluetoothAdapter.ACTION_STATE_CHANGED:
                    Log.e("-s-", "蓝牙状态改变");
                    checkBluetooth();
                    break;
                //开始扫描
                case BluetoothAdapter.ACTION_DISCOVERY_STARTED:
                    Log.e("-s-", "开始扫描蓝牙");
                    allAdapter.clear();
                    changeText("开始扫描蓝牙");
                    showToast("开始扫描蓝牙");
                    break;
                //搜索完成
                case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
                    Log.e("-s-", "搜索完成");
                    changeText("搜索完成");
                    showToast("搜索完成");
                    break;
                //找到设备
                case BluetoothDevice.ACTION_FOUND:
                    Log.e("-s-", "找到设备");
                    changeText("搜索中...");
                    printDevice(bluetoothDevice);
                    allAdapter.add(bluetoothDevice);
                    break;
                //配对状态改变
                case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
                    Log.e("-s-", "配对状态改变");
                    if (bluetoothDevice.getBondState() == BluetoothDevice.BOND_BONDING) {
                        changeText(bluetoothDevice.getName() + " 配对中");
                        Log.e("-s-", "配对中");
                    } else if (bluetoothDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
                        changeText(bluetoothDevice.getName() + " 已配对成功");
                        Log.e("-s-", "已配对成功");
                    } else {
                        changeText(bluetoothDevice.getName() + " 已取消配对");
                        Log.e("-s-", "已取消配对");
                    }
                    printDevice(bluetoothDevice);
                    updataBonds();
                    break;
                default:
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_blue);

        PermissionUtils.requestPermissions(this, PermissionUtils.CODE_LOCATION, PermissionUtils.CODE_PHONE);

        btn1 = findViewById(R.id.btn_1);
        btn2 = findViewById(R.id.btn_2);
        btn3 = findViewById(R.id.btn_3);
        btn4 = findViewById(R.id.btn_4);
        btn5 = findViewById(R.id.btn_5);
        btn6 = findViewById(R.id.btn_6);
        tv = findViewById(R.id.tv_state);
        sw = findViewById(R.id.sw_state);
        rv = findViewById(R.id.rv_ly);
        rv2 = findViewById(R.id.rv_ypd);

        //初始化蓝牙
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (bluetoothAdapter == null) {
            Toast.makeText(this, "设备不存在蓝牙", Toast.LENGTH_SHORT).show();
            return;
        }
        //绑定广播
        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothDevice.ACTION_FOUND);//找到设备的广播
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索完成的广播
        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);//蓝牙状态改变的广播
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);//开始扫描的广播
        filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);//配对状态改变
        registerReceiver(mReceiver, filter);

        //初始化RecyclerView和适配器
        rv.setLayoutManager(new LinearLayoutManager(this));
        rv2.setLayoutManager(new LinearLayoutManager(this));

        allAdapter = new BaseRecyclerAdapter(this, R.layout.item_blue, null) {
            @Override
            public void bindData(RecyclerViewHolder holder, BluetoothDevice device, int position) {
                holder.setTextViewText(R.id.tv_name, device.getName());
                holder.setTextViewText(R.id.tv_address, device.getAddress());
                if (BluetoothDevice.BOND_BONDED == device.getBondState()) {
                    holder.setTextViewText(R.id.tv_state, "已配对");
                } else {
                    holder.setTextViewText(R.id.tv_state, "未配对");
                }
            }
        };
        rv.setAdapter(allAdapter);

        bondAdapter = new BaseRecyclerAdapter(this, R.layout.item_blue, null) {
            @Override
            public void bindData(RecyclerViewHolder holder, BluetoothDevice device, int position) {
                holder.setTextViewText(R.id.tv_name, device.getName());
                holder.setTextViewText(R.id.tv_address, device.getAddress());
                if (BluetoothDevice.BOND_BONDED == device.getBondState()) {
                    holder.setTextViewText(R.id.tv_state, "已配对");
                } else {
                    holder.setTextViewText(R.id.tv_state, "未配对");
                }
            }
        };
        rv2.setAdapter(bondAdapter);

        checkBluetooth();

        initData();
    }

    private void initData() {

        allAdapter.setOnItemClickListener(new BaseRecyclerAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int pos) {
                bond(allAdapter.getItem(pos));
            }
        });

        bondAdapter.setOnItemClickListener(new BaseRecyclerAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int pos) {
                unBond(bondAdapter.getItem(pos));
            }
        });


        btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!bluetoothAdapter.isEnabled()) {
                    //单独打开蓝牙
                    Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                    startActivityForResult(intent, REQUEST_ENABLE);
                }
            }
        });

        btn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                bluetoothAdapter.enable();
            }
        });

        btn5.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    Method setScanMode = BluetoothAdapter.class.getMethod("setScanMode", int.class);
                    boolean result = (boolean) setScanMode.invoke(bluetoothAdapter, BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
                    Log.e("-s-", "result = " + result);
                    Method getDiscoverableTimeout = BluetoothAdapter.class.getMethod("getDiscoverableTimeout");
                    int time = (int) getDiscoverableTimeout.invoke(bluetoothAdapter);
                    Log.e("-s-", "time = " + time);
                } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                    e.printStackTrace();
                }

            }
        });

        btn6.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //打开蓝牙并且自己蓝牙可见
                Intent discoveryIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);//默认是120秒
                discoveryIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);//设置持续时间(最多300秒)
                startActivityForResult(discoveryIntent, REQUEST_ENABLE);
            }
        });

        btn3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (bluetoothAdapter.isEnabled()) {
                    bluetoothAdapter.disable();
                }
            }
        });

        btn4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (bluetoothAdapter.isEnabled()) {
                    if (bluetoothAdapter.isDiscovering()) {
                        bluetoothAdapter.cancelDiscovery();
                    }
                    bluetoothAdapter.startDiscovery();
                }
            }
        });

    }

    private void unBond(BluetoothDevice device) {
        if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
            //反射取消配对
            try {
                Method method = BluetoothDevice.class.getMethod("removeBond");
                boolean result = (boolean) method.invoke(device);
                if (result) {
                    Log.e("-s-", "取消成功");
                    showToast("取消成功");
                } else {
                    Log.e("-s-", "取消失败");
                    showToast("取消失败");
                }
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }

    private void bond(BluetoothDevice device) {
        if (device.getBondState() == BluetoothDevice.BOND_NONE) {
//            //反射配对
//            try {
//                Method method = BluetoothDevice.class.getMethod("createBond");
//                boolean result = (boolean) method.invoke(device);
//                if (result) {
//                    Log.e("-s-", "配对成功");
//                    showToast("配对成功");
//                }else {
//                    Log.e("-s-", "配对失败");
//                    showToast("配对失败");
//                }
//            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
//                e.printStackTrace();
//            }
            //正常配对
            if (device.createBond()) {
                Log.e("-s-", "开始配对");
                tv.setText(device.getName() + " 开始配对");
                showToast("开始配对");
            } else {
                Log.e("-s-", "配对失败");
                showToast(device.getName() + " 配对失败");
            }
        }
    }

    private void changeText(String str) {
        tv.setText(str);
    }

    private void showToast(String s) {
        Toast.makeText(this, s, Toast.LENGTH_SHORT).show();
    }

    private void checkBluetooth() {
        switch (bluetoothAdapter.getScanMode()) {
            case BluetoothAdapter.SCAN_MODE_CONNECTABLE:
                Log.e("-s-", "蓝牙可连接");
                tv.setText("蓝牙可连接");
                break;
            case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
                Log.e("-s-", "蓝牙可连接可发现");
                tv.setText("蓝牙可连接可发现");
                break;
            case BluetoothAdapter.SCAN_MODE_NONE:
            default:
                Log.e("-s-", "蓝牙不可连接不可见");
                tv.setText("蓝牙不可连接不可见");
        }
        if (bluetoothAdapter.isEnabled()) {
            sw.setChecked(true);
            updataBonds();
        } else {
            sw.setChecked(false);
            allAdapter.clear();
            bondAdapter.clear();
        }
    }

    private void updataBonds() {
        bondAdapter.clear();
        for (BluetoothDevice device : bluetoothAdapter.getBondedDevices()) {
            bondAdapter.add(device);
        }
    }

    private void printDevice(BluetoothDevice device) {
        Log.e("-s-", "Name = " + device.getName());
        Log.e("-s-", "Address = " + device.getAddress());
        Log.e("-s-", "BondState = " + device.getBondState());
        Log.e("-s-", "Type = " + device.getType());
        if (device.getUuids() != null) {
            for (ParcelUuid uuid : device.getUuids()) {
                Log.e("-s-", "uuid = " + uuid);
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(mReceiver);
    }
}
activity_blue.xml



    

    

资料

Android BLE 蓝牙开发入门
Android蓝牙开发(一)之打开蓝牙和设备搜索
Android蓝牙开发(二)之蓝牙配对和蓝牙连接
Android 低功耗蓝牙(BLE)开发(1)-- 基本概念
Android 低功耗蓝牙(BLE)开发(2)-- BluetoothAdapter详解
Android 低功耗蓝牙(BLE)开发(3)-- BluetoothDevice详解
Android 低功耗蓝牙(BLE)开发(4)-- 蓝牙扫描和连接

你可能感兴趣的:(程序日记)