赞
踩
注意的问题
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设备多的时候,容易导致底层堵塞
这个方法用到广播。
所以先定义一个类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()); } } } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。