У меня есть приложение, которое использует WebView, где сайты могут запросить использование геолокации устройства. В своей основной деятельности у меня есть следующее:
public void onGeolocationPermissionsShowPrompt(final String origin, final GeolocationPermissions.Callback callback) {
m_geolocationCallback = null;
m_geolocationOrigin = null;
// If we don't have location permissions, we must request them first
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// Show rationale if necessary
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)) {
new AlertDialog.Builder(MainActivity.this)
.setMessage(getString(R.string.permission_location_rationale, origin))
.setNeutralButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
m_geolocationOrigin = origin;
m_geolocationCallback = callback;
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
}
})
.show();
}
else {
m_geolocationOrigin = origin;
m_geolocationCallback = callback;
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
}
}
// Otherwise just tell webview that permission has been granted
else {
callback.invoke(origin, true, false);
}
}
Для обработки результата запроса разрешения MainActivity
также имеет следующее:
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION:
// Permission granted
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (m_geolocationCallback != null) {
m_geolocationCallback.invoke(m_geolocationOrigin, true, false);
}
}
// Permission denied
else {
// In this case, the user checked "Don't ask again" and denied permission
if (Build.VERSION.SDK_INT >= 23 && !shouldShowRequestPermissionRationale(permissions[0])) {
Toast.makeText(this, R.string.permission_location_denied, Toast.LENGTH_LONG).show();
}
if (m_geolocationCallback != null) {
m_geolocationCallback.invoke(m_geolocationOrigin, false, false);
}
}
return;
}
}
Проблема, с которой я сталкиваюсь, заключается в том, что всякий раз, когда сайт запрашивает использование геолокации, и я отрицаю это (в результате вызывается invoke(origin, false false)
), метод onGeolocationPermissionsShowPrompt
вызывается немедленно, и я зацикливаюсь на бесконечности отказ в разрешении на приложение.
Если я отмечу «не спрашивать снова» в запросе на разрешение, он будет работать нормально, но я хочу иметь возможность снова запросить у пользователя разрешение на более позднее время.
Я попытался исправить это, изменив мой вызов обратного вызова на
m_geolocationCallback.invoke(m_geolocationOrigin, false, true)
, но это не дает желаемого эффекта. Это предотвратит остановку непрерывных вызовов на onGeolocationPermissionsShowPrompt
, но это также означает, что данный источник больше не может использовать геолокацию, даже если разрешения включены позднее, и я не нашел способа отменить это (даже путем удаления / переустановки приложения).
Есть идеи, как обойти эту проблему?