Czy jest jakiś sposób na połączenie z ustawieniami powiadomień Androida dla mojej aplikacji?

84

Czy istnieje sposób, w jaki mogę uruchomić zamiar przejścia do ekranu ustawień powiadomień Androida dla mojej aplikacji (na zdjęciu poniżej)? Czy w prosty sposób mogę utworzyć element PreferenceScreen, który prowadzi tutaj po kliknięciu?

wprowadź opis obrazu tutaj

Mohamed Hafez
źródło
Wygląda na to, że Ustawienia.ACTION_APPLICATION_DETAILS_SETTINGS przeniesie mnie do głównego ekranu informacji o aplikacji, ale próbuję przejść o krok dalej w ustawieniach powiadomień na ekranie informacji o aplikacji ...
Mohamed Hafez
Skoro już jesteśmy na tym @ mohamed-hafez, czy możesz wyjaśnić, jak zakotwiczyłeś tutaj ten wpis „Ustawienia aplikacji”? Wydaje mi się, że odbywa się to przez filtr intencji w Manifeście, ale nie udało mi się tego zrobić. Dzięki!
Gabriel
@Gabriel, wygląda na to, że już znalazłeś odpowiedź na swoje pytanie, ale dla wszystkich zainteresowanych odpowiedź jest tutaj .
Sam
jak otworzyć kategorię powiadomień aplikacji (domyślna)? on orio. gdzie możemy zmienić dźwięk, wibracje i inne ustawienia
Sagar

Odpowiedzi:

148

Następujące elementy będą działać w systemie Android 5.0 (Lollipop) i nowszych:

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

Uwagi: nie jest to oficjalnie obsługiwane w systemie Android 5-7, ale działa dobrze. Jest oficjalnie obsługiwany od Androida 8. Ten kod nie jest wstecznie kompatybilny z wersjami Androida wcześniejszymi niż 5.0.

shhp
źródło
@shhp - Dziękuję za tę odpowiedź. Działa również w podglądzie N. Czy mógłbyś powiedzieć w kilku słowach, jak znalazłeś to rozwiązanie? Najdalej w tym badaniu był ten komunikat dziennika: com.android.settings D/SubSettings: Launching fragment com.android.settings.notification.AppNotificationSettingspo kliknięciu wiersza „Powiadomienia” w ustawieniach aplikacji. link2src
Dev-iL
@ Dev-iL masz pierwszy krok. Następnie sprawdziłem kod źródłowy, aby zobaczyć, jakie dodatki należy umieścić w intent:-)
shhp
1
To jest fajne, ale użytkownicy powinni być świadomi kilku rzeczy: 1) Ten zamiar opiera się na wewnętrznym / ukrytym kodzie Settingsaplikacji, więc nie ma gwarancji, że w przyszłości Settingsaplikacja się nie zmieni i nie będzie już używać tej samej akcji String , składnik lub dodatki, aby otworzyć ekran powiadomień specyficznych dla aplikacji. 2) Ta metoda nie jest w pełni kompatybilna wstecz. Akcja String i zastosowane komponenty zostały wprowadzone około 2 lata temu. Zobacz zobowiązanie tutaj
Tony Chan
@TonyChan Dziękuję za przypomnienie. Dodam je w odpowiedzi.
shhp
1
Na marginesie: możesz również przejść do określonego ustawienia kanału powiadomień, jak pokazano tutaj: stackoverflow.com/a/48854197/878126
programista Androida
78

Połączyłem rozwiązanie Sergei i Shhp, aby obsługiwać wszystkie przypadki:

    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);
Spirala
źródło
13

Dodałem ustawienia powiadomień kanału dla Androida 8.0 Oreo API 26 lub nowszego. Jest rozwiązanie z Androida 4.4 KitKat.

Wykorzystanie ustawień powiadomień dotyczących kanału:

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

Wykorzystanie ustawień powiadomień aplikacji:

goToNotificationSettings(null, mContext);

Metoda 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);
}
Andy Sander
źródło
1
Settings.ACTION_APP_NOTIFICATION_SETTINGS jest dostępny z API> = Build.VERSION_CODES.O, więc nie powinien być używany na N_MR1 developer.android.com/reference/android/provider/ ...
Ante
kod wewnątrz if(Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1)nigdy nie zostanie wykonany, w niektórych częściach używasz poprawnie, Settings.ACTION_APP_NOTIFICATION_SETTINGSale w innych używasz "android.settings.APP_NOTIFICATION_SETTINGS"
stałego kodu
5

Używam tego kodu (KitKat i kolejne wersje):

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);
}
Siergiej K.
źródło
5

Dla leniwych mężczyzn to wersja kotlin odpowiedzi @Helix:

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)
}
carlol
źródło
Czy istnieje sposób obsługi ustawień powiadomień push z poziomu aplikacji bez rozpoczynania działania ustawień?
vinay kumar
3

Połączyłem kod niektórych z powyższych odpowiedzi i dodałem małą edycję, przetestowałem i działa dobrze na Androidzie KitKat, Lollipop, Marshmallow, Nougat, Oreo i Pie, poziom 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           

    }

}
NewDevin
źródło
2

Chciałbym przedstawić czysto kodową wersję odpowiedzi @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)
}

Można pójść jeszcze dalej i wyodrębnić każdą gałąź w klasę kompaktową. I stwórz fabrykę, w której whenbędzie.

Kirill Starostin
źródło
1

Użycie ACTION_APP_NOTIFICATION_SETTINGSspowoduje wyświetlenie wszystkich kanałów aplikacji:

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

Aby otworzyć ustawienia dla pojedynczego kanału, możesz użyć ACTION_CHANNEL_NOTIFICATION_SETTINGS:

Gdzie możesz zmienić sound,vibration.etcustawienia dla poszczególnych kanałów.

 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);
   } 
Sagar
źródło
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);
    }
itzhar
źródło
Jaka jest stała SCHEMAT?
Atetc
Wygląda na to, że oddział else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1)nigdy nie zostanie nazwany
Atetc
0

Wreszcie przetestowałem prawie wszystkie urządzenia i działa dobrze. Kod podany w następujący sposób

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
    }
}
Farid Haq
źródło