Java 蓝牙LE扫描器没有结果

Java 蓝牙LE扫描器没有结果,java,android,android-studio,bluetooth,bluetooth-lowenergy,Java,Android,Android Studio,Bluetooth,Bluetooth Lowenergy,我有这个问题:我正在为LE设备创建一个蓝牙扫描仪应用程序,以便扫描ESP32设备。这个应用程序工作得很好,但在某些设备(比如我自己的设备)中,扫描仪不会给出任何结果。 不用着急,因为我可以在我父亲的手机上测试,基本上已经完成了。问题是它有多令人沮丧,特别是不知道原因 以下是扫描活动: import android.Manifest; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevi

我有这个问题:我正在为LE设备创建一个蓝牙扫描仪应用程序,以便扫描ESP32设备。这个应用程序工作得很好,但在某些设备(比如我自己的设备)中,扫描仪不会给出任何结果。 不用着急,因为我可以在我父亲的手机上测试,基本上已经完成了。问题是它有多令人沮丧,特别是不知道原因

以下是扫描活动:


import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
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.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.content.res.ResourcesCompat;
import androidx.fragment.app.DialogFragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.BaseTransientBottomBar;
import com.google.android.material.snackbar.Snackbar;

import java.util.ArrayList;
import java.util.Objects;

public class ScanActivity extends AppCompatActivity implements ResultsListAdapter.OnResultClickListener {

    private final static int REQUEST_ENABLE_BT = 69;
    private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;
    private static final int SIGNAL_STRENGTH = -75;

    private static boolean scanning = false;
    private ConstraintLayout parent;
    private RecyclerView recyclerView;
    private FloatingActionButton startScanButton, stopScanButton;

    private ArrayList<ScanResult> results = new ArrayList<>();
    private ArrayList<BluetoothDevice> devices = new ArrayList<>();

    private BluetoothManager btManager;
    private BluetoothAdapter btAdapter;
    private BluetoothLeScanner btScanner;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_scan);

        getWindow().setStatusBarColor(ResourcesCompat.getColor(getResources(), R.color.colorAccentDark, null));
        parent = findViewById(R.id.parent_activity_scan);
        recyclerView = findViewById(R.id.scanner_recycler_view);
        startScanButton = findViewById(R.id.start_scan_button);
        stopScanButton = findViewById(R.id.stop_scan_button);

        initRecyclerView();
        startScanButton.setOnClickListener(v -> {
            start();
        });

        stopScanButton.setOnClickListener(v -> {
            stop();
        });

        btManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        btAdapter = Objects.requireNonNull(btManager).getAdapter();
        btScanner = btAdapter.getBluetoothLeScanner();

        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(R.string.coarse_location_access_title);
            builder.setMessage(R.string.coarse_location_access_message);
            builder.setPositiveButton(R.string.concede, null);
            builder.setOnDismissListener(dialog -> requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION));
            builder.show();
        }

    }

    private void start() {
        if (btAdapter != null && !btAdapter.isEnabled()) {
            Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
            stop();
        } else {
            startScanButton.setVisibility(View.INVISIBLE);
            stopScanButton.setVisibility(View.VISIBLE);
            devices.clear();
            results.clear();
            recyclerView.getAdapter().notifyDataSetChanged();
            scan(true);
        }
    }

    private void stop() {
        btScanner.stopScan(leScanCallback);
    }

    private void scan(final boolean enable) {

        if (enable && !scanning) {
            Handler handler = new Handler();
            final Runnable runnable = () -> {
                scanning = false;
                Snackbar.make(parent, "Encontrados " + results.size() + " dispotivos.", BaseTransientBottomBar.LENGTH_LONG)
                        .setAction("", null)
                        .setBackgroundTint(ResourcesCompat.getColor(ScanActivity.this.getResources(), R.color.colorAccentDark, null))
                        .show();
                startScanButton.setVisibility(View.VISIBLE);
                stopScanButton.setVisibility(View.INVISIBLE);
                AsyncTask.execute(() -> btScanner.stopScan(leScanCallback));
            };
            handler.postDelayed(runnable, 7500);
            scanning = true;
            btScanner.startScan(leScanCallback);
        } else {
            scanning = false;
            btScanner.stopScan(leScanCallback);
        }
    }

    private void initRecyclerView() {
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        ResultsListAdapter adapter = new ResultsListAdapter(results, this);
        recyclerView.setAdapter(adapter);
    }

    private final ScanCallback leScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            if (!devices.contains(result.getDevice()) && result.getRssi() > SIGNAL_STRENGTH) {
                new Handler().post(() -> {
                    if (result.getDevice().getAddress().startsWith("A4:CF:12")) {
                        results.add(result);
                        devices.add(result.getDevice());
                        recyclerView.getAdapter().notifyDataSetChanged();
                    }
                });
            }
        }
    };

    @Override
    public void onResultClick(int position) {
        BluetoothDevice device = results.get(position).getDevice();
        DialogFragment dialogFragment = new ConfirmActionDialog();
        Bundle args = new Bundle();
        args.putString("confirm_action_dialog_message",
                "¿Conectar con el dispositivo con dirección " + device.getAddress() + "?");
        args.putInt("type", ConfirmActionDialog.CONNECTION_CODE);
        args.putParcelable("object", device);
        dialogFragment.setArguments(args);
        dialogFragment.show(getSupportFragmentManager(), "Confirm connection");
    }

    @Override
    public void onResultInfoClick(int position) {
        DialogFragment dialogFragment = new InfoDialog();
        Bundle args = new Bundle();
        args.putParcelable("object", results.get(position).getDevice());
        dialogFragment.setArguments(args);
        dialogFragment.show(getSupportFragmentManager(), "InfoDialog");
    }
}

