Как программно открыть экран разрешений для конкретного приложения на Android Marshmallow?
У меня есть вопрос относительно новой версии Android Marshmallow:
Можно ли отобразить экран разрешений для определенного приложения через намерение или что-то подобное?
Можно отобразить настройки приложения с помощью следующего кода - есть ли аналоговое решение для прямого открытия экрана разрешений?
startActivity(new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", getPackageName(), null)));
Я уже провел некоторые исследования по этому вопросу, но не смог найти правильного решения - я был бы признателен за любую помощь!
16 ответов
Согласно официальному видео с разрешениями "Зефир" (на отметке 4 м 43 с), вы должны вместо этого открыть страницу "Настройки приложения" (оттуда один клик до страницы "Разрешения").
Чтобы открыть страницу настроек, вы должны сделать
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
Это невозможно. Я тоже пытался это сделать. Я мог бы выяснить имя пакета и активность, которая будет запущена. Но в конце вы получите исключение безопасности из-за отсутствия разрешения, которое вы не можете объявить.
ОБНОВИТЬ:
Что касается другого ответа, я также рекомендую открыть экран настроек приложения. Я делаю это с помощью следующего кода:
public static void startInstalledAppDetailsActivity(final Activity context) {
if (context == null) {
return;
}
final Intent i = new Intent();
i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
i.addCategory(Intent.CATEGORY_DEFAULT);
i.setData(Uri.parse("package:" + context.getPackageName()));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
context.startActivity(i);
}
Поскольку я не хочу иметь это в моем стеке истории, я удаляю это, используя намеренные флаги.
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
Описание Settings.ACTION_APPLICATION_DETAILS_SETTINGS
Открывает страницу настроек сведений для приложения. Отсюда пользователь должен вручную назначить желаемое разрешение.
Intent.FLAG_ACTIVITY_NEW_TASK
Необязательно. Если установлено, откроется экран настроек (активность) как новое действие. В противном случае он будет открыт в текущем действии.
Uri.fromParts("package", getPackageName(), null)
Подготавливает или создает URI, тогда как getPackageName() - возвращает имя вашего пакета приложения.
intent.setData(uri)
Не забудьте установить это. В противном случае вы получите android.content.ActivityNotFoundException
, Потому что вы установили свое намерение как Settings.ACTION_APPLICATION_DETAILS_SETTINGS
и Android ожидает какое-то имя для поиска.
Если вы хотите написать меньше кода в Kotlin
вы можете сделать это:
fun Context.openAppSystemSettings() {
startActivity(Intent().apply {
action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
data = Uri.fromParts("package", packageName, null)
})
}
Основано на ответе Мартина Конечны
Вместо этого вы можете открыть общие настройки конкретного приложения одной строкой
startActivity(new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + BuildConfig.APPLICATION_ID)));
Котлинский стиль.
startActivity(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
data = Uri.fromParts("package", packageName, null)
})
Начиная с Android 11, вы можете напрямую вызвать страницу настроек конкретного приложения для разрешения местоположения, только используя следующий код:
requestPermissions(arrayOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION), PERMISSION_REQUEST_BACKGROUND_LOCATION)
Однако вышеуказанное будет работать только один раз. Если пользователь отказывает в разрешении или даже случайно закрывает экран, приложение никогда не сможет вызвать это снова.
Помимо вышеперечисленного, ответ остается таким же, как и до Android 11 - лучшее, что вы можете сделать, - это открыть страницу настроек для конкретного приложения и попросить пользователя вручную развернуть два уровня, чтобы включить правильное разрешение.
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
val uri: Uri = Uri.fromParts("package", packageName, null)
intent.data = uri
// This will take the user to a page where they have to click twice to drill down to grant the permission
startActivity(intent)
См. Мой связанный с этим вопрос здесь: Пользователи Android 11 не могут предоставить разрешение на определение местоположения в фоновом режиме?
Невозможно прагматично открыть экран разрешений. Вместо этого мы можем открыть экран настроек приложения.
Код
Intent i = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + BuildConfig.APPLICATION_ID));
startActivity(i);
Пример вывода
Xamarin Forms Android:
//---------------------------------------------------------
public void OpenSettings()
//---------------------------------------------------------
{
var intent = new Intent(Android.Provider.Settings.ActionApplicationDetailsSettings,
Android.Net.Uri.Parse("package:" + Forms.Context.PackageName));
Forms.Context.StartActivity(intent);
}
В Котлине
/*
*
* To open app notification permission screen instead of setting
* */
fun Context.openAppNotificationSettings() {
val intent = Intent().apply {
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> {
action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
}
else -> {
action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
addCategory(Intent.CATEGORY_DEFAULT)
data = Uri.parse("package:" + packageName)
}
}
}
startActivity(intent)
}
Над одним проверен и работает код, надеюсь, это поможет.
Может быть, это поможет вам
private void openSettings() {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, 101);
}
Если мы говорим только о FLYME OS (Meizu), то есть собственное приложение безопасности с разрешениями.
Чтобы открыть его используйте следующее намерение:
public static void openFlymeSecurityApp(Activity context) {
Intent intent = new Intent("com.meizu.safe.security.SHOW_APPSEC");
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.putExtra("packageName", BuildConfig.APPLICATION_ID);
try {
context.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
}
Из-за BuildConfig является BuildConfig вашего приложения.
Откройте экран разрешений для определенного приложения
if (ContextCompat.checkSelfPermission(
context, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED
) {
//Permission is not granted yet. Ask for permission.
val alertDialog = AlertDialog.Builder(context)
alertDialog.setMessage(context.getString(R.string.file_permission))
alertDialog.setPositiveButton("सेटिंग") { _, _ ->
val intent = Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", BuildConfig.APPLICATION_ID, null)
)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)
}
alertDialog.setNegativeButton("हाँ") { _, _ ->
ActivityCompat.requestPermissions(
context as Activity, arrayOf(
Manifest.permission.WRITE_EXTERNAL_STORAGE
), 1
)
}
alertDialog.show()
} else {}
невозможно прагматически получить разрешение... но я не советую вам помещать эту строку кода в try{} catch{}, который, к сожалению, останавливает ваше приложение... и в теле body сделать диалоговое окно, которое будет перемещаться по от пользователя к небольшому учебнику, чтобы разрешить рисование поверх других приложений... затем нажмите кнопку Да, введите этот код...
Intent callSettingIntent= new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
startActivity(callSettingIntent);
эта цель состоит в том, чтобы непосредственно открыть список отрисовки над другими приложениями для управления разрешениями, а затем отсюда можно одним щелчком мыши отрисовать поверх других приложений Разрешения... я знаю, что это не тот ответ, который вы ищете... но Я делаю это в моих приложениях...
Попробуй это
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName(appDetails.packageName,"com.android.packageinstaller.permission.ui.ManagePermissionsActivity"));
startActivity(intent);
Это возможно с методом requestPermissions
Хотя вы не можете непосредственно видеть страницу настроек, вы можете изменить права доступа.
Хороший пример:
https://www.learn2crack.com/2015/10/android-marshmallow-permissions.html
Таким образом, вы можете проверить и позвонить
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
{
requestPermissions(new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE}, 0);
}