我正在创建一个Android应用程序,该应用程序使用Android Studio扫描所有附近的BLE(蓝牙低功耗)设备。
我想我已经实施了所有这些文件:
但是,正如您在下面的日志中看到的,(问题)应用程序没有扫描任何BLE设备。
以下是日志中的日志:
我认为这可能发生,因为没有调用BLE扫描回调
(日志中没有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>
BluetoothHelper.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);
}
}
我将这段代码添加到< code > bluetooth helper . Java 类中的< code > Android 10 bluetooth permission()函数中,但仍然无法运行。
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
);
}
最后,我修改了我的代码,所以代码现在可以工作了。这是:
ScanAndPairActivity.java(我正在创建一个用于扫描和配对BLE设备的新活动):
package com.example.ui.scanandpair;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import com.example.R;
import com.example.databinding.ActivityScanAndPairBinding;
import com.example.entity.BLEDeviceEntity;
import java.util.ArrayList;
import java.util.List;
public class ScanAndPairActivity extends AppCompatActivity {
// GENERAL
String TAG = getClass().getSimpleName();
ActivityScanAndPairBinding binding;
// BLUETOOTH
int REQUEST_ENABLE_BT = 1;
boolean isScanning = false;
BluetoothAdapter bluetoothAdapter;
BluetoothLeScanner bluetoothLeScanner;
ScanAndPairAdapter scanAndPairAdapter;
List<BLEDeviceEntity> bleDeviceEntityList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityScanAndPairBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
android10BluetoothPermission();
scanAndPairAdapter = new ScanAndPairAdapter(this);
bleDeviceEntityList = new ArrayList<>();
}
// SOURCE FOR BLUETOOTH PERMISSION: https://developer.android.com/guide/topics/connectivity/bluetooth/permissions#java
// CHECK FOR BLUETOOTH PERMISSION FOR ANDROID 10
private void android10BluetoothPermission () {
boolean isLocationPermissionRequired = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N;
boolean isBGLocationAccessNotGranted = false;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
isBGLocationAccessNotGranted = ContextCompat.checkSelfPermission(
this, Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED;
}
boolean isLocationAccessNotGranted = ContextCompat.checkSelfPermission(
this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED;
if (isLocationPermissionRequired && isBGLocationAccessNotGranted && isLocationAccessNotGranted) {
requestLocationPermission();
}
else {
setUpBluetooth();
}
}
private void requestLocationPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder
.setTitle(getString(R.string.izinkan_lokasi))
.setMessage(getString(R.string.mohon_izinkan_aplikasi_mengakses_lokasi))
.setPositiveButton(getString(R.string.ya), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
makeLocationRequest();
}
});
alertDialogBuilder.show();
} else {
makeLocationRequest();
}
}
}
private void makeLocationRequest() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{"android.permission.ACCESS_FINE_LOCATION"}, 101);
}
}
// ON REQUEST PERMISSION RESULT
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch(requestCode) {
case 101:
if (grantResults.length != 0 && grantResults[0] == 0) {
setUpBluetooth();
}
break;
default:
Toast.makeText(this, getString(R.string.maaf_izin_lokasi_harus_disetujui), Toast.LENGTH_LONG).show();
}
}
private void setUpBluetooth() {
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
checkBluetooth(bluetoothAdapter);
enableBluetooth(this, bluetoothAdapter);
bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
scanBLEDevices(bluetoothLeScanner);
}
// SOURCE FOR SET UP BLUETOOTH: https://developer.android.com/guide/topics/connectivity/bluetooth/setup#java
// GET BLUETOOTH ADAPTER
private void checkBluetooth (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
private 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 BLE DEVICES: https://developer.android.com/guide/topics/connectivity/bluetooth/find-ble-devices#java
// SCAN BLE DEVICES
private void scanBLEDevices (BluetoothLeScanner bluetoothLeScanner) {
showProgressBar();
int SCAN_DURATION = 5000;
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");
populateDataToRecyclerView();
}
}, SCAN_DURATION);
isScanning = true;
showProgressBar();
bluetoothLeScanner.startScan(buildScanFilters(), buildScanSettings(), bleScanCallback);
Log.d(TAG, "ScanBLEDevices: " + "start scanning");
}
else {
isScanning = false;
bluetoothLeScanner.stopScan(bleScanCallback);
Log.d(TAG, "ScanBLEDevices: " + "stop scanning");
populateDataToRecyclerView();
}
}
private void showProgressBar() {
binding.recylerViewFilm.setVisibility(View.GONE);
binding.progressBar.setVisibility(View.VISIBLE);
}
private void hideProgressBar() {
binding.recylerViewFilm.setVisibility(View.VISIBLE);
binding.progressBar.setVisibility(View.GONE);
}
private void populateDataToRecyclerView() {
hideProgressBar();
scanAndPairAdapter.setBleDeviceEntityList(bleDeviceEntityList);
scanAndPairAdapter.notifyDataSetChanged();
binding.recylerViewFilm.setLayoutManager(new LinearLayoutManager(ScanAndPairActivity.this));
binding.recylerViewFilm.setHasFixedSize(true);
binding.recylerViewFilm.setAdapter(scanAndPairAdapter);
scanAndPairAdapter.setOnItemClickCallback(new ScanAndPairAdapter.OnItemClickCallback() {
@Override
public void onItemClicked(BLEDeviceEntity bleDeviceEntity) {
Toast.makeText(
ScanAndPairActivity.this, "try to connect to " + bleDeviceEntity.getName(), Toast.LENGTH_SHORT).show();
}
});
}
// BLE SCAN CALLBACK
private ScanCallback bleScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
String deviceAddress = result.getDevice().getAddress();
String deviceName = result.getDevice().getName();
Log.d(TAG, "ScanCallback, deviceAddress: " + deviceAddress + ", deviceName: " + deviceName);
if(bleDeviceEntityList.size() == 0) {
bleDeviceEntityList.add(new BLEDeviceEntity(deviceAddress, deviceName));
}
else {
for(BLEDeviceEntity bleDeviceEntity : bleDeviceEntityList){
if(!bleDeviceEntity.getAddress().equals(deviceAddress)) {
bleDeviceEntityList.add(new BLEDeviceEntity(deviceAddress, deviceName));
}
}
}
Log.d(TAG, "bleDeviceEntityList: " + bleDeviceEntityList);
}
};
// SOURCE FOR LATEST ANDROID BLE APPLICATION SAMPLE: https://github.com/android/connectivity-samples/tree/main/BluetoothAdvertisementsKotlin
private static List<ScanFilter> buildScanFilters() {
List<ScanFilter> scanFilters = new ArrayList<>();
ScanFilter.Builder builder = new ScanFilter.Builder();
// Comment out the below line to see all BLE devices around you
// builder.setServiceUuid(Constants.Service_UUID);
scanFilters.add(builder.build());
return scanFilters;
}
private static ScanSettings buildScanSettings() {
ScanSettings.Builder builder = new ScanSettings.Builder();
builder.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER);
return builder.build();
}
}
感谢大家的帮助,特别感谢Isaidamier在这里向我展示了示例应用程序。
我试图扫描BLE设备与 (我知道它在新版本中已经过时了,但我只是想看看它是否能与我的手机配合使用[4.4],我正在使用它)。因此,它开始扫描,然后继续,没有给出错误,但没有检测到设备。也会触发OnLEScan事件,但其中的设备参数为null。我的LE设备就在那里并已连接。 在Google上,我发现如果BluetoothAdapter没有UUID,就会发生这种情况。如何设置UUID?何时调用/启动O
我有3台Android设备,三星Galaxy S3手机,三星Tab4和Verizon OEM平板电脑。Verizon OEM平板电脑不支持BLE、API 17。我从android开发者网站安装了“BLE设备扫描”,并在Galaxy S3上运行。它只显示Verizon平板电脑是找到的设备。当我在三星Tab4上运行相同的应用程序时,它只显示Galaxy S3作为找到的设备。如果我只看Galaxy S3
我想在我的Android应用程序中被动地扫描BLE广告商, 但我找不到如何做到这一点。 > < li> 根据蓝牙4.0核心规范,存在被动扫描模式。< br >第6卷:核心系统包[低能耗控制器卷],< br > D部分:4.1被动扫描< br > https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=282159 “设备可
我试图用BLE API扫描附近的蓝牙设备,但它似乎不起作用 我已经在清单中添加了权限 以下内容在创建对象时 创建扫描仪回调对象并进一步扫描 在logcat中,我只看到以下内容 这是我的app build gradle } 有人能指出我在这里遗漏了什么吗?
开启蓝牙扫描 参数说明 字段 类型 必须? 说明 blePrefix String 是 设备名称类型前缀 示例代码 Swift: RokidMobileSDK.binder.startBLEScan(blePrefix: String) ->Bool Objc: [RokidMobileSDK.binder startBLEScanWithBlePrefix:@"Rokid-"]; 手机蓝牙未打
扫描设备 介绍 需要传入扫描蓝牙设备的名称的前缀,回调均在主线程。如果传空,是无法获取设备列表。 1、单前缀蓝牙设备 参数说明 字段 类型 必须? 说明 type String 是 设备名称类型前缀 举个大栗子 String type = "Rokid-" RokidMobileSDK.binder.startBTScan(type, new IBTScanCallBack() { @Ov