导入android.Manifest;
导入android.bluetooth.BluetoothAdapter;
导入android.bluetooth.bluetooth设备;
导入android.bluetooth.BluetoothManager;
导入android.bluetooth.le.BluetoothLeScanner;
导入android.bluetooth.le.ScanCallback;
导入android.bluetooth.le.ScanResult;
导入android.content.Context;
导入android.content.Intent;
导入android.content.pm.PackageManager;
导入android.os.AsyncTask;
导入android.os.Bundle;
导入android.os.Handler;
导入android.view.view;
导入androidx.appcompat.app.AlertDialog;
导入androidx.appcompat.app.appcompat活动;
导入androidx.constraintlayout.widget.constraintlayout;
导入androidx.core.content.res.ResourcesCompat;
导入androidx.fragment.app.DialogFragment;
导入androidx.recyclerview.widget.LinearLayoutManager;
导入androidx.recyclerview.widget.recyclerview;
导入com.google.android.material.floatingactionbutton.floatingactionbutton;
导入com.google.android.material.snackbar.BaseTransientBottomBar;
导入com.google.android.material.snackbar.snackbar;
导入java.util.ArrayList;
导入java.util.Objects;
公共类ScanActivity扩展AppCompatActivity实现ResultListAdapter.OnResultClickListener{
私有最终静态整数请求\启用\ BT=69;
私有静态最终整数权限\请求\粗略\位置=1;
专用静态最终整数信号强度=-75;
私有静态布尔扫描=false;
私人约束青年父母;
私人回收站;
专用浮动操作按钮开始扫描按钮、停止扫描按钮;
private ArrayList results=new ArrayList();
私有ArrayList设备=新建ArrayList();
私人蓝牙经理;
私人蓝牙适配器;
私人蓝牙扫描仪;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity\u扫描);
getWindow().setStatusBarColor(ResourcesCompat.getColor(getResources(),R.color.colorAccentDark,null));
父项=findViewById(R.id.parent\u activity\u scan);
recyclerView=findViewById(R.id.scanner\u recycler\u视图);
startScanButton=findViewById(R.id.start\u scan\u按钮);
stopScanButton=findViewById(R.id.stop\u scan\u按钮);
initRecyclerView();
startScanButton.setOnClickListener(v->{
start();
});
stopScanButton.setOnClickListener(v->{
停止();
});
btManager=(BluetoothManager)getSystemService(Context.BLUETOOTH\u服务);
btAdapter=Objects.requirennull(btManager.getAdapter();
btScanner=btAdapter.getBluetoothLeScanner();
if(btAdapter!=null&&!btAdapter.isEnabled()){
Intent enableentent=新意图(BluetoothAdapter.ACTION\u REQUEST\u ENABLE);
startActivityForResult(启用意图、请求和启用);
}
if(this.checkSelfPermission(Manifest.permission.ACCESS\u\u LOCATION)!=PackageManager.permission\u已授予){
final AlertDialog.Builder=新建AlertDialog.Builder(此);
builder.setTitle(R.string.rough\u location\u access\u title);
builder.setMessage(R.string.rough\u location\u access\u message);
setPositiveButton(R.string.concept,null);
builder.setOnDismissListener(对话框->requestPermissions(新字符串[]{Manifest.permission.ACCESS\u rough\u LOCATION},permission\u REQUEST\u rough\u LOCATION));
builder.show();
}
}
私有void start(){
if(btAdapter!=null&&!btAdapter.isEnabled()){
Intent enableentent=新意图(BluetoothAdapter.ACTION\u REQUEST\u ENABLE);
startActivityForResult(启用意图、请求和启用);
停止();
}否则{
startScanButton.setVisibility(视图不可见);
stopScanButton.setVisibility(View.VISIBLE);
设备。清除();
结果:清晰();
RecycleView.getAdapter().notifyDataSetChanged();
扫描(真);
}
}
私人停车场(){
btScanner.stopScan(leScanCallback);
}
专用无效扫描(最终布尔启用){
如果(启用&&!扫描){
Handler=newhandler();
最终可运行可运行=()->{
扫描=假;
Snackbar.make(父级,“Encontrados”+results.size()+“dispotivos.”,BaseTransientBottomBar.LENGTH\u LONG)
.setAction(“,null)
.setBackgroundTint(ResourcesCompat.getColor(ScanActivity.this.getResources(),R.color.colorAccentDark,null))
.show();
startScanButton.setVisibility(View.VISIBLE);
stopScanButton.setVisibility(视图不可见);
AsyncTask.execute(()->btScanner.stopScan(leScanCallback));
};
handler.postDelayed(可运行,7500);
扫描=真;
btScanner.startScan(leScanCallback);
}否则{
扫描=假;
btScanner.stopScan(leScanCallback);
}
}
私有void initRecyclerView(){
recyclerView.setLayoutManager(新的LinearLayoutManager(本));
ResultsListAdapter=新的ResultsListAdapter(results,this);
recyclerView.setAdapter(适配器);
}
private final ScanCallback leScanCallback=新建ScanCallback(){
@凌驾
公共无效onScanResult(int callbackType,ScanResu