Gibt es eine Möglichkeit, auf die Android-Benachrichtigungseinstellungen für meine App zu verlinken?

81

Gibt es eine Möglichkeit, die Absicht zu starten, zum Benachrichtigungseinstellungsbildschirm von Android für meine App zu gelangen (siehe Abbildung unten)? Oder auf einfache Weise kann ich ein PreferenceScreen-Element erstellen, das nur mit einem Klick hierher führt?

Geben Sie hier die Bildbeschreibung ein

Mohamed Hafez
quelle
Es sieht so aus, als würde Settings.ACTION_APPLICATION_DETAILS_SETTINGS mich zum Haupt-App-Info-Bildschirm bringen, aber ich versuche, einen Schritt weiter in die Benachrichtigungseinstellungen auf dem App-Info-Bildschirm zu gelangen ...
Mohamed Hafez
Können Sie erklären, wie Sie diesen Eintrag "App-Einstellungen" hier verankert haben, während wir bei @ mohamed-hafez sind? Ich gehe davon aus, dass dies über einen Intent-Filter im Manifest erfolgt, dies jedoch nicht getan hat. Vielen Dank!
Gabriel
@Gabriel, es sieht so aus, als hätten Sie die Antwort auf Ihre Frage bereits gefunden, aber für alle anderen Interessierten ist die Antwort hier .
Sam
Wie öffne ich die App-Benachrichtigungskategorie (Standard)? auf orio. wo wir Klang, Vibration und andere Einstellungen ändern können
Sagar

Antworten:

144

Folgendes funktioniert in Android 5.0 (Lollipop) und höher:

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

Hinweise: Dies wird in Android 5-7 nicht offiziell unterstützt, funktioniert aber einwandfrei. Es wird ab Android 8 offiziell unterstützt. Dieser Code ist nicht abwärtskompatibel mit Versionen von Android vor 5.0.

shhp
quelle
@shhp - Danke für diese Antwort. Funktioniert auch in der N-Vorschau. Würden Sie bitte in wenigen Worten sagen, wie Sie diese Lösung gefunden haben? Am weitesten von dieser Untersuchung entfernt war diese Protokollmeldung: com.android.settings D/SubSettings: Launching fragment com.android.settings.notification.AppNotificationSettingsWenn Sie in den App-Einstellungen auf die Zeile "Benachrichtigungen" klicken. link2src
Dev-iL
@ Dev-iL du bekommst den ersten Schritt. Dann habe ich den Quellcode überprüft, um zu sehen, welche Extras in die intent:-)
shhp
1
Das ist cool, aber Benutzer sollten sich einiger Dinge bewusst sein: 1) Diese Absicht beruht auf internem / verstecktem Code der SettingsApp, daher gibt es keine Garantie dafür, dass sich die SettingsApp in Zukunft nicht ändert und nicht mehr dieselbe String-Aktion verwendet , Komponenten- oder Absichts-Extras zum Öffnen des app-spezifischen Benachrichtigungsbildschirms. 2) Diese Methode ist nicht vollständig abwärtskompatibel. Die String-Aktion und die verwendeten Komponenten wurden vor ca. 2 Jahren eingeführt. Siehe Commit hier
Tony Chan
@ TonyChan Danke für die Erinnerung. Ich werde sie in der Antwort hinzufügen.
shhp
Gerade bearbeitet, damit dies zusätzlich zu Android 5-7 auch mit Android O funktioniert. Hinweis: Dies wird offiziell in Android O unterstützt!
Mohamed Hafez
77

Ich habe die Lösung von Sergei und Shhp zusammengeführt, um alle Fälle zu unterstützen:

    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);
Wendel
quelle
12

Ich habe die Kanalbenachrichtigungseinstellungen für Android 8.0 Oreo API 26 oder höher angehängt. Es gibt eine Lösung von Android 4.4, KitKat.

Verwendung für Kanalbenachrichtigungseinstellungen:

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

Verwendung für App-Benachrichtigungseinstellungen:

goToNotificationSettings(null, mContext);

Die Methode von 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
quelle
1
Settings.ACTION_APP_NOTIFICATION_SETTINGS ist über API> = Build.VERSION_CODES.O verfügbar, daher sollte es nicht unter N_MR1 developer.android.com/reference/android/provider/…
Ante
Code im Inneren if(Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1)wird nie ausgeführt, in einigen Teilen verwenden Sie korrekt Settings.ACTION_APP_NOTIFICATION_SETTINGS, in anderen verwenden Sie "android.settings.APP_NOTIFICATION_SETTINGS"
Hardcode-
5

Ich benutze diesen Code (Kitkat und nächste Versionen):

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);
}
Sergei K.
quelle
3

Ich habe den Code einiger der obigen Antworten zusammengeführt und wenig Bearbeitung hinzugefügt. Ich habe ihn getestet und er funktioniert einwandfrei unter Android KitKat, Lollipop, Marshmallow, Nougat, Oreo und Pie, API-Level 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
quelle
3

Für faule Männer ist dies die Kotlin-Version von @Helix Antwort:

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
quelle
2

Ich möchte eine Clean-Code-Version von @Helix Antwort präsentieren:

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

Man kann noch weiter gehen und jedes extrahieren, wenn man in eine kompakte Klasse verzweigt. Und schaffen Sie eine Fabrik, in der whenwäre.

Kirill Starostin
quelle
1

Mit ACTION_APP_NOTIFICATION_SETTINGSwerden alle Kanäle der App aufgelistet:

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

Um die Einstellungen für einen einzelnen Kanal zu öffnen, können Sie Folgendes verwenden ACTION_CHANNEL_NOTIFICATION_SETTINGS:

Hier können Sie sound,vibration.etcEinstellungen für einzelne Kanäle ändern .

 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
quelle
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
quelle
Was ist die SCHEMA-Konstante?
Atetc
Sieht so aus, als würde die Filiale else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1)niemals angerufen werden
Atetc,
0

Schließlich habe ich fast alle Geräte getestet und funktioniert einwandfrei. Der Code wird wie folgt angegeben

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
quelle