Bluetooth in 6.01 seems to be not working as expected with the following code and permissions as per update + appCompat for Kitkat 4.4.4.
No results are being returned and I have several discoverable devices in the vicinity.
Anyone have any insight as per why? I am running on a Nexus 5.
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
package bluetoothscanneractivity;
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.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
public class BluetoothScannerActivity extends Activity {
//private final BroadcastReceiver FoundReceiver = null;
protected ArrayList<BluetoothDevice> foundDevices = new ArrayList<BluetoothDevice>();
private ListView foundDevicesListView;
private ArrayAdapter<BluetoothDevice> btArrayAdapter;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bluetooth_scanner);
final BluetoothAdapter myBlueToothAdapter = BluetoothAdapter.getDefaultAdapter();
final Button scanb = (Button) findViewById(R.id.button);
final ListView foundDevicesListView = (ListView) findViewById(R.id.listView1);
btArrayAdapter = new ArrayAdapter<BluetoothDevice>(this,
android.R.layout.simple_list_item_1, foundDevices);
foundDevicesListView.setAdapter(btArrayAdapter);
//Turn on Bluetooth
if (myBlueToothAdapter == null)
Toast.makeText(BluetoothScannerActivity.this, "Your device doesnot support Bluetooth", Toast.LENGTH_LONG).show();
else if (!myBlueToothAdapter.isEnabled()) {
Intent BtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(BtIntent, 0);
Toast.makeText(BluetoothScannerActivity.this, "Turning on Bluetooth", Toast.LENGTH_LONG).show();
}
//scan
scanb.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
btArrayAdapter.clear();
myBlueToothAdapter.startDiscovery();
Toast.makeText(BluetoothScannerActivity.this, "Scanning Devices", Toast.LENGTH_LONG).show();
}
});
registerReceiver(FoundReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
IntentFilter filter = new IntentFilter(
BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
this.registerReceiver(FoundReceiver, filter);
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
unregisterReceiver(FoundReceiver);
}
private final BroadcastReceiver FoundReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a new device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (!foundDevices.contains(device)) {
foundDevices.add(device);
btArrayAdapter.notifyDataSetChanged();
}
}
// When discovery cycle finished
if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
if (foundDevices == null || foundDevices.isEmpty()) {
Toast.makeText(BluetoothScannerActivity.this, "No Devices", Toast.LENGTH_LONG).show();
}
}
}
};
}
You know that since Marshmallow, you need these permissions for your task -
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Also since Marshmallow, you have to programmatically request for permissions even though you've declared them in your Manifest file.
So you have to request for location permissions before you startDiscovery()
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 1001); //Any number
And after the user accepts these permissions, you can startDiscovery(). And if he/she denies , you cannot discover the devices.
You can check the user action in
onRequestPermissionsResult() callback.
With the added permissions, changing to min SDk version to 23 - it works with the following:
package bluetoothscanneractivity;
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.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import android.Manifest;
import java.util.ArrayList;
public class BluetoothScannerActivity extends AppCompatActivity {
//private final BroadcastReceiver FoundReceiver = null;
protected ArrayList<BluetoothDevice> foundDevices = new ArrayList<BluetoothDevice>();
private ListView foundDevicesListView;
private ArrayAdapter<BluetoothDevice> btArrayAdapter;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bluetooth_scanner);
final BluetoothAdapter myBlueToothAdapter = BluetoothAdapter.getDefaultAdapter();
final Button scanb = (Button) findViewById(R.id.button);
final ListView foundDevicesListView = (ListView) findViewById(R.id.listView1);
btArrayAdapter = new ArrayAdapter<BluetoothDevice>(this,
android.R.layout.simple_list_item_1, foundDevices);
foundDevicesListView.setAdapter(btArrayAdapter);
//Turn on Bluetooth
if (myBlueToothAdapter == null)
Toast.makeText(BluetoothScannerActivity.this, "Your device doesnt support Bluetooth", Toast.LENGTH_LONG).show();
else if (!myBlueToothAdapter.isEnabled()) {
Intent BtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(BtIntent, 0);
Toast.makeText(BluetoothScannerActivity.this, "Turning on Bluetooth", Toast.LENGTH_LONG).show();
}
// Quick permission check
int permissionCheck = this.checkSelfPermission("Manifest.permission.ACCESS_FINE_LOCATION");
permissionCheck += this.checkSelfPermission("Manifest.permission.ACCESS_COARSE_LOCATION");
if (permissionCheck != 0) {
this.requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 1001); //Any number
}
scanb.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
btArrayAdapter.clear();
myBlueToothAdapter.startDiscovery();
Toast.makeText(BluetoothScannerActivity.this, "Scanning Devices", Toast.LENGTH_LONG).show();
}
});
registerReceiver(FoundReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
IntentFilter filter = new IntentFilter(
BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
this.registerReceiver(FoundReceiver, filter);
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
unregisterReceiver(FoundReceiver);
}
private final BroadcastReceiver FoundReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a new device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (!foundDevices.contains(device)) {
foundDevices.add(device);
Toast.makeText(BluetoothScannerActivity.this, "name: " + device.getName() + " " + device.getAddress(), Toast.LENGTH_LONG).show();
btArrayAdapter.notifyDataSetChanged();
}
}
// When discovery cycle finished
if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
if (foundDevices == null || foundDevices.isEmpty()) {
Toast.makeText(BluetoothScannerActivity.this, "No Devices", Toast.LENGTH_LONG).show();
}
}
}
};
}
The method below will only execute if the SDK version is > LOLLIPOP. When I tried to use it without this restriction my app crashed. Simply call this method just before you use .startDiscovery();
public void checkBTPermissions(){
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP){
int permissionCheck = this.checkSelfPermission("Manifest.permission.ACCESS_FINE_LOCATION");
permissionCheck += this.checkSelfPermission("Manifest.permission.ACCESS_COARSE_LOCATION");
if (permissionCheck != 0) {
this.requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 1001); //Any number
}
}else{
Log.d(TAG, "checkBTPermissions: No need to check permissions. SDK version < LOLLIPOP.");
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With