【发布时间】:2021-06-18 14:06:25
【问题描述】:
我正在创建一个使用 Android Studio 扫描附近所有 BLE(低功耗蓝牙)设备的 Android 应用。
我想我已经实现了所有这些文档:
- https://developer.android.com/guide/topics/connectivity/bluetooth/ble-overview
- https://developer.android.com/guide/topics/connectivity/bluetooth/permissions#java
- https://developer.android.com/guide/topics/connectivity/bluetooth/setup#java
- https://developer.android.com/guide/topics/connectivity/bluetooth/find-ble-devices
但正如您在下面的日志中看到的那样,(问题)应用程序没有扫描到 BLE 设备。
这里是logcat中的日志:
我认为这可能会发生,因为没有调用 BLE scan callback(日志中没有 BLE 扫描回调)。
所以我的问题是我的代码的解决方案是什么?我错过了编码吗?
这是我的代码
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example">
<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-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-feature
android:name="android.hardware.bluetooth_le"
android:required="true" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Example">
<activity android:name=".ui.authentication.signin.SignInActivity" />
<activity android:name=".ui.authentication.signup.SignUpActivity" />
<activity android:name=".ui.home.HomeActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
蓝牙助手.java:
package com.example.util;
import android.Manifest;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler;
import android.util.Log;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
public class BluetoothHelper {
static int REQUEST_ENABLE_BT = 1;
static int PERMISSION_CODE = 1;
static String TAG = "Bluetooth";
static boolean isScanning = false;
// SOURCE FOR BLUETOOTH PERMISSION: https://developer.android.com/guide/topics/connectivity/bluetooth/permissions#java
// CHECK FOR BLUETOOTH PERMISSION FOR ANDROID 10
public static void android10BluetoothPermission (Context context, Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (ContextCompat.checkSelfPermission(context,
Manifest.permission.ACCESS_BACKGROUND_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
activity,
new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION},
PERMISSION_CODE
);
}
}
}
// SOURCE FOR SET UP BLUETOOTH: https://developer.android.com/guide/topics/connectivity/bluetooth/setup#java
// GET BLUETOOTH ADAPTER
public static void setupBluetooth (BluetoothAdapter bluetoothAdapter) {
if (bluetoothAdapter == null) {
Log.d(TAG, "Bluetooth: " + "bluetooth adapter is null");
}
else {
Log.d(TAG, "Bluetooth: " + "bluetooth is adapter not null");
}
}
// ENABLE BLUETOOTH
public static void enableBluetooth (Activity activity, BluetoothAdapter bluetoothAdapter) {
Log.d(TAG, "Bluetooth: " + "bluetooth adapter is enabled: " + bluetoothAdapter.isEnabled());
if (!bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
activity.startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
Log.d(TAG, "Bluetooth: " + "bluetooth is enabled");
}
else {
Log.d(TAG, "Bluetooth: " + "bluetooth is already enabled");
}
}
// SOURCE FOR FIND BLUETOOTH DEVICES: https://developer.android.com/guide/topics/connectivity/bluetooth/find-bluetooth-devices
// QUERY PAIRED DEVICES
public static Set<BluetoothDevice> queryPairedDevices (BluetoothAdapter bluetoothAdapter) {
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
Log.d(TAG, "PairedDevices: " + pairedDevices.toString());
return pairedDevices;
}
// GET ALL NAMES AND MAC ADDRESSES
public static ArrayList<HashMap<String, String>> getNamesAndMacAddresses(Set<BluetoothDevice> bluetoothDevices) {
ArrayList<HashMap<String, String>> arrayList = new ArrayList<>();
if (bluetoothDevices.size() > 0) {
for (BluetoothDevice device : bluetoothDevices) {
String deviceName = device.getName();
String deviceMacAddress = device.getAddress();
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("deviceName", deviceName);
hashMap.put("deviceMacAddress", deviceMacAddress);
arrayList.add(hashMap);
}
}
Log.d(TAG, "NamesAndMacAddress: " + arrayList);
return arrayList;
}
// SOURCE FOR FIND BLE DEVICES: https://developer.android.com/guide/topics/connectivity/bluetooth/find-ble-devices#java
// SCAN BLE DEVICES
public static void scanBLEDevices (BluetoothLeScanner bluetoothLeScanner) {
int SCAN_DURATION = 10000;
if(!isScanning) {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
isScanning = false;
bluetoothLeScanner.stopScan(bleScanCallback);
Log.d(TAG, "ScanBLEDevices: " + "stop scanning");
}
}, SCAN_DURATION);
isScanning = true;
bluetoothLeScanner.startScan(bleScanCallback);
Log.d(TAG, "ScanBLEDevices: " + "start scanning");
}
else {
isScanning = false;
bluetoothLeScanner.stopScan(bleScanCallback);
Log.d(TAG, "ScanBLEDevices: " + "stop scanning");
}
}
// BLE SCAN CALLBACK
private static ScanCallback bleScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
Log.d(TAG, "ScanCallback: " + result.getDevice());
}
};
}
HomeActivity.java:
package com.example.ui.home;
import androidx.appcompat.app.AppCompatActivity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.le.BluetoothLeScanner;
import android.os.Bundle;
import android.view.View;
import com.example.R;
import com.example.databinding.ActivityHomeBinding;
import com.example.util.AuthenticationHelper;
import com.example.util.BluetoothHelper;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
public class HomeActivity extends AppCompatActivity implements View.OnClickListener {
ActivityHomeBinding binding;
Set<BluetoothDevice> pairedDevices;
ArrayList<HashMap<String, String>> arrayList;
BluetoothLeScanner bluetoothLeScanner;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityHomeBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
setUpBluetooth();
binding.buttonKeluar.setOnClickListener(this);
}
@Override
protected void onStart() {
super.onStart();
AuthenticationHelper.checkHasTheUserLoggedIn(this);
}
@Override
public void onClick(View v) {
if(v.getId() == R.id.buttonKeluar) {
AuthenticationHelper.signOutUser(this);
}
}
private void setUpBluetooth() {
BluetoothHelper.android10BluetoothPermission(this, HomeActivity.this);
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothHelper.setupBluetooth(bluetoothAdapter);
BluetoothHelper.enableBluetooth(this, bluetoothAdapter);
pairedDevices = BluetoothHelper.queryPairedDevices(bluetoothAdapter);
arrayList = BluetoothHelper.getNamesAndMacAddresses(pairedDevices);
bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
BluetoothHelper.scanBLEDevices(bluetoothLeScanner);
}
}
更新
我将此代码添加到 BluetoothHelper.java 类中的 android10BluetoothPermission() 函数中,但仍然没有工作。
if (ContextCompat.checkSelfPermission(context,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
activity,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSION_CODE
);
}
if (ContextCompat.checkSelfPermission(context,
Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
activity,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
PERMISSION_CODE
);
}
【问题讨论】:
-
我看到您已授予您的应用使用该位置的权限。但是您通常还必须在运行时请求该权限。有关信息,请参阅此链接:developer.android.com/training/location/permissions 您能否检查您的应用程序实际上是否有权使用该位置?您可以在设置 -> 应用程序 -> 您的应用程序 -> 权限中执行此操作
-
感谢您对@M.Kotzjan 发表评论。现在,我每次调用 BLE
start scan函数时都请求运行时权限,并且我还在运行时添加了精细和粗略的位置。但仍然没有调用scan callback。我在设置中检查了应用程序权限,然后我发现应用程序不允许任何权限,并且权限位置被拒绝。怎么会这样? -
您能否edit您的问题并添加您在运行时请求权限的部分?
-
我想我已经在
android10BluetoothPermission()BluetoothHelper.java@M.Kotzjan 的函数中这样做了 -
我有一个。谢谢你帮助我。我找到了解决方案。我会尽快给出答案。
标签: java android android-studio bluetooth bluetooth-lowenergy