问题
I am trying to discover devices. I am turning on my laptop's and other Bluetooth devices but discovery can't discover Bluetooth devices. I found a lot of questions about this problem but I could not find solution.
These are the permissions that I am requesting:
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Here is my code:
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);
}
}
The log:
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
I would like to notice that this code is working in android 4.4. I am working on android 7.
回答1:
Coincidentally I had this problem about a week ago.
Try to also add the Coarse Location permission. I have both Fine and Coarse on my application and it works with API 19 (Kit Kat), API 21 (Lollipop), API 23 (Marshmallow), and API 24 (Nougat).
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Also make sure you request the permission before you reach this point in the app. So in onCreate add the following method to make sure your permissions are requested on higher versions of Android. I know I needed to add this code as well to get it working. You can use your own defined int for REQUEST_ID. It will pop up a prompt to the user when you load the app for higher versions of 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);
}
}
来源:https://stackoverflow.com/questions/47641106/can-not-discover-available-bluetooth-devices