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);
}
}
Ü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
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
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