zoukankan      html  css  js  c++  java
  • [安卓] 20、基于蓝牙BLE的广播包高频快速搜索


    前言:

    之前介绍过很多蓝牙beacon、搜索、连接、通讯的文章。不过最近我发现:之前写的蓝牙广播包搜索的工程,搜索频率太慢,而且不能一直保持搜索状态。因此,这里探讨下高频蓝牙广播包扫描 —— 蓝牙BLE扫描。

    注: 本文将从对比之前慢的和现在快的两个工程进行展开


    1、初始化-onCreate

    新的:

    // Get the local Bluetooth adapter
    // Initializes Bluetooth adapter.
    final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
    mBluetoothAdapter = bluetoothManager.getAdapter();
    
    // Ensures Bluetooth is available on the device and it is enabled. If not,
    // displays a dialog requesting user permission to enable Bluetooth.
    if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
        Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
    }
    

    老的:

    // Register for broadcasts when a device is discovered
    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
    this.registerReceiver(mReceiver, filter);
    // Register for broadcasts when discovery has finished
    filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
    this.registerReceiver(mReceiver, filter);
    
    // Get the local Bluetooth adapter
    mBtAdapter = BluetoothAdapter.getDefaultAdapter();
    

    可见:老的是通过注册广播过滤条件BluetoothDevice.ACTION_FOUNDBluetoothAdapter.ACTION_DISCOVERY_FINISHED,来实现监听蓝牙设备扫描的发现和停止扫描事件。而mReceiver则是回调函数,接下来会介绍;新的暂时看不出啥头绪,仅仅获得bluetoothManagermBluetoothAdapter,接下来会用到。


    2、开始扫描-doDiscovery

    新的:

    // Start device discover with the BluetoothAdapter
    private void doDiscovery() {
        // If we're already discovering, stop it
        if (mBluetoothAdapter.isDiscovering()) {
        	mBluetoothAdapter.stopLeScan(mLeScanCallback);
        }
    	// Request discover from BluetoothAdapter
    	//use filter not work!!!!!!!!!!
    	//UUID[] uuid_arrays = new UUID[1];
    	//uuid_arrays[0] = ParcelUuid.fromString(UUID_SERVICE).getUuid();
    	//mBluetoothAdapter.startLeScan(uuid_arrays,mLeScanCallback);
    	//Log.d("RSSI",uuid_arrays[0].toString() + "  " + UUID.randomUUID().toString());
    	mBluetoothAdapter.startLeScan(mLeScanCallback);
    }
    

    老的:

    // Start device discover with the BluetoothAdapter
    private void doDiscovery() {
        // If we're already discovering, stop it
        if (mBtAdapter.isDiscovering()) {
    		mBtAdapter.cancelDiscovery();
        }
        // Request discover from BluetoothAdapter
        mBtAdapter.startDiscovery();
    }
    

    可见:区别在于一个是BLE操作、一个是普通蓝牙操作。


    3、监听

    新的:

    // Device scan callback.
    private BluetoothAdapter.LeScanCallback mLeScanCallback =
    	new BluetoothAdapter.LeScanCallback() {
    	    @Override
    	    public void onLeScan(final BluetoothDevice device, int rssi,
    		    byte[] scanRecord) {
    				runOnUiThread(new Runnable() {
    				    @Override
    			public void run() {
    				if(device_filter(device)){
    				    //mDevicesNameVector.add(device.getName());
    				    //mDevicesAddrVector.add(device.getAddress());
    				    //mRSSIVector.add((short)rssi);
    				    Log.d("RSSI",device.getAddress() + " " + device.getName() + " " + String.valueOf(rssi));
    				    ...
    				}
    			}
    		});
    	}
    };
    

    老的:

    // The BroadcastReceiver that listens for discovered devices and
    // changes the title when discovery is finished
    //【查找蓝牙设备】
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    	@Override
    	public void onReceive(Context context, Intent intent) {
    		Log.d("onReceive","OK");
    		String action = intent.getAction();
    		// When discovery finds a device
    		if (BluetoothDevice.ACTION_FOUND.equals(action)) {
    			// Get the BluetoothDevice object from the Intent
    			BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
    			mDevicesNameVector.add(device.getName());
    			mDevicesAddrVector.add(device.getAddress());
    			short rssi = intent.getExtras().getShort(BluetoothDevice.EXTRA_RSSI);
    			mRSSIVector.add(rssi);
    			Log.d("RSSI",device.getName()+"  "+String.valueOf(rssi));
    			// When discovery is finished, change the Activity title
    		} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
    			setProgressBarIndeterminateVisibility(false);
    			if (mDevicesNameVector.size() != 0) {
    				Message msg = new Message();//消息
    				Bundle bundle = new Bundle();
    			    bundle.clear();Log.d("onReceive","1");
    			    msg.what = 0x01;//消息类别
    			    bundle.putShort("msg",(short) 0);Log.d("onReceive","2");
    					msg.setData(bundle);Log.d("onReceive","3");
    					myHandler.sendMessage(msg);Log.d("onReceive","4");
    			}
    		}
    	}
    };
    

    可见:新的相对比较简单、可以持续不断的扫描获取(同一个设备会被不断的扫描到);老的则分为两步:第一步是每次扫描到一次新设备都会有一个FOUND事件、最后停止扫描了还有个FINISH事件,这里我在FINISH事件结束时发出一个msg来通知进行其他操作。


    4、权限文件配置

    新的:

    <uses-permission a:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission a:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission a:name="android.permission.BLUETOOTH"/>
    <uses-permission a:name="android.permission.BLUETOOTH_ADMIN"/>
    <uses-feature a:name="android.hardware.bluetooth_le" a:required="true"/>
    

    老的:

    <uses-permission a:name="android.permission.BLUETOOTH" />
    <uses-permission a:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission a:name="android.permission.ACCESS_COARSE_LOCATION" />
    

    可见: 相差不大,新的比老的多了bluetooth_le说明。


    5、最后说明

    当你尝试使用BLE SCAN之后,你会感觉有一种飞一般的感觉,几乎同一个设备每一秒都会被扫描到多次。拿这些高频扫描的大量数据,就可以做类似beacon、距离估算、定位等小应用了!效果会比老的scan方法要好很多~


    [1]. 本项目GITHUB链接地址
    [2]. 在Linux下搭建安卓APP的开发烧写环境(makefile版)—— 在Linux上用命令行+VIM开发安卓APP
    [3]. android developer TextView
    [4]. android developer Vector
    [5]. android developer String
    [6]. android developer Formatter
    [7]. android developer Matcher
    [8]. android developer Pattern
    [9]. 等宽字体-Android 设置字体的三种方法(TypeFace)
    [10]. Android 设置TextView滑动滚动条和滑动效果


    @beautifulzzzz
    智能硬件、物联网,热爱技术,关注产品
    博客:http://blog.beautifulzzzz.com
    园友交流群:414948975
    
  • 相关阅读:
    Oracle的基本语法(增删改查)
    Oracle存储过程的学习
    Oracle创建联合主键
    Oracle查询当前用户的信息
    Oracle给创建函数的权限
    Oracle给存储过程权限及触发器
    Unity3D脚本的生命周期(执行顺序)
    Unity性能优化的N种武器
    序列化、反序列化(Serializable特性)
    Unity 读取资源(图片)
  • 原文地址:https://www.cnblogs.com/zjutlitao/p/10100212.html
Copyright © 2011-2022 走看看