感谢您的很好的解释。现在我觉得很愚蠢,因为我真的不知道如何让这个工作。
这里是我的清单:
<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"/>
在这里,我的活动:
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());
}
});
}
};
}
我刚刚认识到,hasBlePermissions()始终返回false即便如此清单中的权限正确设置。
更新:得到它的工作。一旦你了解它并不难。首先授予权限,然后扫描设备。这是我在onCreate方法更新的代码:
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);
}
}
检查应用程序的权限。检查SDK 23权限,因为您需要位置权限。确保位置服务处于打开状态。除此之外,请检查您的代码是否正常! – zed
我设置了所有权限,但它无法正常工作。根据这个:https://code.google.com/p/android/issues/detail?id=196485 这似乎是一个问题 – Patricks
这不是一个问题,它的目的是行为,因为BLE设备可以发出地点信息。您必须添加位置服务权限,并且如果您针对API 23+进行构建,则必须在运行时询问权限。 – zed