Android BLE 扫描问题
Posted
技术标签:
【中文标题】Android BLE 扫描问题【英文标题】:Android BLE scan issue 【发布时间】:2021-03-06 15:38:17 【问题描述】:我正在尝试在我的 android 手机上创建一个简单的 BLE 应用程序。 我已经尝试了很多没有成功的例子,我必须忘记一些东西。 希望你能帮助我。 首先你会发现添加的权限,然后是我的简单活动
权限:
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
还有我的活动: 两个按钮,一个用于执行扫描,另一个用于停止它。 我想检测一个 BLE 设备,但我的代码从来没有检测到任何东西。
public class MainActivity extends AppCompatActivity
BluetoothManager btManager;
BluetoothAdapter btAdapter;
BluetoothLeScanner btScanner;
Button startScanningButton;
Button stopScanningButton;
TextView peripheralTextView;
private final static int REQUEST_ENABLE_BT = 1;
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
peripheralTextView = (TextView) findViewById(R.id.PeripheralTextView);
peripheralTextView.setMovementMethod(new ScrollingMovementMethod());
startScanningButton = (Button) findViewById(R.id.StartScanButton);
startScanningButton.setOnClickListener(new View.OnClickListener()
public void onClick(View v)
startScanning();
);
stopScanningButton = (Button) findViewById(R.id.StopScanButton);
stopScanningButton.setOnClickListener(new View.OnClickListener()
public void onClick(View v)
stopScanning();
);
stopScanningButton.setVisibility(View.INVISIBLE);
btManager = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
btAdapter = BluetoothAdapter.getDefaultAdapter();
if ( btAdapter == null )
Toast.makeText(
this,
"Bluetooth not supported on this deveice",
Toast.LENGTH_LONG).show();
return;
btScanner = btAdapter.getBluetoothLeScanner();
btScanner = BluetoothAdapter.getDefaultAdapter().getBluetoothLeScanner();
// Ensures Bluetooth is available on the device and it is enabled. If not,
// displays a dialog requesting user permission to enable Bluetooth.
if (btAdapter == null || !btAdapter.isEnabled())
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
if ( ! btAdapter.isEnabled() )
// Demande à activer l'interface bluetooth
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
if ( checkSelfPermission( Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED )
requestPermissions(
new String[] android.Manifest.permission.ACCESS_COARSE_LOCATION ,
456 );
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE))
Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
finish();
if (btAdapter != null && !btAdapter.isEnabled())
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent,REQUEST_ENABLE_BT);
if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("This app needs location access");
builder.setMessage("Please grant location access so this app can detect peripherals.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener()
@Override
public void onDismiss(DialogInterface dialog)
requestPermissions(new String[]Manifest.permission.ACCESS_COARSE_LOCATION, PERMISSION_REQUEST_COARSE_LOCATION);
);
builder.show();
private ScanCallback leScanCallback = new ScanCallback()
@Override
public void onScanResult(int callbackType, ScanResult result)
peripheralTextView.append("Device Name: " + result.getDevice().getName() + " rssi: " + result.getRssi() + "\n");
super.onScanResult(callbackType, result);
final int scrollAmount = peripheralTextView.getLayout().getLineTop(peripheralTextView.getLineCount()) - peripheralTextView.getHeight();
if (scrollAmount > 0)
peripheralTextView.scrollTo(0, scrollAmount);
;
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults)
switch (requestCode)
case PERMISSION_REQUEST_COARSE_LOCATION:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
System.out.println("coarse location permission granted");
else
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Functionality limited");
builder.setMessage("Since location access has not been granted, this app will not be able to discover beacons when in the background.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener()
@Override
public void onDismiss(DialogInterface dialog)
);
builder.show();
return;
private boolean mScanning = false;
private Handler handler = new Handler();
private static final long SCAN_PERIOD = 30000;
public void startScanning()
System.out.println("start scanning");
peripheralTextView.setText("");
startScanningButton.setVisibility(View.INVISIBLE);
stopScanningButton.setVisibility(View.VISIBLE);
if (!mScanning)
// Stops scanning after a pre-defined scan period.
handler.postDelayed(new Runnable()
@Override
public void run()
mScanning = false;
btScanner.stopScan(leScanCallback);
System.out.println("stop scanning");
, SCAN_PERIOD);
mScanning = true;
btScanner.startScan(leScanCallback);
System.out.println("restart scanning");
else
mScanning = false;
btScanner.stopScan(leScanCallback);
System.out.println("stop scanning");
public void stopScanning()
System.out.println("stopping scanning");
peripheralTextView.append("Stopped Scanning");
startScanningButton.setVisibility(View.VISIBLE);
stopScanningButton.setVisibility(View.INVISIBLE);
AsyncTask.execute(new Runnable()
@Override
public void run()
btScanner.stopScan(leScanCallback);
);
我从不扫描任何东西.. 完全是新手,非常感谢您的帮助。
问候
【问题讨论】:
【参考方案1】:您还需要声明 ACCESS_BACKGROUND_LOCATION 才能找到其他蓝牙设备。你可以在这里找到更多信息:-
https://developer.android.com/guide/topics/connectivity/bluetooth#Permissions Bluetooth LE Scan fails in the background - permissions Turn on Android LE scanning without asking user for permission下面的链接对于开始使用 Android LE 开发很有用:-
The Ultimate Guide to Android BLE Development Android Lollipop: Bluetooth LE Matures Bluetooth LE Send String Data between Devices【讨论】:
不,如果您只在应用程序处于前台时使用扫描,则不需要后台位置。您需要在运行时向用户询问 android.permission.ACCESS_FINE_LOCATION 权限。以上是关于Android BLE 扫描问题的主要内容,如果未能解决你的问题,请参考以下文章
检测Android App收到扫描请求时是不是发送BLE扫描响应