android扫描蓝牙信号的小结,startLeScan()方法和startDiscovery()方法

注意的问题
1:添加权限

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

2:添加运行时权限(SDK23以上一定要加,我就是没加怎么都搞不出来,弄了半天,嘤嘤嘤)

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&

        checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&

        checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&

        checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED ) {

    requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION ,

            Manifest.permission.CAMERA,}, 1);
}

**

小结

:**
首先添加手机中已经配对好的蓝牙设备到 mBluetoothAdapter(也可以不用创建BluetoothAdapter对象即可)。

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

方式1,startLeScan()方法

startLeScan()方法有一个回调参数BluetoothAdapter.LeScanCallback 类,先创建这个类的对象,在扫描找到周围的蓝牙设备时,会返回到 onLeScan 函数,可以在 onLeScan 函数中处理逻辑

BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
      @Override
      public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
          mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
          lv_bluetooth.setAdapter(mArrayAdapter);
          Log.d(TAG, "onLeScan:563463 ");
      }
  };

然后再用 startLeScan()方法扫描

mBluetoothAdapter.startLeScan(mLeScanCallback);

startLeScan()方法的特点:在onLeScan() 中不能做耗时操作,特别是周围的BLE设备多的时候,容易导致底层堵塞

方式2,startDiscovery()方法

这个方法用到广播。

所以先定义一个类SingBroadcastReceiver,让他继承自BroadcastReceiver ,并重写onReceive()方法,在该方法中写扫描到设备时的逻辑。

class SingBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (BluetoothDevice.ACTION_FOUND.equals(action) ){
            // Get the BluetoothDevice object from the Intent
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            // Add the name and address to an array adapter to show in a Toast
            String derp = device.getName() + " - " + device.getAddress();
            Toast.makeText(context, derp, Toast.LENGTH_LONG).show();
        }
    }
}

然后创建SingBroadcastReceiver对象,注册广播,再执行startDiscovery()方法

SingBroadcastReceiver mReceiver=new SingBroadcastReceiver ();
 mBluetoothAdapter.startDiscovery();
 IntentFilter ifilter1= new IntentFilter(BluetoothDevice.ACTION_FOUND);
  registerReceiver(mReceiver, ifilter1);

对于经典蓝牙设备,扫描是通过调用startDiscovery接口,返回的结果是通过BroadcastReceiver接收的,可以获取设备MAC地址,名称以及RSSI。startDiscovery是个异步调用,会立即返回。如果不调用cancelDiscovery主动停止扫描的话,最多扫描12s。广播主要监听以下几个Action:BluetoothDevice.ACTION_FOUNDBluetoothAdapter.ACTION_DISCOVERY_STARTEDBluetoothAdapter.ACTION_DISCOVERY_FINISHED另外要注意startDiscovery返回的设备不包括已配对设备,如要获取已配对设备,需要额外调用getBondedDevices。

例子

我比较喜欢用startDiscovery(),所以是用这个startDiscovery()写的。

public class MainActivity extends AppCompatActivity {
    private ListView lv_bluetooth;//用于显示蓝牙设备
    private SingBroadcastReceiver mReceiver;//这个我自定义的一个广播接收器
    private  ArrayAdapter<String> mArrayAdapter;//一个简单的适配器
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //实例化
        lv_bluetooth=findViewById(R.id.lv_bluetooth);
        Button button_find=findViewById(R.id.find);
        Button button_cancel=findViewById(R.id.cancel);
        mArrayAdapter=new ArrayAdapter<String >(
                MainActivity.this,android.R.layout.simple_list_item_1
        );
        //运行时权限
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&

                checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&

                checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&

                checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED ) {

            requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION ,

                    Manifest.permission.CAMERA,}, 1);
        }
       final  BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        //注册广播
        mReceiver = new SingBroadcastReceiver();
        IntentFilter ifilter1= new IntentFilter(BluetoothDevice.ACTION_FOUND);
        registerReceiver(mReceiver, ifilter1);
        //扫描
        button_find.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mBluetoothAdapter.startDiscovery();
                    lv_bluetooth.setAdapter(mArrayAdapter);
                }
            });
        //停止扫描
        button_cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mBluetoothAdapter.cancelDiscovery();
            }
        });
        }
    //广播接收器
    class SingBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (BluetoothDevice.ACTION_FOUND.equals(action) ){
                // Get the BluetoothDevice object from the Intent
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                //下面的代码的效果是不让已经扫描到的设备重复显示

               Boolean isRepetition=false;
                for(int i=0;i<mArrayAdapter.getCount();i++)
                {
                    if((device.getName()+"-"+device.getAddress()).equals(mArrayAdapter.getItem(i).toString()))
                    {
                        isRepetition=true;
                    }
                }
                if(!isRepetition){
                    mArrayAdapter.add(device.getName()+"-"+device.getAddress());
                }
            }
        }
    }
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值