BigFace222 2020-03-26 21:42 采纳率: 0%
浏览 303

写Android BLE程序测试发现无法发现设备,请问怎么解决?

代码如下:
1.MainActivity部分

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private BluetoothAdapter mBluetoothAdapter;
    private RecyclerView mRecyclerView;
    private ScanResultAdapter mScanResultAdapter;
    private BluetoothLeScanner mBluetoothLeScanner;
    private Button mStartScaleButton,mStopScaleButton;
    private static final int REQUEST_CODE_ACCESS_COARSE_LOCATION = 1;   //动态申请权限
    private static final int SCAN_START = 1000;             //开始搜索
    private static final int SCAN_TIME = 10 * 1000;         //扫描时间
    private static final String TAG = "BLE";
    private List<ScanResult> mList = new ArrayList<>();
    private List<String> mListAddress = new ArrayList<>();

    private Handler mHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(@NonNull Message msg) {
            switch (msg.what){
                case SCAN_START:
                    scanBluetooth(false);
            }
            return false;
        }
    });

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        SetOnClickListener();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//如果 API level 是大于等于 23(Android 6.0) 时
            //判断是否具有权限
            if (ContextCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                //判断是否需要向用户解释为什么需要申请该权限
                if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                        Manifest.permission.ACCESS_COARSE_LOCATION)) {
                    Toast.makeText(MainActivity.this, "自Android 6.0开始需要打开位置权限才可以搜索到Ble设备", Toast.LENGTH_LONG).show();
                }
                //请求权限
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                        REQUEST_CODE_ACCESS_COARSE_LOCATION);
            }
        }
    }
    private void initView(){
        /*找到控件*/
        mStartScaleButton = findViewById(R.id.bt_1);
        mStopScaleButton = findViewById(R.id.bt_2);
        mRecyclerView = findViewById(R.id.rv_1);
        mRecyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL));
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mScanResultAdapter = new ScanResultAdapter(this,mList);
        mRecyclerView.setAdapter(mScanResultAdapter);

       mScanResultAdapter.setOnItemClickListener(new ScanResultAdapter.OnItemClickListener() {
           @Override
           public void OnClick(int position) {
                scanBluetooth(false);
                ScanResult scanResult = mList.get(position);
           }
       });
        /*获取本地蓝牙适配器*/
        BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();
        mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();

        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            Toast.makeText(this, "设备不支持BLE", Toast.LENGTH_SHORT).show();
            finish();
        }
        /*打开蓝牙*/
        if(mBluetoothAdapter == null ||!mBluetoothAdapter.isEnabled()){
            Intent TrunOnBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(TrunOnBtIntent,0);
        }
    }

    /*控件点击事件*/
    private void SetOnClickListener(){
        mStartScaleButton.setOnClickListener(this);
        mStopScaleButton.setOnClickListener(this);
    }

    /*对应控件执行相关操作*/
    @Override
    public void onClick(View v){
        switch (v.getId()){
            case R.id.bt_1:
                scanBluetooth(true);
                Toast.makeText(MainActivity.this,"扫描",Toast.LENGTH_LONG).show();
                break;
            case R.id.bt_2:
                scanBluetooth(false);
                break;
        }
    }
    /*开始搜索设备及停止搜索设备函数*/
    private void scanBluetooth(boolean isSan){
        if(isSan==true){
            mBluetoothLeScanner.startScan(mScanCallback);
            mHandler.sendEmptyMessageDelayed(SCAN_START,SCAN_TIME);//定时搜索蓝牙设备
        }else {
            mBluetoothLeScanner.stopScan(mScanCallback);
            if(mHandler.hasMessages(SCAN_START)){
                mHandler.removeMessages(SCAN_START);
            }
        }
    }
    /*搜索的回调函数*/
    private ScanCallback mScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            Log.i(TAG,"result:" + result + "callbackType:" + callbackType);
            /*通过扫描到的设备地址与新扫描的地址作比较,避免重复*/
            if(!mListAddress.contains(result.getDevice().getAddress())){
                mList.add(result);
                mListAddress.add(result.getDevice().getAddress());
            }
            super.onScanResult(callbackType, result);
        }
        @Override
        /*扫描失败的处理*/
        public void onScanFailed(int errorCode){
            Log.e(TAG,"onScanFailed:" + errorCode);
        }
    };

}

2.ScanResultAdapter部分

public class ScanResultAdapter extends RecyclerView.Adapter<ScanResultAdapter.ViewHolder> {
    private Context mContext;
    private List<ScanResult> mList;
    private LayoutInflater inflater;
    private OnItemClickListener onItemClickListener;
    public ScanResultAdapter(Context mContext,List<ScanResult>mList){
        this.mContext = mContext;
        this.mList = mList;
        inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }
    public void setOnItemClickListener(OnItemClickListener onItemClickListener){
        this.onItemClickListener = onItemClickListener;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        return new ViewHolder(inflater.from(mContext).inflate(R.layout.layout_scanadapter_item,parent,false));
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
        ScanResult scanResult = mList.get(position);
        holder.tv_name.setText("设备名:"+scanResult.getDevice().getName());
        holder.tv_address.setText("设备地址:"+scanResult.getDevice().getAddress());
        holder.tv_rssi.setText("信号:"+scanResult.getRssi());
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(null != onItemClickListener){
                    onItemClickListener.OnClick(position);
                }
            }
        });
    }

    @Override
    public int getItemCount() {
        return mList.size();
    }
    public class ViewHolder extends RecyclerView.ViewHolder{
        private TextView tv_name;
        private TextView tv_address;
        private TextView tv_rssi;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            tv_name = itemView.findViewById(R.id.tv_name);
            tv_address = itemView.findViewById(R.id.tv_address);
            tv_rssi = itemView.findViewById(R.id.tv_rssi);
        }
    }
    public interface OnItemClickListener{
        void OnClick(int position);
    }
}

另:测试手机为小米mix2s,SDK版本为29

  • 写回答

1条回答 默认 最新

  • 有头发的猿 2020-03-27 10:48
    关注

    低功耗扫描你确保两点:
    1、位置权限同意后再去扫描。
    2.添加过滤扫描,因为现在Android对高功耗的要求越来越严格,不添加过滤,对功耗消费太大了,也很有可能不允许。
    通过 ScanFilter 去过滤name 或者address 试试。

    评论

报告相同问题?

悬赏问题

  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大
  • ¥15 import arcpy出现importing _arcgisscripting 找不到相关程序