且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

扫描 BLE 设备后不调用 Android BLE 扫描回调

更新时间:2022-10-18 07:52:24

最后,我修改了我的代码,所以代码现在可以工作.这是:

ScanAndPairActivity.java(我正在创建一个用于扫描和配对 BLE 设备的新活动):

package com.example.ui.scanandpair;导入 androidx.annotation.NonNull;导入 androidx.appcompat.app.AppCompatActivity;导入 androidx.core.content.ContextCompat;导入 androidx.recyclerview.widget.LinearLayoutManager;导入 android.Manifest;导入 android.app.Activity;导入 android.app.AlertDialog;导入 android.bluetooth.BluetoothAdapter;导入 android.bluetooth.le.BluetoothLeScanner;导入 android.bluetooth.le.ScanCallback;导入 android.bluetooth.le.ScanFilter;导入 android.bluetooth.le.ScanResult;导入 android.bluetooth.le.ScanSettings;导入 android.content.DialogInterface;导入 android.content.Intent;导入 android.content.pm.PackageManager;导入 android.os.Build;导入 android.os.Bundle;导入 android.os.Handler;导入 android.util.Log;导入 android.view.View;导入 android.widget.Toast;导入 com.example.R;导入 com.example.databinding.ActivityScanAndPairBinding;导入 com.example.entity.BLEDeviceEntity;导入 java.util.ArrayList;导入 java.util.List;公共类 ScanAndPairActivity 扩展 AppCompatActivity {//一般的String TAG = getClass().getSimpleName();ActivityScanAndPairBinding 绑定;//蓝牙int REQUEST_ENABLE_BT = 1;布尔 isScanning = false;蓝牙适配器蓝牙适配器;BluetoothLeScanner bluetoothLeScanner;ScanAndPairAdapter scanAndPairAdapter;列表bleDeviceEntityList;@覆盖protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);绑定 = ActivityScanAndPairBinding.inflate(getLayoutInflater());setContentView(binding.getRoot());android10BluetoothPermission();scanAndPairAdapter = new ScanAndPairAdapter(this);bleDeviceEntityList = new ArrayList();}//蓝牙权限来源:https://developer.android.com/guide/topics/connectivity/bluetooth/permissions#java//检查 Android 10 的蓝牙权限私人无效android10BluetoothPermission(){boolean isLocationPermissionRequired = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N;boolean isBGLocationAccessNotGranted = false;如果 (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {isBGLocationAccessNotGranted = ContextCompat.checkSelfPermission(这,Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED;}boolean isLocationAccessNotGranted = ContextCompat.checkSelfPermission(这,Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED;如果(isLocationPermissionRequired && isBGLocationAccessNotGranted && isLocationAccessNotGranted){requestLocationPermission();}别的 {设置蓝牙();}}私有无效 requestLocationPermission() {如果 (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {如果(shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)){AlertDialog.Builder alertDialogBu​​ilder = new AlertDialog.Builder(this);警报对话框构建器.setTitle(getString(R.string.izinkan_lokasi)).setMessage(getString(R.string.mohon_izinkan_aplikasi_mengakses_lokasi)).setPositiveButton(getString(R.string.ya), new DialogInterface.OnClickListener() {@覆盖public void onClick(DialogInterface dialog, int which) {makeLocationRequest();}});alertDialogBu​​ilder.show();} 别的 {makeLocationRequest();}}}私有无效 makeLocationRequest() {如果 (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {请求权限(新字符串[]{android.permission.ACCESS_FINE_LOCATION"},101);}}//请求许可结果@覆盖public void onRequestPermissionsResult(int requestCode, @NonNull String[] 权限, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);开关(请求代码){案例101:if (grantResults.length != 0 && grantResults[0] == 0) {设置蓝牙();}休息;默认:Toast.makeText(this, getString(R.string.maaf_izin_lokasi_harus_disetujui), Toast.LENGTH_LONG).show();}}私有无效 setUpBluetooth() {bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();检查蓝牙(蓝牙适配器);启用蓝牙(这个,蓝牙适配器);bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();scanBLEDevices(bluetoothLeScanner);}//设置蓝牙的来源:https://developer.android.com/guide/topics/connectivity/bluetooth/setup#java//获取蓝牙适配器private void checkBluetooth (BluetoothAdapter bluetoothAdapter) {如果(蓝牙适配器 == 空){Log.d(TAG,蓝牙:"+蓝牙适配器为空");}别的 {Log.d(TAG,蓝牙:"+蓝牙是适配器不为空");}}//启用蓝牙private void enableBluetooth(活动活动,BluetoothAdapter bluetoothAdapter){Log.d(TAG, "蓝牙:"+"蓝牙适配器已启用:"+ bluetoothAdapter.isEnabled());如果 (!bluetoothAdapter.isEnabled()) {Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);activity.startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);Log.d(TAG,蓝牙:"+蓝牙已启用");}别的 {Log.d(TAG,蓝牙:"+蓝牙已启用");}}//查找 BLE 设备的来源:https://developer.android.com/guide/topics/connectivity/bluetooth/find-ble-devices#java//扫描BLE设备private void scanBLEDevices (BluetoothLeScanner bluetoothLeScanner) {showProgressBar();int SCAN_DURATION = 5000;如果(!isScanning){Handler handler = new Handler();handler.postDelayed(new Runnable() {@覆盖公共无效运行(){isScanning = false;bluetoothLeScanner.stopScan(bleScanCallback);Log.d(TAG,ScanBLEDevices:"+停止扫描");populateDataToRecyclerView();}}, SCAN_DURATION);isScanning = true;showProgressBar();bluetoothLeScanner.startScan(buildScanFilters(), buildScanSettings(), bleScanCallback);Log.d(TAG,ScanBLEDevices:"+开始扫描");}别的 {isScanning = false;bluetoothLeScanner.stopScan(bleScanCallback);Log.d(TAG,ScanBLEDevices:"+停止扫描");populateDataToRecyclerView();}}私有无效 showProgressBar() {binding.recylerViewFilm.setVisibility(View.GONE);binding.progressBar.setVisibility(View.VISIBLE);}私有无效 hideProgressBar() {binding.recylerViewFilm.setVisibility(View.VISIBLE);binding.progressBar.setVisibility(View.GONE);}私有无效 populateDataToRecyclerView() {隐藏进度条();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() {@覆盖公共无效 onItemClicked(BLEDeviceEntity bleDeviceEntity) {Toast.makeText(ScanAndPairActivity.this,尝试连接到"+ bleDeviceEntity.getName(), Toast.LENGTH_SHORT).show();}});}//BLE 扫描回调私人 ScanCallback bleScanCallback = 新 ScanCallback() {@覆盖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));}别的 {for(BLEDeviceEntity bleDeviceEntity : bleDeviceEntityList){if(!bleDeviceEntity.getAddress().equals(deviceAddress)) {bleDeviceEntityList.add(new BLEDeviceEntity(deviceAddress, deviceName));}}}Log.d(TAG, "bleDeviceEntityList: " + bleDeviceEntityList);}};//最新 Android BLE 应用示例的来源:https://github.com/android/connectivity-samples/tree/main/BluetoothAdvertisementsKotlin私有静态列表构建扫描过滤器(){列表scanFilters = new ArrayList();ScanFilter.Builder builder = new ScanFilter.Builder();//注释掉以下行以查看您周围的所有 BLE 设备//builder.setServiceUuid(Constants.Service_UUID);scanFilters.add(builder.build());返回扫描过滤器;}私有静态 ScanSettings buildScanSettings() {ScanSettings.Builder builder = new ScanSettings.Builder();builder.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER);返回 builder.build();}}

感谢大家的帮助,特别感谢 Isaidamier 向我展示示例应用 这里.

I'm creating an Android app that scans all nearby BLE (Bluetooth Low Energy) devices using Android Studio.

I think I have implemented all these documentations:

  1. https://developer.android.com/guide/topics/connectivity/bluetooth/ble-overview
  2. https://developer.android.com/guide/topics/connectivity/bluetooth/permissions#java
  3. https://developer.android.com/guide/topics/connectivity/bluetooth/setup#java
  4. https://developer.android.com/guide/topics/connectivity/bluetooth/find-ble-devices

But as you can see in the log below, (the problem) there are no BLE devices scanned by the app.

Here are the logs in the logcat:

I think it could happen because the BLE scan callback is not called (no BLE scan callback in the log).

So my question is what is the solution for my code? Did I miss coding something?

Here is my code

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);
    }
}

UPDATE

I added this code into android10BluetoothPermission() function in BluetoothHelper.java class but still didn't work.

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
            );
        }

Finally, I have modified my code so the code now is working. Here it is:

ScanAndPairActivity.java (I'm creating a new activity for scanning and pairing BLE devices):

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();
    }
}

Thank you everyone for your help and special thanks to Isaidamier for showing me the example app here.