web-dev-qa-db-fra.com

La numérisation Bluetooth LE ne trouve parfois pas de périphériques

Je recherche des appareils Bluetooth LE et fonctionne en tant que périphérique (exécutant Android 6.0 sur un Moto G 2e génération)

Le problème que j'ai, c'est que parfois (au hasard, mais souvent) il ne trouvera aucun de mes autres périphériques, les autres fois il fonctionne bien.

J'ai un appareil iOS compagnon exécutant un code similaire (à la fois pour la recherche de périphériques et comme périphérique), et lorsque le Android scan ne peut pas trouver l'appareil iOS, mon iOS trouve le Android périphérique fonctionnant très bien comme périphérique. Il semble donc que ce soit uniquement un problème de numérisation.).

Non seulement je ne trouve pas mon appareil iOS compagnon, mais il ne trouve aucun appareil Bluetooth. Quand cela fonctionne, il trouve mon appareil iOS compagnon ainsi qu'un tas d'autres appareils.

Je l'ai essayé avec et sans ScanFilters, et j'obtiens le même problème. Je construis contre SDK 26 avec un SDK minimum de 23.

Je règle les autorisations nécessaires, car cela fonctionne parfois.

Code pertinent ci-dessous:

private void startScanning() {
    mHandler = new Handler(mContext.getMainLooper());

    mHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
            ScanSettings settings = new ScanSettings.Builder()
                                        .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                                        .setReportDelay(0)
                                        .build();

            mBluetoothLeScanner.startScan(null, settings, mScanCallback);
        }
    }, 1000);
}

private ScanCallback mScanCallback = new ScanCallback() {
    @Override
    public void onScanResult(int callbackType, ScanResult result) {
        super.onScanResult(callbackType, result);

        if( result == null || result.getDevice() == null )
            return;

        Log.e("myTest", "Found Device");

        BluetoothDevice device = result.getDevice();
        final String deviceAddress = device.getAddress();

        List<ParcelUuid> parcel = result.getScanRecord().getServiceUuids();

        if (parcel != null) {
            String parcelUUID = parcel.toString().substring(1,37);

            if (parcelUUID.equalsIgnoreCase(mContext.getString(R.string.service_uuid))) {
                final BluetoothDevice bleDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(deviceAddress);

                if (!seenPeripherals.contains(deviceAddress)) {
                    stopScanning();

                    mHandler = new Handler(mContext.getMainLooper());

                    mHandler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            Log.e("AppToApp", "Trying to connect to device " + deviceAddress);

                            mGatt = bleDevice.connectGatt(mContext, false, mGattCallback);
                        }
                    }, 1000);
                }
            }
        }   
    }
}
15
kdbdallas

Je fais face au même problème. En effet, la politique de Google a été modifiée pour l'API Marshmallow 23 et la version supérieure, pour utiliser le besoin de l'utilisateur BLE, tournez SUR GPS. Pour Google Docs, vérifiez ce lien Permission @ Runtime . Pour y remédier, vous devez activer "Localisation" dans les paramètres du téléphone ainsi que l'emplacement de la demande permission dans l'application à Runtime. Les deux doivent être effectués pour que la numérisation fonctionne correctement.

Pour demander l'autorisation de localisation, placez ce qui suit dans une boîte de dialogue ou les goûts:

myActivity.requestPermissions(new String[]{Manifest.permission.ACCESS_COURSE_LOCATION}, yourPermissionRequestCode);

et mettre en œuvre:

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] Results){
    if(requestCode == yourPermissionRequestCode)
    {
        ... //Do something based on Results
    }
}

dans myActivity gère tout ce que l'utilisateur sélectionne. Vous devez également effectuer les opérations suivantes pour activer les services de localisation de votre appareil:

Intent enableLocationIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
myActivity.startActivityForResult(enableLocationIntent, yourServiceRequestCode);

Vous pouvez vérifier si l'utilisateur a activé les services de localisation en implémentant:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    if(requestCode == yourServiceRequestCode)
    {
        ...//Do whatever you need to
    }
}

dans myActivity. Vous pouvez également activer manuellement les services de localisation en procédant comme suit:

Enter phone settings -> Select "Apps" -> Select your app -> Select the "Permissions" option -> Switch the "Location" permission on.

Une fois que l'utilisateur a activé l'autorisation et démarré les services de localisation, vous pouvez commencer à rechercher des périphériques. J'ai remarqué que si vous numérisez déjà pendant que vous activez l'autorisation/activez le service de localisation, il ne mettra toujours rien dans votre onScanResults

Cela permet aux entreprises de voir votre emplacement et de vous diriger là où elles veulent.

pendant la numérisation de l'appareil, une fois que vous êtes connecté à l'appareil BLE, vous pouvez désactiver le service de localisation sur votre téléphone et vous resterez toujours connecté à votre appareil périphérique. Cependant, une fois connecté à un micrologiciel (périphérique), vous ne pouvez plus vous connecter à un nouveau périphérique tant que vous ne déconnectez pas la connexion au périphérique couplé, et tous les autres périphériques de numérisation (mobile) ne peuvent pas voir le nom du périphérique dans leur liste numérisée (lorsque l'utilisateur recherche de périphérique proche) lorsque le périphérique est déjà connecté à un autre périphérique mobile, car un périphérique ne peut être connecté qu'à un seul périphérique à la fois. Pour un exemple de base BLE, vous pouvez vérifier ceci tutoriel Truiton Ble . Je pense que cet extrait résoudra votre problème. Bon codage :)

4
anand krish

Si vous utilisez l'application à des fins non commerciales (ce qui signifie que vous attendez moins de 5 000 utilisateurs), vous pouvez utiliser P2Pkit .

Il utilise une connexion wifi P2P en plus du bluetooth BLE et non BLE, sur les anciennes versions d'Android, et obtient en fait d'excellents résultats sur la découverte des téléphones à proximité.

Les avantages sont que cela fonctionne sur IOS aussi, et il a une interface assez simple.

L'inconvénient est de plus de 5 000 utilisateurs que vous devez payer.

0
eiran

Cette question est liée à quelque chose que je poste avant. Vérifiez ce lien https://stackoverflow.com/a/39084810/399772 et celui-ci https://stackoverflow.com/a/39597845/399772

Vous avez besoin de deux méthodes, l'une pour les anciennes API et l'autre pour les dernières.

Comme pour le SDK 23 et les versions ultérieures, vous devez demander des autorisations d'exécution. Demandez l'autorisation de localisation.

0
Pedro Varela

Il se peut que le téléphone Android possède une puce Bluetooth merdique. Avez-vous consulté le journal hci? Ou logcat?

Les puces Bluetooth 4.0 (qui sont dans votre moto g) ont des limites strictes: vous ne pouvez pas être un central et un périphérique en même temps, même si la numérisation doit être autorisée en tout temps. Par conséquent, je ne ferais pas un produit qui dépend de la fonctionnalité périphérique dans Android jusqu'à ce que BT 4.0 soit supprimé.

Vous devriez tester avec un téléphone plus récent qui possède au moins une puce Bluetooth 4.1.

0
Emil