2017-02-15 4 views
0

Hier ist das Problem. Ich habe eine App für iOS entwickelt, um ein BLE-LED-Gerät (und ein paar andere Dinge) zu steuern. Alles funktioniert gut und reibungslos. Jetzt wollte ich die gleiche App für Android entwickeln und scheitere bereits beim Scannen von BLE-Geräten. Ich habe ein paar Tutorials und Beispielcodes ausprobiert, aber was immer ich auch mache, ich kann keine Geräte finden. Ich arbeite an einem Moto G4 Play. Das Bluetooth funktioniert und ich kann Geräte in den Einstellungen paaren, aber es funktioniert nicht mit irgendeinem Beispielcode/Tutorial, das ich versucht habe. Zum Beispiel dieses: https://github.com/kaviles/BLE_TutorialsAndroid kann keine BLE-Geräte finden

Ich baue diese App, wie es ist, und es kann nichts finden.

Also habe ich einen BLE-Scanner aus dem Playstore heruntergeladen und das funktioniert gut und findet alle Geräte.

Ich weiß, es ist schwer ohne Beispielcode zu sagen, aber ich habe so viele ausprobiert und ich bin mir nicht sicher, ob ich etwas völlig Grundlegendes vermisse.

+2

Überprüfen Sie die Berechtigungen der Anwendung. Überprüfen Sie die SDK 23-Berechtigungen, da Sie Standortberechtigungen benötigen. Stellen Sie sicher, dass die Standortdienste aktiviert sind. Ansonsten prüfen Sie, ob Ihr Code in Ordnung ist! – zed

+0

Ich setze alle Berechtigungen, aber es wird sowieso nicht funktionieren. Demnach: https://code.google.com/p/android/issues/detail?id=196485 scheint es ein Problem zu sein – Patricks

+0

Dies ist kein Problem, es ist ein beabsichtigtes Verhalten, weil BLE-Geräte ausgeben können Standortinformationen. Sie müssen die Berechtigungen für Standortdienste hinzufügen, und wenn Sie mit API 23+ arbeiten, müssen Sie in Runtime nach Berechtigungen fragen. – zed

Antwort

2

Wie in den Kommentaren besprochen, müssen Sie die Berechtigungen entsprechend einrichten, wenn Ihr ZielSdk 23+ oder andere ist. Die Ortungsdienste müssen eingeschaltet sein.

Manifest Berechtigungen für API 23+:

<uses-permission android:name="android.permission.BLUETOOTH"/> 
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> 
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> 
<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION"/> 
<uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION"/> 

Bluetooth-Berechtigungen zu überprüfen:

public boolean hasBlePermissions() { 
     if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) 
       != PackageManager.PERMISSION_GRANTED || 
       ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) 
         != PackageManager.PERMISSION_GRANTED) { 
      return false; 
     } else { 
      return true; 
     } 
    } 

mit Laufzeitberechtigungen bitten:

public void requestBlePermissions(final Activity activity, int requestCode) { 
    ActivityCompat.requestPermissions(activity, 
      new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 
      requestCode); 
} 

dann die Erteilung Ergebnisse zu überprüfen aus OnRequestPermissionResult:

public boolean checkGrantResults(String[] permissions, int[] grantResults) { 
    int granted = 0; 

    if (grantResults.length > 0) { 
     for(int i = 0; i < permissions.length ; i++) { 
      String permission = permissions[i]; 
      if (permission.equals(Manifest.permission.ACCESS_FINE_LOCATION) || 
        permission.equals(Manifest.permission.ACCESS_COARSE_LOCATION)) { 
       if (grantResults[i] == PackageManager.PERMISSION_GRANTED) { 
        granted++; 
       } 
      } 
     } 
    } else { // if cancelled 
     return false; 
    } 

    return granted == 2; 
} 

prüfen Ortungsdienste:

public boolean areLocationServicesEnabled(Context context) { 
    LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); 
    try { 
     return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || 
       locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return false; 
    } 
} 
1

Vielen Dank für die gute Erklärung. Jetzt fühle ich mich ziemlich dumm, weil ich wirklich nicht weiß, wie ich das funktioniere.

Hier ist mein Manifest:

<uses-permission android:name="android.permission.BLUETOOTH"/> 
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> 
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 
<uses-feature android:name="android.hardware.location.gps" /> 
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/> 

Und hier meine Tätigkeit:

