赞
踩
BluetoothAdapter在Android6.0+以上startDiscovery不能发现蓝牙设备问题
问题的重要原因之一是Android 6.0+,Android 7.0+的权限问题引起的。在Android 4.0+上运行良好的蓝牙代码,在高版本运行异常。比如BluetoothAdapter的startDiscovery虽然启动了发现蓝牙任务,但是不能发现蓝牙设备。解决问题是针对最新高版本的Android系统增加权限申请。现在给出一个完整例子。
activity_main.xml:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- tools:context="zhangphil.bluetooth.MainActivity">
-
- <Button
- android:id="@+id/init"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="初始化蓝牙设备" />
-
- <Button
- android:id="@+id/discovery"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="发现设备" />
-
- <Button
- android:id="@+id/enable_discovery"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="使自身可被其他蓝牙设备发现" />
-
- <ListView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:id="@+id/listView">
- </ListView>
- </LinearLayout>
测试的MainActivity.java:
- package zhangphil.bluetooth;
-
- import android.Manifest;
- import android.app.Activity;
- import android.bluetooth.BluetoothAdapter;
- import android.bluetooth.BluetoothDevice;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.content.pm.PackageManager;
- import android.os.Build;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.View;
- import android.widget.ArrayAdapter;
- import android.widget.ListView;
-
- public class MainActivity extends Activity implements View.OnClickListener {
- private final int REQUEST_ENABLE_BT = 0xa01;
- private final int PERMISSION_REQUEST_COARSE_LOCATION = 0xb01;
-
- private String TAG = "zhangphil";
-
- private ArrayAdapter<String> mAdapter;
- private BluetoothAdapter mBluetoothAdapter;
-
- // 广播接收发现蓝牙设备
- private BroadcastReceiver mReceiver = new BroadcastReceiver() {
-
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
-
- if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
- Log.d(TAG, "开始扫描...");
- }
-
- if (BluetoothDevice.ACTION_FOUND.equals(action)) {
- BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- if (device != null) {
- // 添加到ListView的Adapter。
- mAdapter.add("设备名:" + device.getName() + "\n设备地址:" + device.getAddress());
- mAdapter.notifyDataSetChanged();
- }
- }
-
- if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
- Log.d(TAG, "扫描结束.");
- }
- }
- };
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
- requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
- }
- }
-
-
- // 注册广播接收器。
- // 接收蓝牙发现
- IntentFilter filterFound = new IntentFilter(BluetoothDevice.ACTION_FOUND);
- registerReceiver(mReceiver, filterFound);
-
- IntentFilter filterStart = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
- registerReceiver(mReceiver, filterStart);
-
- IntentFilter filterFinish = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
- registerReceiver(mReceiver, filterFinish);
-
- mAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, android.R.id.text1);
- ((ListView) findViewById(R.id.listView)).setAdapter(mAdapter);
-
- findViewById(R.id.init).setOnClickListener(this);
- findViewById(R.id.discovery).setOnClickListener(this);
- findViewById(R.id.enable_discovery).setOnClickListener(this);
- }
-
- @Override
- public void onClick(View view) {
- switch (view.getId()) {
- case R.id.init:
- init();
-
- case R.id.discovery:
- discovery();
-
- case R.id.enable_discovery:
- enable_discovery();
- }
- }
-
- // 初始化蓝牙设备
- private void init() {
- mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
-
- // 检查设备是否支持蓝牙设备
- if (mBluetoothAdapter == null) {
- Log.d(TAG, "设备不支持蓝牙");
-
- // 不支持蓝牙,退出。
- return;
- }
-
- // 如果用户的设备没有开启蓝牙,则弹出开启蓝牙设备的对话框,让用户开启蓝牙
- if (!mBluetoothAdapter.isEnabled()) {
- Log.d(TAG, "请求用户打开蓝牙");
-
- Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
- startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
- // 接下去,在onActivityResult回调判断
- }
- }
-
- // 启动蓝牙发现...
- private void discovery() {
- if (mBluetoothAdapter == null) {
- init();
- }
-
- mBluetoothAdapter.startDiscovery();
- }
-
- // 可选方法,非必需
- // 此方法使自身的蓝牙设备可以被其他蓝牙设备扫描到,
- // 注意时间阈值。0 - 3600 秒。
- // 通常设置时间为120秒。
- private void enable_discovery() {
- Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
-
- // 第二个参数可设置的范围是0~3600秒,在此时间区间(窗口期)内可被发现
- // 任何不在此区间的值都将被自动设置成120秒。
- discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 3600);
-
- startActivity(discoverableIntent);
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
-
- if (requestCode == REQUEST_ENABLE_BT) {
- if (resultCode == RESULT_OK) {
- Log.d(TAG, "打开蓝牙成功!");
- }
-
- if (resultCode == RESULT_CANCELED) {
- Log.d(TAG, "放弃打开蓝牙!");
- }
-
- } else {
- Log.d(TAG, "蓝牙异常!");
- }
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- unregisterReceiver(mReceiver);
- }
-
-
- @Override
- public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
- switch (requestCode) {
- case PERMISSION_REQUEST_COARSE_LOCATION:
- if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
-
- }
-
- break;
- }
- }
- }
不要忘记增加权限:
- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
- <uses-permission android:name="android.permission.BLUETOOTH" />
- <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
代码运行结果:
以上代码运行测试环境:硬件设备是三星S7Edge,Android版本:7.0
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。