无法发现可用的蓝牙设备

时间:2017-12-04 20:02:25

标签: android android-studio bluetooth android-bluetooth

我正在尝试发现设备。我正在打开我的笔记本电脑和其他蓝牙设备,但发现无法发现蓝牙设备。我发现了很多关于这个问题的问题,但我找不到解决方案。

这些是我要求的权限:

<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

这是我的代码:

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.os.Parcelable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;

import java.util.ArrayList;

public class ScanDevicesActivity extends AppCompatActivity {
    private final int REQUEST_ENABLE_BT = 21;
    private final String CUSTOM_INFO = "Custom info";
    private final String CUSTOM_ERROR = "Custom error";

    private boolean receiverIsRegistered = false;

    private BluetoothAdapter bluetoothAdapter;

    private ListView devicesList;
    private BluetoothDevicesAdapter bluetoothDevicesAdapter;
    private ArrayList<FoundBluetoothDeviceInfo> foundDevices = new ArrayList<>();

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

        listConfiguration();

        checkIfBluetoothDeviceIsSupported();
    }

    private void listConfiguration(){
        bluetoothDevicesAdapter = new BluetoothDevicesAdapter(this, android.R.layout.simple_list_item_1, foundDevices);

        //final ConnectThread[] connectThread = new ConnectThread[1];
        devicesList = findViewById(R.id.items_list);
        devicesList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                FoundBluetoothDeviceInfo clickedDevice = (FoundBluetoothDeviceInfo)devicesList.getItemAtPosition(i);
            }
        });
        devicesList.setAdapter(bluetoothDevicesAdapter);
    }

    private void checkIfBluetoothDeviceIsSupported(){
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if(bluetoothAdapter == null){
            Toast.makeText(this, "Bluetooth not supported", Toast.LENGTH_LONG).show();
            finish();
        }
    }

    private void checkIfBluetoothIsEnabled(){
        if (!bluetoothAdapter.isEnabled()){
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
            discoverDevices();
        }else {
            discoverDevices();
        }
    }

    private void discoverDevices(){
        if ((bluetoothAdapter != null) && (bluetoothAdapter.startDiscovery() != false)) {
            // Register for broadcasts when a device is discovered.
            IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
            filter.addAction(BluetoothDevice.EXTRA_UUID);
            filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
            filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
            Log.i(CUSTOM_INFO, "Starting Discovery");
            registerReceiver(mReceiver, filter);
            receiverIsRegistered = true;
        }
    }

    // Create a BroadcastReceiver for ACTION_FOUND.
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            Log.i(CUSTOM_INFO, "ON RECEIVE");
            String action = intent.getAction();
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                // Discovery has found a device. Get the BluetoothDevice
                // object and its info from the Intent.
                Log.i(CUSTOM_INFO, "ACTION_FOUND");
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                String deviceName = device.getName();
                int deviceType = device.getBluetoothClass().getDeviceClass();
                String deviceHardwareAddress = device.getAddress(); // MAC address

                FoundBluetoothDeviceInfo found = new FoundBluetoothDeviceInfo(deviceType, deviceName, deviceHardwareAddress);
                foundDevices.add(found);
                Log.i(CUSTOM_INFO, "Device added to list");
                bluetoothDevicesAdapter.notifyDataSetChanged();
            }else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){
                Log.i(CUSTOM_INFO, "DISCOVERY STARTED");
                if(bluetoothAdapter.startDiscovery())
                    Log.i(CUSTOM_INFO, "TRUE");
                else
                    Log.i(CUSTOM_INFO, "FALSE");
            }else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
                Log.i(CUSTOM_INFO, "DISCOVERY FINISHED");
            }
        }
    };

    public void searchButtonPressed(View view){

        if(receiverIsRegistered){
            this.unregisterReceiver(mReceiver);
            bluetoothAdapter.cancelDiscovery();
            receiverIsRegistered = false;
        }
        checkIfBluetoothIsEnabled();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data){
        if ((requestCode == REQUEST_ENABLE_BT) && (resultCode == RESULT_OK)){
            discoverDevices();
        }else {
            Toast.makeText(this, "Bluetooth is required!", Toast.LENGTH_LONG).show();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        this.unregisterReceiver(mReceiver);
    }
}

日志:

12/04 21:32:26: Launching app
$ adb install-multiple -r -t D:\AndroidProjects\OriginalController\app\build\intermediates\split-apk\debug\slices\slice_8.apk D:\AndroidProjects\OriginalController\app\build\outputs\apk\debug\app-debug.apk D:\AndroidProjects\OriginalController\app\build\intermediates\split-apk\debug\slices\slice_9.apk D:\AndroidProjects\OriginalController\app\build\intermediates\split-apk\debug\dep\dependencies.apk D:\AndroidProjects\OriginalController\app\build\intermediates\split-apk\debug\slices\slice_0.apk D:\AndroidProjects\OriginalController\app\build\intermediates\split-apk\debug\slices\slice_7.apk D:\AndroidProjects\OriginalController\app\build\intermediates\split-apk\debug\slices\slice_2.apk D:\AndroidProjects\OriginalController\app\build\intermediates\split-apk\debug\slices\slice_1.apk D:\AndroidProjects\OriginalController\app\build\intermediates\split-apk\debug\slices\slice_3.apk D:\AndroidProjects\OriginalController\app\build\intermediates\split-apk\debug\slices\slice_6.apk D:\AndroidProjects\OriginalController\app\build\intermediates\split-apk\debug\slices\slice_5.apk D:\AndroidProjects\OriginalController\app\build\intermediates\split-apk\debug\slices\slice_4.apk 
Split APKs installed
$ adb shell am start -n "com.example.tafy.originalcontroller/com.example.tafy.originalcontroller.ScanDevicesActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -D
Waiting for application to come online: com.example.tafy.originalcontroller | com.example.tafy.originalcontroller.test
Waiting for application to come online: com.example.tafy.originalcontroller | com.example.tafy.originalcontroller.test
Waiting for application to come online: com.example.tafy.originalcontroller | com.example.tafy.originalcontroller.test
Waiting for application to come online: com.example.tafy.originalcontroller | com.example.tafy.originalcontroller.test
Connecting to com.example.tafy.originalcontroller
Connected to the target VM, address: 'localhost:8600', transport: 'socket'
Capturing and displaying logcat messages from application. This behavior can be disabled in the "Logcat output" section of the "Debugger" settings page.
I/art: Late-enabling -Xcheck:jni
D/TidaProvider: TidaProvider()
V/BoostFramework: BoostFramework() : mPerf = com.qualcomm.qti.Performance@e8f07f1
I/art: Debugger is no longer active
I/art: Starting a blocking GC Instrumentation
W/ActivityThread: Application com.example.tafy.originalcontroller is waiting for the debugger on port 8100...
I/System.out: Sending WAIT chunk
I/art: Debugger is active
I/System.out: Debugger has connected
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: debugger has settled (1465)
W/System: ClassLoader referenced unknown path: /data/app/com.example.tafy.originalcontroller-1/lib/arm64
I/InstantRun: starting instant run server: is main process
W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
D/AccessibilityManager: current package=com.example.tafy.originalcontroller, accessibility manager mIsFinalEnabled=false, mOptimizeEnabled=true, mIsUiAutomationEnabled=false, mIsInterestedPackage=false
V/BoostFramework: BoostFramework() : mPerf = com.qualcomm.qti.Performance@d229de1
V/BoostFramework: BoostFramework() : mPerf = com.qualcomm.qti.Performance@ddf706
E/HAL: PATH3 /odm/lib64/hw/gralloc.qcom.so
E/HAL: PATH2 /vendor/lib64/hw/gralloc.qcom.so
E/HAL: PATH1 /system/lib64/hw/gralloc.qcom.so
E/HAL: PATH3 /odm/lib64/hw/gralloc.msm8953.so
E/HAL: PATH2 /vendor/lib64/hw/gralloc.msm8953.so
E/HAL: PATH1 /system/lib64/hw/gralloc.msm8953.so
D/ActivityThreadInjector: clearCachedDrawables.
I/Adreno: QUALCOMM build                   : 01d2d27, I3d52eaf367
          Build Date                       : 12/10/16
          OpenGL ES Shader Compiler Version: XE031.09.00.03
          Local Branch                     : 
          Remote Branch                    : 
          Remote Branch                    : 
          Reconstruct Branch               : 
I/OpenGLRenderer: Initialized EGL, version 1.4
D/OpenGLRenderer: Swap behavior 1
W/art: Before Android 4.1, method int android.support.v7.widget.ListViewCompat.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView
I/art: Do partial code cache collection, code=30KB, data=23KB
I/art: After code cache collection, code=28KB, data=22KB
I/art: Increasing code cache capacity to 128KB
V/BoostFramework: BoostFramework() : mPerf = com.qualcomm.qti.Performance@8f3511e
I/Timeline: Timeline: Activity_launch_request time:21042198
I/Custom info: Starting Discovery
I/Custom info: ON RECEIVE
I/Custom info: DISCOVERY STARTED
I/Custom info: TRUE
I/Custom info: ON RECEIVE
I/Custom info: DISCOVERY FINISHED

我想注意这个代码在android 4.4中有效。 我正在研究android 7。

1 个答案:

答案 0 :(得分:3)

巧合的是,一周前我遇到了这个问题。

尝试添加Coarse Location权限。我的应用程序中包含Fine和Coarse,它适用于API 19(Kit Kat),API 21(Lollipop),API 23(Marshmallow)和API 24(Nougat)。

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

此外,请确保在到达应用程序中的此点之前请求权限。因此,在onCreate中添加以下方法以确保在更高版本的Android上请求您的权限。我知道我需要添加此代码以使其正常工作。您可以将自己定义的int用于REQUEST_ID。当您为更高版本的Android加载应用程序时,它会弹出一个提示给用户。

private int androidVersion; //define at top of code as a variable

private void requestPermissions(){
androidVersion = Build.VERSION.SDK_INT;
        if (androidVersion >= 23){
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
                            Manifest.permission.ACCESS_COARSE_LOCATION,                                
                    }, REQUEST_ID);
        }
    }