#android #android-permissions #android-location
Вопрос:
Я работаю над приложением для Android, которому требуется местоположение пользователя, каждый раз, когда пользователь входит в приложение.
Я написал код для определения местоположения пользователя и отлично работает, но проблема в том, что если пользователь дважды отказывает в разрешении, он больше не спрашивал, вот мой код:
public class MainActivity extends AppCompatActivity {
String myLocation = "";
private LocationRequest locationRequest;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(5000);
locationRequest.setFastestInterval(2000);
getCurrentLocation();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (isGPSEnabled()) {
getCurrentLocation();
} else {
turnOnGPS();
}
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 2) {
if (resultCode == Activity.RESULT_OK) {
getCurrentLocation();
}
}
}
private void getCurrentLocation() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
if (isGPSEnabled()) {
LocationServices.getFusedLocationProviderClient(MainActivity.this)
.requestLocationUpdates(locationRequest, new LocationCallback() {
@Override
public void onLocationResult(@NonNull LocationResult locationResult) {
super.onLocationResult(locationResult);
LocationServices.getFusedLocationProviderClient(MainActivity.this)
.removeLocationUpdates(this);
if (locationResult != null amp;amp; locationResult.getLocations().size() > 0) {
int index = locationResult.getLocations().size() - 1;
double latitude = locationResult.getLocations().get(index).getLatitude();
double longitude = locationResult.getLocations().get(index).getLongitude();
myLocation = "Latitude: " latitude " Longitude: " longitude;
Toast.makeText(getApplicationContext(), myLocation, Toast.LENGTH_LONG).show();
}
}
}, Looper.getMainLooper());
} else {
turnOnGPS();
}
} else {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
}
}
}
private void turnOnGPS() {
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
builder.setAlwaysShow(true);
Task<LocationSettingsResponse> result = LocationServices.getSettingsClient(getApplicationContext())
.checkLocationSettings(builder.build());
result.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>() {
@Override
public void onComplete(@NonNull Task<LocationSettingsResponse> task) {
try {
LocationSettingsResponse response = task.getResult(ApiException.class);
Toast.makeText(MainActivity.this, "GPS is already tured on", Toast.LENGTH_SHORT).show();
} catch (ApiException e) {
switch (e.getStatusCode()) {
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
ResolvableApiException resolvableApiException = (ResolvableApiException) e;
resolvableApiException.startResolutionForResult(MainActivity.this, 2);
} catch (IntentSender.SendIntentException ex) {
ex.printStackTrace();
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
//Device does not have location
break;
}
}
}
});
}
private boolean isGPSEnabled() {
LocationManager locationManager = null;
boolean isEnabled = false;
if (locationManager == null) {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}
isEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
return isEnabled;
}
}
Поскольку местоположение пользователя является обязательным для работы приложения. Теперь я хочу, чтобы приложение:
1 — запросите разрешение на начало деятельности, если разрешение не было предоставлено или отказано ранее.
2 — если разрешение предоставлено, продолжайте, иначе закройте действие.
Итак, как я могу этого достичь? Спасибо
Ответ №1:
Вы можете проверить, дал ли пользователь разрешение на использование или нет checkSelfPermission
, и если нет, то вы снова запрашиваете разрешение, чтобы выполнить процесс с потоком программы.
if (ContextCompat.checkSelfPermission(this,Manifest.permission.READ_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED){
doStuff()
} else {
requestStoragePermission()
}
Ответ №2:
но проблема в том, что если пользователь дважды отказывает в разрешении, он больше не спрашивал,
Да, вы не можете спросить снова, как только пользователь откажет в разрешении, поставив флажок «Не спрашивать снова». Этот флажок обычно устанавливается по умолчанию при втором запросе разрешения. Имейте в виду, что в api 11 нет флажка, и отказ является автоматическим автоматическим сбросом автоматического отказа .
Дело в том, что вы ничего не предполагаете по этому поводу, просто применяете логику для обработки этого. В случае отказа вы можете сообщить пользователю только о требуемом разрешении. Официальный документ гласит: ref
Если метод ContextCompat.checkSelfPermission() возвращает PERMISSION_DENIED, вызов shouldShowRequestPermissionRationale(). Если этот метод возвращает значение true, покажите пользователю образовательный пользовательский интерфейс. В этом пользовательском интерфейсе опишите, почему для функции, которую пользователь хочет включить, требуется определенное разрешение.