web-dev-qa-db-fra.com

Android - La découverte Bluetooth ne trouve aucun périphérique

Je travaille actuellement sur une petite application pour commencer à utiliser les services que l'API Bluetooth Android peut fournir.

Éditer -> Répondre:

Il semble que le problème soit dû aux périphériques spécifiques du Nexus 5. On dirait que leur récepteur Bluetooth ne fonctionne pas bien. La solution ci-dessous devrait fonctionner pour d'autres appareils

Remarque:

  1. J'ai lu la documentation ici: http://developer.Android.com/guide/topics/connectivity/bluetooth.html ainsi que le code source suivant de ce tutoriel http: //www.londatiga.net/it/programming/Android/how-to-programmatically-scan-or-discover-Android-bluetooth-device/ situé sur github sous/lorensiuswlt/AndroBluetooth

  2. J’ai terminé presque toutes les fonctionnalités qui m’intéressaient (vérification de l’existence de l’adaptateur, activation/désactivation du Blueooth, interrogation de divis appariés, définition de l’adaptateur détectable).

Problème:

En fait , aucun périphérique n'est trouvé lorsque je lance la méthode .onDiscovery (), même si des périphériques sont détectés à partir de Paramètres/Bluetooth sur mon Nexus 5.

Voici comment je le gère:

public class MainActivity extends AppCompatActivity {
private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

...

protected void onCreate(Bundle savedInstanceState) {
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mReceiver, filter); 
}

Le filtre fonctionne bien autant que j'ai pu essayer, à savoir ACTION_STATE_CHANGED (sur l'activation de Bluetooth) et les deux ACTION_DISCOVERY _ ***.

La méthode suivante est ensuite appelée avec succès:

public void onDiscovery(View view)
{
    mBluetoothAdapter.startDiscovery();
}

Et puis j'ai mon récepteur Bluetooth:

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

        if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
            final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);

            if (state == BluetoothAdapter.STATE_ON) {
                showToast("ACTION_STATE_CHANGED: STATE_ON");
            }
        }

        else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
            mDeviceList = new ArrayList<>();
            showToast("ACTION_DISCOVERY_STARTED");
            mProgressDlg.show();
        }

        else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action) && !bluetoothSwitchedOFF) {
            mProgressDlg.dismiss();
            showToast("ACTION_DISCOVERY_FINISHED");

            Intent newIntent = new Intent(MainActivity.this, DeviceListActivity.class);

            newIntent.putParcelableArrayListExtra("device.list", mDeviceList);

            startActivity(newIntent);
        }

        else if (BluetoothDevice.ACTION_FOUND.equals(action)) {// When discovery finds a device
            // Get the BluetoothDevice object from the Intent
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            mDeviceList.add(device);
            showToast("Device found = " + device.getName());
        }
    }
};

Je n'ai aucun problème à sortir du logcat et je n'ai remarqué aucun problème lors du test que j'ai fait. Le seul problème est que aucun périphérique n'est découvert à la fin de l'analyse, lorsque de nombreux périphériques détectables sont disponibles.

J'ai essayé de ne pas mettre trop de code afin de ne pas submerger le sujet. Demande-moi si tu as besoin de plus.

Merci de m'avoir lu et merci d'avance pour vos réponses.

38
Amesys

Quelle version de Android utilisez-vous cette application? Si c'est Android 6.x, je pense que vous devez ajouter le ACCESS_COURSE_LOCATION permission à votre manifeste. Par exemple:

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

J'ai eu un problème similaire et cela a résolu le problème pour moi.

UPDATE: Ajout de documentation directe de Google à ce sujet:

Pour accéder aux identifiants matériels des périphériques externes proches via les scans Bluetooth et Wi-Fi, votre application doit maintenant disposer du ACCESS_FINE_LOCATION ou ACCESS_COARSE_LOCATION autorisations

71
nverbeek

Peu en retard à la fête, mais cela peut être utile pour d'autres personnes.

Vous devez faire deux choses

  1. Ajouter <uses-permission Android:name="Android.permission.ACCESS_COARSE_LOCATION"/>

ou <uses-permission Android:name="Android.permission.ACCESS_FINE_LOCATION"/>

à votre AndroidManifest.xml

  1. Assurez-vous également que vous demandez l'autorisation au moment de l'exécution pour Android 6.0 Périphériques en utilisant quelque chose comme ceci

    int MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION = 1; 
    ActivityCompat.requestPermissions(this,
            new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
            MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION);
    

    juste avant mBluetoothAdapter.startDiscovery();

Si vous ne procédez pas à l'étape 2, vous ne pourrez obtenir aucune information d'identification matérielle sur le périphérique avec Android> = 6.0

PDATE/EDIT:
Exemple avec Android Vérification de la version et boîte de dialogue d’alerte en guise d’avertissement

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {  // Only ask for these permissions on runtime when running Android 6.0 or higher
    switch (ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.ACCESS_COARSE_LOCATION)) {
        case PackageManager.PERMISSION_DENIED:
            ((TextView) new AlertDialog.Builder(this)
                    .setTitle("Runtime Permissions up ahead")
                    .setMessage(Html.fromHtml("<p>To find nearby bluetooth devices please click \"Allow\" on the runtime permissions popup.</p>" +
                            "<p>For more info see <a href=\"http://developer.Android.com/about/versions/Marshmallow/Android-6.0-changes.html#behavior-hardware-id\">here</a>.</p>"))
                    .setNeutralButton("Okay", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            if (ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                                ActivityCompat.requestPermissions(DeviceListActivity.this,
                                        new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                                        REQUEST_ACCESS_COARSE_LOCATION);
                            }
                        }
                    })
                    .show()
                    .findViewById(Android.R.id.message))
                    .setMovementMethod(LinkMovementMethod.getInstance());       // Make the link clickable. Needs to be called after show(), in order to generate hyperlinks
            break;
        case PackageManager.PERMISSION_GRANTED:
            break;
    }
}
60
Nils