Будь-який спосіб пов’язати налаштування сповіщень Android для мого додатка?


84

Чи є спосіб запустити намір перейти на екран налаштувань сповіщень Android для мого додатка (на малюнку нижче)? Або простим способом я можу зробити елемент PreferenceScreen, який просто веде сюди за кліком?

введіть тут опис зображення


Це схоже на Налаштування. ACTION_APPLICATION_DETAILS_SETTINGS приведе мене до головного екрану інформації про програму, але я намагаюся зробити ще один крок далі в налаштуваннях сповіщень на екрані інформації про програму ...
Мохамед Хафез,

Поки ми на цьому @ mohamed-hafez, чи можете ви пояснити, як ви закріпили цей запис "Налаштування програми" тут? Я вважаю, що це робиться за допомогою фільтра намірів у Маніфесті, але не вдалося це зробити. Дякую!
Габріель

@ Габріель, схоже, ти вже знайшов відповідь на своє запитання, але для всіх, хто цікавиться, відповідь тут .
Сем

як відкрити категорію сповіщень програми (за замовчуванням)? на оріо. де ми можемо змінити звук, вібрацію та інші параметри
Сагар,

Відповіді:


148

У ОС Android 5.0 (Lollipop) та новіших версіях працюватиме наступне:

Intent intent = new Intent();
intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");

//for Android 5-7
intent.putExtra("app_package", getPackageName());
intent.putExtra("app_uid", getApplicationInfo().uid);

// for Android 8 and above
intent.putExtra("android.provider.extra.APP_PACKAGE", getPackageName());

startActivity(intent);

Примітки: Це офіційно не підтримується в Android 5-7, але воно працює чудово. Він офіційно підтримується з Android 8. Цей код не сумісний із версіями Android до 5.0.


@shhp - Дякую за цю відповідь. Також працює в попередньому перегляді N. Скажіть, будь ласка, кількома словами, як ви знайшли це рішення? Найдальше, що я отримав у цьому розслідуванні, це повідомлення журналу: com.android.settings D/SubSettings: Launching fragment com.android.settings.notification.AppNotificationSettingsпри натисканні на рядок "Сповіщення" в налаштуваннях програми. link2src
Dev-iL

@ Dev-iL ви отримуєте перший крок. Потім я перевірив вихідний код, щоб побачити, які додаткові intent
компоненти

1
Це круто, але користувачі повинні знати декілька речей: 1) Цей намір спирається на внутрішній / прихований код Settingsпрограми, тому немає гарантії, що в майбутньому Settingsпрограма не зміниться і більше не використовуватиме ті самі дії рядка , компонент або наміри, щоб відкрити екран сповіщень про програму. 2) Цей метод не є повністю зворотним. Дія String та використовувані компоненти були введені близько 2 років тому. Дивіться коміт тут
Тоні Чан

@TonyChan Дякуємо за нагадування. Додам їх у відповідь.
shhp

1
Тільки примітка: ви також можете досягти конкретного налаштування каналу сповіщень, як показано тут: stackoverflow.com/a/48854197/878126
розробник Android

78

Я об’єднав рішення Сергія та Шпха, щоб підтримати всі справи:

    Intent intent = new Intent();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
        intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName());
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
        intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
        intent.putExtra("app_package", context.getPackageName());
        intent.putExtra("app_uid", context.getApplicationInfo().uid);
    } else {
        intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.setData(Uri.parse("package:" + context.getPackageName()));
    }
    context.startActivity(intent);

13

Я додав налаштування сповіщення про канал для Android 8.0 Oreo API 26 або новішої версії. Є рішення від Android 4.4, KitKat.

Використання для налаштувань сповіщень каналу:

// PRIMARY_CHANNEL:
goToNotificationSettings(getString(R.string.PRIMARY_CHANNEL), mContext);
// SECONDARY_CHANNEL:
goToNotificationSettings(getString(R.string.SECONDARY_CHANNEL), mContext);

Використання для налаштувань сповіщень програми:

goToNotificationSettings(null, mContext);

Метод goToNotificationSettings:

public void goToNotificationSettings(String channel, Context context) {
    Intent intent = new Intent();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        intent.addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
        if (channel != null) {
            intent.setAction(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
            intent.putExtra(Settings.EXTRA_CHANNEL_ID, channel);
        } else {
            intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
        }
        intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName());
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        if (channel != null) {
            intent.setAction(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
            intent.putExtra(Settings.EXTRA_CHANNEL_ID, channel);
        } else {
            intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
        }
        intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName());
    } else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
        intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
        intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName());
    } else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
        intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
        intent.putExtra("app_package", context.getPackageName());
        intent.putExtra("app_uid", context.getApplicationInfo().uid);
    } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {
        intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.setData(Uri.parse("package:" + context.getPackageName()));
    }
    context.startActivity(intent);
}

1
Settings.ACTION_APP_NOTIFICATION_SETTINGS доступний з API> = Build.VERSION_CODES.O, тому його не слід використовувати на N_MR1 developer.android.com/reference/android/provider/…
Анте

код всередині if(Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1)ніколи не буде виконаний, в деяких частинах ви використовуєте правильно, Settings.ACTION_APP_NOTIFICATION_SETTINGSа в інших використовуєте рядок "android.settings.APP_NOTIFICATION_SETTINGS"
жорсткого коду

5

Я використовую цей код (kitkat та наступні версії):

