Как программно открыть экран разрешений для конкретного приложения на Android Marshmallow?

У меня есть вопрос относительно новой версии Android Marshmallow:

Можно ли отобразить экран разрешений для определенного приложения через намерение или что-то подобное?

Экран разрешения Android M

Можно отобразить настройки приложения с помощью следующего кода - есть ли аналоговое решение для прямого открытия экрана разрешений?

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);

}
Другие вопросы по тегам