3

I am trying to list all available devices nearby in a ListView.

My manifest contains the permissions for BLUETOOTH, BLUETOOTH_ADMIN and ACCESS_COARSE_LOCATION.

My problem is ACTION_DISCOVERY_STARTED and ACTION_DISCOVERY_FINISHED are received but ACTION_FOUND is not. I have my computers Bluetooth discoverable and the Bluetooth device on my phone can discover it but my app cannot. Same applies to all devices near.

private BluetoothAdapter mBluetoothAdapter;
private ArrayList<String> mDeviceList;
private ListView mListView;
private ProgressDialog progressDialog;

private static final int REQUEST_ENABLE_BT = 1;

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

    //list to hold all devices found
    mDeviceList = new ArrayList<>();

    //list to display all devices found
    mListView = (ListView) findViewById(R.id.availItems);
    mListView.setAdapter(new ArrayAdapter<>(this,
            android.R.layout.simple_list_item_1, mDeviceList));

    //local bluetooth device
    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

    // If the adapter is null, then Bluetooth is not supported
    if (mBluetoothAdapter == null) {
        Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
    }else if(!mBluetoothAdapter.isEnabled()){
        Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
    }

    Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();

    if (pairedDevices.size() > 0) {
        for (BluetoothDevice device : pairedDevices) {
            mDeviceList.add(device.getName() + "\n" + device.getAddress());
        }
    }

    progressDialog = new ProgressDialog(this);
    progressDialog.setMessage("Scanning...");
    progressDialog.setTitle("Looking for devices...");
    progressDialog.setCancelable(false);
    progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            dialog.dismiss();
        }
    });

    Button findButton = (Button) findViewById(R.id.findButton);
    findButton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            IntentFilter filter = new IntentFilter();

            filter.addAction(BluetoothDevice.ACTION_FOUND);
            filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
            filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);

            registerReceiver(mReceiver, filter);
            mBluetoothAdapter.startDiscovery();
        }
    });
}

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();

        if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
            progressDialog.show();
        }else if (BluetoothDevice.ACTION_FOUND.equals(action) && mBluetoothAdapter.isDiscovering()) {
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            mDeviceList.add(device.getName() + "\n" + device.getAddress());
        }else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
            progressDialog.dismiss();
        }
    }
};

@Override
protected void onResume() {
    super.onResume();
    registerReceiver(mReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
}

@Override
public void onPause() {
    if (mBluetoothAdapter != null) {
        if (mBluetoothAdapter.isDiscovering()) {
            mBluetoothAdapter.cancelDiscovery();
        }
    }

    super.onPause();
}

@Override
public void onDestroy() {
    unregisterReceiver(mReceiver);
    mListView = null;
    mBluetoothAdapter = null;
    mDeviceList = null;

    super.onDestroy();
}
Aaron
  • 175
  • 2
  • 10

1 Answers1

1

As i stated for my own question:

https://stackoverflow.com/posts/comments/63810282?noredirect=1

The problem here was that permission had to be granted at runtime, and not only in the manifest, since ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION are grouped in the DANGEROUS permissions group.

To do so try this:

  1. Request FINE_LOCATION (or coarse location) permission at runtime, since i was working with appcompat, i used ActivityCompat method, but this method can be called easily from Activity subclassess:

    ActivityCompat.requestPermissions(this, new String[{Manifest.permission.ACCESS_FINE_LOCATION},MY_PERMISSION_REQUEST_CONSTANT);
    
  2. Implement onRequestPermissionsResult method:

    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSION_REQUEST_CONSTANT: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    //permission granted!
                }
                return;
            }
        }
    }
    
Community
  • 1
  • 1
Francesco Rizzi
  • 631
  • 6
  • 24
  • Please don't post link only answers to other Stack Overflow questions. Instead, vote/flag to close as duplicate, or, if the question is not a duplicate, *tailor the answer to this specific question.* – Paul Roub Jul 12 '16 at 05:06
  • Sorry, i've never done this before, i tries to find my old question on the flag list but i didn't find it.. can you help me? – Francesco Rizzi Jul 12 '16 at 05:10
  • 1
    Regardless thanks for the direction, the runtime permission was all I needed. Cheers – Aaron Jul 12 '16 at 22:00