开启蓝牙并设置永久可见

在调用蓝牙方面,接触最多的可能是BluetoothAdapter,很多操作蓝牙的方法多在此类中有接口,哪怕很多接口是不公开的,也可以通过反射的方式使用,如设置蓝牙永久可见和关闭可见的函数;而开启蓝牙大体逻辑为:

  1. 开启蓝牙权限
  2. 注册蓝牙广播
  3. 初始化BluetoothAdapter实例
  4. 开启蓝牙
  5. 设置可见或不可见

Bluetooth权限

AndroidManifest.xml 中注册

    <!-- 允许程序连接到已配对的蓝牙设备 -->
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <!-- 允许程序发现和配对蓝牙设备 -->
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

Bluetooth广播注册

if (mReceiver == null) { //蓝牙广播注册
     mReceiver = new CustomBroadcastReceiver();
     IntentFilter intentFilter = new IntentFilter();
     intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
     intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
     intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
     intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); 
     registerReceiver(mReceiver, intentFilter);
}

Bluetooth 广播Receiver

在启动蓝牙搜索时,系统会发送3个 action

BluetoothAdapter.ACTION_DISCOVERY_STARTED  //启动蓝牙搜索
BluetoothDevice.ACTION_FOUND  //查找到的结果
BluetoothAdapter.ACTION_DISCOVERY_FINISHED //结束蓝牙搜索

在自定义BroadcastReceiver中接受处理action; 这里需要注意的是:
@1开启蓝牙
@2接收ACTION_STATE_CHANGED广播
@3蓝牙状态是打开状态 (BluetoothAdapter.getState() == BluetoothAdapter.STATE_ON)
@4 设置蓝牙永久可见 setDiscoverableTimeout(0);

  • 这个顺序执行才能让你的蓝牙可以打开和可见

以下是搜索蓝牙的具体方法:

private class CustomBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_STARTED)) {
                Log.d(TAG, "正在扫描设备,请稍候...");
            } else if (action.equals(BluetoothDevice.ACTION_FOUND)) {
            
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if (device.getBondState() == BluetoothDevice.BOND_BONDED) { //TODO 可使用
                } else {   //TODO 可配对
                }
            } else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
                Log.d(TAG, "扫描结束");
            }

            if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
                if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) {
                    Log.d(TAG, "--------打开蓝牙-----------");
                    setDiscoverableTimeout(0); //蓝牙可见
                } else if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_OFF) {
                    Log.d(TAG, "--------关闭蓝牙-----------");
                }
            }
        }
    }

Android6.0蓝牙搜索需要定位权限,具体博文请看Android6.0权限详解, 蓝牙搜索使用的权限申请方法如下:

private void mayRequestLocation(){
    Log.d(TAG, "mayRequestLocation: androidSDK--" + Build.VERSION.SDK_INT);
    if(Build.VERSION.SDK_INT >= 23){
        //6.0以上设备
        int checkCallPhonePermission = checkSelfPermission(Manifest.permission.
                ACCESS_COARSE_LOCATION);
        if(checkCallPhonePermission != PackageManager.PERMISSION_GRANTED) {
            Log.d(TAG, "mayRequestLocation: 请求粗略定位的权限");
            requestPermissions(new String[]{Manifest.permission.
                    ACCESS_COARSE_LOCATION}, REQUEST_PERMISSION_LOCATION);
            return;
        }
    }
}

Bluetooth的适配器实例化和开启bluetooth

BluetoothAdapter 自身定义静态函数,获取适配器对象
public static synchronized BluetoothAdapter getDefaultAdapter()

        if (!mBluetoothAdapter.isEnabled()) { //检测是否开启
            mBluetoothAdapter.enable();   //打开蓝牙
        }

Bluetooth 的可见和不可见

可见:
通过系统setting强制开启,直接从后台开启蓝牙可见,但会一直可见下去,直到蓝牙关闭。

    private void setDiscoverableTimeout(int timeout) {
        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
        try {
            Method setDiscoverableTimeout = BluetoothAdapter.class.getMethod("setDiscoverableTimeout", int.class);
            setDiscoverableTimeout.setAccessible(true);
            Method setScanMode = BluetoothAdapter.class.getMethod("setScanMode", int.class, int.class);
            setScanMode.setAccessible(true);

            setDiscoverableTimeout.invoke(adapter, timeout);
            setScanMode.invoke(adapter, BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, timeout);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

不可见:
关闭了蓝牙可见性。

    private void closeDiscoverableTimeout() {
        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
        try {
            Method setDiscoverableTimeout = BluetoothAdapter.class.getMethod("setDiscoverableTimeout", int.class);
            setDiscoverableTimeout.setAccessible(true);
            Method setScanMode = BluetoothAdapter.class.getMethod("setScanMode", int.class, int.class);
            setScanMode.setAccessible(true);

            setDiscoverableTimeout.invoke(adapter, 1);
            setScanMode.invoke(adapter, BluetoothAdapter.SCAN_MODE_CONNECTABLE, 1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

BluetoothAdapter的常用方法

getAddress() //获取本地蓝牙地址

getDefaultAdapter() //获取默认BluetoothAdapter,实际上,也只有这一种方法获取BluetoothAdapter

getName() //获取本地蓝牙名称

getRemoteDevice(String address) //根据蓝牙地址获取远程蓝牙设备

getState() //获取本地蓝牙适配器当前状态(感觉可能调试的时候更需要)

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

isEnabled() //判断蓝牙是否打开,已打开返回true,否则,返回false

listenUsingRfcommWithServiceRecord(String name,UUID uuid) //根据名称,UUID创建并返回

BluetoothServerSocket,这是创建BluetoothSocket服务器端的第一步

startDiscovery() //开始搜索,这是搜索的第一步

BluetoothAdapter里的方法很多,常用的有以下几个:

cancelDiscovery()  //根据字面意思,是取消发现,也就是说当我们正在搜索设备的时候调用这个方法将不再继续搜索

disable() //关闭蓝牙

enable() //打开蓝牙,这个方法打开蓝牙不会弹出提示
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值