public class LightActivity extends AppCompatActivity { 
private BluetoothAdapter mBluetoothAdapter; 
private boolean mScanning; 
private Handler mHandler; 
private final static int REQUEST_ENABLE_BT = 1; 

// Stops scanning after 10 seconds. 
private static final long SCAN_PERIOD = 10000; 

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

    if(hasBlePermissions() && areLocationServicesEnabled(this)) { 
     final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); 
     mBluetoothAdapter = bluetoothManager.getAdapter(); 

     if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { 
      Toast.makeText(this, "Bluetooth low energy is not supported", Toast.LENGTH_SHORT).show(); 
      finish(); 
     } 

     // Ensures Bluetooth is available on the device and it is enabled. If not, 
     // displays a dialog requesting user permission to enable Bluetooth. 
     if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) { 
      Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 
      startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); 
     } else { 
      scanLeDevice(true); 
     } 
    } 
} 

public boolean hasBlePermissions() { 
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED || 
     ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) { 
     return true; 
    } else { 
     return false; 
    } 
} 

public void requestBlePermissions(final Activity activity, int requestCode) { 
    ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, requestCode); 
} 

public boolean checkGrantResults(String[] permissions, int[] grantResults) { 
    int granted = 0; 

    if (grantResults.length > 0) { 
     for(int i = 0; i < permissions.length ; i++) { 
      String permission = permissions[i]; 
      if (permission.equals(Manifest.permission.ACCESS_FINE_LOCATION) || permission.equals(Manifest.permission.ACCESS_COARSE_LOCATION)) { 
       if (grantResults[i] == PackageManager.PERMISSION_GRANTED) { 
        granted++; 
       } 
      } 
     } 
    } else { // if cancelled 
     return false; 
    } 

    return granted == 2; 
} 

public boolean areLocationServicesEnabled(Context context) { 
    LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); 

    try { 
     return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return false; 
    } 
} 

private void scanLeDevice(final boolean enable) { 
    if (enable) { 


     mScanning = true; 
     mBluetoothAdapter.startLeScan(mLeScanCallback); 
    } else { 
     mScanning = false; 
     mBluetoothAdapter.stopLeScan(mLeScanCallback); 
    } 
} 

// Device scan callback. 
private BluetoothAdapter.LeScanCallback mLeScanCallback = 
     new BluetoothAdapter.LeScanCallback() { 
    @Override 
    public void onLeScan(final BluetoothDevice device, int rssi, 
         byte[] scanRecord) { 
     runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       Log.i("NEW DEVICE", device.getName()); 
      } 
     }); 
    } 
}; 

}

ich, dass nur anerkannte hasBlePermissions() immer false zurück, auch so die Berechtigungen im Manifest sind richtig eingestellt.

UPDATE: Es funktioniert. Sobald Sie es verstehen, ist es nicht so schwer. Erteilen Sie zuerst die Berechtigungen und suchen Sie dann nach dem Gerät.Hier ist meine aktualisierte Code in der onCreate Methode:

int permissionCheck = ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION); 

if (permissionCheck != PackageManager.PERMISSION_GRANTED) { 
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION); 
} else { 
    if(areLocationServicesEnabled(this)) { 
     mHandler = new Handler(); 

     if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { 
      Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show(); 
      finish(); 
     } 

     final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); 
     mBluetoothAdapter = bluetoothManager.getAdapter(); 

     scanLeDevice(true); 
    } 
} 
+0

funktioniert nicht für mich. Bist du sicher, dass dies der Code ist, der für dich funktioniert hat? –

+1

siehe meinen aktualisierten Code oben. Ich hoffe, das ist der wesentliche Teil. Mein Code hat sich seit meinem letzten Post ziemlich geändert, daher hatte ich die Spur zurück, wo das Problem lag. – Patricks

0

Ich verwende das Cordova Plugin cordova-Plugin-ble-Zentrum, die gut mit Android arbeitet. Das Plugin benötigt folgende Berechtigungen:

ACCESS_COARSE_LOCATION

BLUETOOTH

BLUETOOTH_ADMIN

hoffe, das hilft,

0

Für Xamarin, API> = 24 habe ich herausgefunden, wie es funktioniert Es ist möglicherweise nicht intuitiv, dass Sie die COARSE_LOCATION-Berechtigung benötigen, damit Bluetooth funktioniert. Gehe zu dem Projekt auf Xamarin> Rechtsklick> Optionen> Aktivieren Sie die Kontrollkästchen für Bluetooth und Standortberechtigungen> OK -> Rebuild auf Gerät

Verwandte Themen