ActivityCompat.requestPermissions не показывает диалоговое окно
if (ContextCompat.checkSelfPermission(RegisterActivity.this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_DENIED){
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_PHONE_STATE}, REQUEST_READ_PHONE_STATE_PERMISSION);
Я пытаюсь использовать эту функцию на nexus 5 api 23, и ее просто не покажут мне диалоговое окно, подобное тому, которое оно должно делать, оно просто ничего не делает.
что может вызвать проблему? (этот код находится в java-активности)
я попытался изменить свой минимум api на 23 и использовать requestPermissions() без ActivityCompat, но все еще не работает.
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "com.example.idanayzen.photomap"
minSdkVersion 23
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.google.android.gms:play-services:8.4.0'
compile 'com.android.support:design:23.1.1'
}
и манифест:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.idanayzen.photomap">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_SMS" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key" />
<activity
android:name=".MapsActivity"
android:label="@string/title_activity_maps" />
<activity android:name=".RegisterActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".WrongPhoneNum"></activity>
</application>
</manifest>
Ответы
Ответ 1
Вот пример использования requestPermissions()
:
Сначала определите разрешение (как и в вашем сообщении) в манифесте, иначе ваш запрос будет автоматически отклонен:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Затем определите значение для обработки обратного вызова разрешения в onRequestPermissionsResult():
private final int REQUEST_PERMISSION_PHONE_STATE=1;
Здесь код для вызова requestPermissions():
private void showPhoneStatePermission() {
int permissionCheck = ContextCompat.checkSelfPermission(
this, Manifest.permission.READ_PHONE_STATE);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.READ_PHONE_STATE)) {
showExplanation("Permission Needed", "Rationale", Manifest.permission.READ_PHONE_STATE, REQUEST_PERMISSION_PHONE_STATE);
} else {
requestPermission(Manifest.permission.READ_PHONE_STATE, REQUEST_PERMISSION_PHONE_STATE);
}
} else {
Toast.makeText(MainActivity.this, "Permission (already) Granted!", Toast.LENGTH_SHORT).show();
}
}
Сначала вы проверяете, имеете ли вы уже разрешение (помните, что даже после получения разрешения пользователь может позже аннулировать разрешение в настройках приложения.)
И, наконец, так вы проверяете, получили ли вы разрешение или нет:
@Override
public void onRequestPermissionsResult(
int requestCode,
String permissions[],
int[] grantResults) {
switch (requestCode) {
case REQUEST_PERMISSION_PHONE_STATE:
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MainActivity.this, "Permission Granted!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "Permission Denied!", Toast.LENGTH_SHORT).show();
}
}
}
private void showExplanation(String title,
String message,
final String permission,
final int permissionRequestCode) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(title)
.setMessage(message)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
requestPermission(permission, permissionRequestCode);
}
});
builder.create().show();
}
private void requestPermission(String permissionName, int permissionRequestCode) {
ActivityCompat.requestPermissions(this,
new String[]{permissionName}, permissionRequestCode);
}
Ответ 2
У меня была та же проблема, и оказалось, что это связано с инструментом слияния манифеста, потянув атрибут android:maxSdkVersion
из зависимости.
Чтобы просмотреть фактические разрешения, запрашиваемые в APK, вы можете использовать инструмент aapt
, например:
/path/to/android-sdk/build-tools/version/aapt d permissions /path/to/your-apk.apk
в моем случае напечатано:
uses-permission: name='android.permission.WRITE_EXTERNAL_STORAGE' maxSdkVersion='18'
хотя я не указал a maxSdkVersion
в своем манифесте. Я исправил эту проблему, изменив <uses-permission>
в своем манифесте на:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:remove="android:maxSdkVersion"/>
(где пространство имен инструментов http://schemas.android.com/tools
)
Ответ 3
Надеюсь, это поможет другим.
Мне нужно было запросить разрешение на WRITE_EXTERNAL_STORAGE, но я не получил всплывающее окно, несмотря на то, что попробовал все упомянутые предложения.
Виновником в итоге стал HockeyApp. Он использует слияние манифеста, чтобы включить собственное разрешение для WRITE_EXTERNAL_STORAGE, за исключением того, что он применяет к нему максимальную версию SDK.
Чтобы обойти эту проблему, включите ее в свой файл манифеста, но с заменой на нее, чтобы переопределить версию и успех HockeyApp!
4.7.2 Другие зависимости, запрашивающие разрешение на внешнее хранилище (SDK версии 5.0.0 и новее) Чтобы быть готовым для Android O, HockeySDK-Android 5.0.0 и новее ограничивают разрешение WRITE_EXTERNAL_STORAGE с помощью фильтра maxSdkVersion. В некоторых случаях использования, например, когда приложение содержит зависимость, для которой требуется это разрешение, maxSdkVersion делает невозможным для этих зависимостей предоставление или запрос разрешения. Решение для этих случаев заключается в следующем:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="replace"/>
Это приведет к тому, что другие атрибуты из низкоприоритетных манифестов будут заменены вместо объединения.
https://support.hockeyapp.net/kb/client-integration-android/hockeyapp-for-android-sdk#permissions-advanced
Ответ 4
Заменить:
ActivityCompat.requestPermissions(this, new String[]{"Manifest.permission.READ_PHONE_STATE"}, 225);
с:
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, 225);
Фактическая строка для этого разрешения не "Manifest.permission.READ_PHONE_STATE"
. Используйте символ Manifest.permission.READ_PHONE_STATE
.
Ответ 5
Я обновил мою целевую версию SDK от 22 до 23, и она отлично работала.
Ответ 6
Это может быть не проблема с одной строкой вашего кода.
На некоторых устройствах (не помню, есть ли в наличии Android) диалоговое окно "Разрешения" включает флажок "Никогда не спрашивать". Если вы нажмете "Запретить" с установленным флажком, у вас больше не будет запрашиваться разрешение, оно будет автоматически отклонено приложению. Чтобы это исправить, вам нужно зайти в "Настройки" → "Приложение" → "Разрешения" и снова включить эту разрешающую способность для приложения. Затем выключите его, чтобы снова отрицать. Возможно, вам придется открыть приложение, прежде чем снова его выключать, не уверен.
Я не знаю, есть ли у твоего Нексуса. Возможно стоит попробовать.
Ответ 7
Для меня проблема заключалась в том, чтобы ошибочно запрашивать группу вместо фактических разрешений.
Ответ 8
У меня была такая же проблема, и я решил ее, заменив Manifest.permission.READ_PHONE_STATE на android.Manifest.permission.READ_PHONE_STATE.
Ответ 9
Это случилось со мной. Оказалось, что я запрашивал ВСЕ разрешения, когда мне нужно было фильтровать только DANGEROUS-разрешения, и он внезапно начал работать.
fun requestPermissions() {
val missingDangerPermissions = PERMISSIONS
.filter { ContextCompat.checkSelfPermission(this, it) != PackageManager.PERMISSION_GRANTED }
.filter { this.getPackageManager().getPermissionInfo(it, PackageManager.GET_META_DATA).protectionLevel == PermissionInfo.PROTECTION_DANGEROUS } // THIS FILTER HERE!
if (missingDangerPermissions.isNotEmpty()) {
Log.i(TAG, "Requesting dangerous permission to $missingDangerPermissions.")
ActivityCompat.requestPermissions(this,
missingDangerPermissions.toTypedArray(),
REQUEST_CODE_REQUIRED_PERMISSIONS);
return
} else {
Log.i(TAG, "We had all the permissions we needed (yay!)")
}
}
Ответ 10
Я сталкивался с этой проблемой в Samsung S8 и N8 (не нашел ни в одном другом)
так что проблема в файле манифеста использования-разрешения
<uses-permission android:name="android.permission.CAMERA"
android:requiredFeature="true" />
По какой-то причине виновником является атрибут android:requiredFeature
. и я не нашел объяснения почему.
чтобы решить просто удалить его,
<uses-permission android:name="android.permission.CAMERA" />
Ответ 11
У меня была эта же проблема. Я обновился до buildToolsVersion "23.0.3" . Все это сработало. Надеюсь, это поможет любому, у кого есть эта проблема.
Ответ 12
Для меня проблема заключалась в том, что у меня был неверный код запроса. Я выбираю 0xDEADBEEF в качестве кода запроса, и он молчал (возможно, он перебрасывается на что-то меньшее, чем 32-битное где-то внутри?) Если я выберу 255, все работает отлично, как описано NightSkyDev.
Ответ 13
Вышеприведенная информация хороша, но настройка targetSdkVersion
до 23 (или выше) критическая для Android, чтобы интерпретировать тег <uses-permission>
в манифесте как "Я спрошу в коде" вместо "Я требую после установки". Многие источники расскажут вам, что вам нужен тег <uses-permission>
, но никто не говорит, почему, и если у вас нет этого набора значений, вы будете так же запутаны, как я был в течение нескольких часов подряд.
Ответ 14
Для меня ошибка была в манифесте: разрешение было в верхнем регистре. Android Studio предлагает мне разрешения в верхнем регистре. Меня это не волнует, и мне потребовалось два часа, чтобы устранить эту проблему.
Правильный синтаксис для разрешения - это
< uses-permission android: name= "android.permission.WRITE_EXTERNAL_STORAGE" / >
Ответ 15
со мной случилось, что я запускал его на API 23, и мне пришлось использовать код, чтобы запросить разрешение, как этот код, приведенный ниже, на метод create. обратите внимание, что MY_PERMISSIONS_REQUEST_READ_LOCATION является целым числом, равным 1 примеру int MY_PERMISSIONS_REQUEST_READ_LOCATION = 1:
if (Build.VERSION.SDK_INT> = Build.VERSION_CODES.M) {requestPermissions (new String [] {Manifest.permission.ACCESS_COARSE_LOCATION}, MY_PERMISSIONS_REQUEST_READ_LOCATION); }
Ответ 16
Может быть, это решение может помочь кому-нибудь, а не:
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
использовать:
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
поэтому мы добавляем android.
на Manifest.permission.WRITE_EXTERNAL_STORAGE
Ответ 17
Для меня проблема была в том, что сразу после выполнения запроса моя основная деятельность запустила другую деятельность. Это заменило диалог, поэтому его никогда не видели.
Ответ 18
Не забудьте написать разрешения без лишних пробелов в манифесте. В моем случае у меня было:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE " />
Но посмотрите, в конце концов, есть дополнительное место. Просто напишите это правильно
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
И это работает сейчас