if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    Intent intent = new Intent();
    intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
    intent.putExtra("app_package", getActivity().getPackageName());
    intent.putExtra("app_uid", getActivity().getApplicationInfo().uid);
    startActivity(intent);
} else if (android.os.Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {
    Intent intent = new Intent();
    intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
    intent.addCategory(Intent.CATEGORY_DEFAULT);
    intent.setData(Uri.parse("package:" + getActivity().getPackageName()));
    startActivity(intent);
}

5

Для ледачих чоловіків це версія відповіді @Helix на kotlin:

fun openAppNotificationSettings(context: Context) {
    val intent = Intent().apply {
        when {
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> {
                action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
                putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
            }
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> {
                action = "android.settings.APP_NOTIFICATION_SETTINGS"
                putExtra("app_package", context.packageName)
                putExtra("app_uid", context.applicationInfo.uid)
            }
            else -> {
                action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
                addCategory(Intent.CATEGORY_DEFAULT)
                data = Uri.parse("package:" + context.packageName)
            }
        }
    }
    context.startActivity(intent)
}

Чи є спосіб обробити налаштування push-сповіщень із додатка, не запускаючи налаштування?
vinay kumar

3

Я об’єднав код деяких відповідей вище та додав трохи редагування, я протестував, і він чудово працює на Android KitKat, Lollipop, Marshmallow, Nougat, Oreo and Pie, API рівень 19 - 28

public void goToNotificationSettings(Context context) {

    String packageName = context.getPackageName();

    try {
        Intent intent = new Intent();
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {

            intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
            intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName);
            intent.addFlags(FLAG_ACTIVITY_NEW_TASK);

        } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O) {

            intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
            intent.putExtra("android.provider.extra.APP_PACKAGE", packageName);

        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

            intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
            intent.putExtra("app_package", packageName);
            intent.putExtra("app_uid", context.getApplicationInfo().uid);

        } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {

            intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            intent.addCategory(Intent.CATEGORY_DEFAULT);
            intent.setData(Uri.parse("package:" + packageName));

        } else {
            return;
        }

        startActivity(intent);

    } catch (Exception e) {
        // log goes here           

    }

}

2

Я хотів би представити чисту версію відповіді @Helix:

fun openNotificationsSettings() {
    val intent = Intent()
    when {
        Build.VERSION.SDK_INT > Build.VERSION_CODES.O -> intent.setOpenSettingsForApiLarger25()
        Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> intent.setOpenSettingsForApiBetween21And25()
        else -> intent.setOpenSettingsForApiLess21()
    }
    app.startActivity(intent)
}

private fun Intent.setOpenSettingsForApiLarger25(){
    action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
    putExtra("android.provider.extra.APP_PACKAGE", app.packageName)
}

private fun Intent.setOpenSettingsForApiBetween21And25(){
    action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
    putExtra("app_package", app.packageName)
    putExtra("app_uid", app.applicationInfo?.uid)
}

private fun Intent.setOpenSettingsForApiLess21(){
    action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
    addCategory(Intent.CATEGORY_DEFAULT)
    data = Uri.parse("package:" + app.packageName)
}

Можна піти ще далі і витягти кожну, коли гілка переходить у компактний клас. І створити фабрику, в якій whenбуло б.


1

За допомогою ACTION_APP_NOTIFICATION_SETTINGSбуде показано всі канали програми:

Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
    .putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName());
startActivity(intent);

Щоб відкрити налаштування для одного каналу, ви можете скористатися ACTION_CHANNEL_NOTIFICATION_SETTINGS :

Де ви можете змінити sound,vibration.etcналаштування для окремого каналу.

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
 Intent intent = new Intent("android.settings.CHANNEL_NOTIFICATION_SETTINGS");
        intent.putExtra("android.provider.extra.CHANNEL_ID", "ChannelID");
        intent.putExtra("android.provider.extra.APP_PACKAGE", getPackageName());
        startActivity(intent);
   } 

0
public static void goToNotificationSettings(Context context) {
        Intent intent = new Intent();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            intent.setData(Uri.fromParts(SCHEME, context.getPackageName(), null));
        } else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1) {
            intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
            intent.putExtra("app_package", context.getPackageName());
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
            intent.putExtra("app_package", context.getPackageName());
            intent.putExtra("app_uid", context.getApplicationInfo().uid);
        } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {
            intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            intent.addCategory(Intent.CATEGORY_DEFAULT);
            intent.setData(Uri.parse("package:" + context.getPackageName()));
        } else {
            return;
        }
        context.startActivity(intent);
    }

Що таке константа SCHEME?
Atetc

Виглядає, що гілка else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1)ніколи не буде викликана
Atetc

0

Нарешті, я протестував майже всі пристрої і працює нормально. Код подається наступним чином

public void goToPushSettingPage(Context context) {
    try {
        Intent intent=new Intent();
        if(Build.VERSION.SDK_INT>Build.VERSION_CODES.N_MR1){
            intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
            intent.putExtra(Settings.EXTRA_APP_PACKAGE,context.getPackageName());
        }else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
            intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
            intent.putExtra(ConstUtil.PUSH_SETTING_APP_PACKAGE,context.getPackageName());
            intent.putExtra(ConstUtil.PUSH_SETTING_APP_UID,context.getApplicationInfo().uid);
        }else{
            intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            intent.addCategory(Intent.CATEGORY_DEFAULT);
            intent.setData(Uri.parse(ConstUtil.PUSH_SETTING_URI_PACKAGE+context.getPackageName()));
        }
        startActivity(intent);
    } catch (Exception e) {
        // log goes here
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.