¿Alguna forma de vincular a la configuración de notificaciones de Android para mi aplicación?

81

¿Hay alguna forma de que pueda iniciar una intención para acceder a la pantalla de configuración de notificaciones de Android para mi aplicación (que se muestra a continuación)? ¿O de una manera fácil puedo hacer un elemento de PreferenceScreen que solo lleve aquí con un clic?

ingrese la descripción de la imagen aquí

Mohamed Hafez
fuente
Parece que Settings.ACTION_APPLICATION_DETAILS_SETTINGS me llevará a la pantalla principal de información de la aplicación, pero estoy tratando de avanzar un paso más en la configuración de notificaciones en la pantalla de información de la aplicación ...
Mohamed Hafez
Ya que estamos en eso @ mohamed-hafez, ¿podrías explicar cómo hiciste para anclar esta entrada de "Configuración de la aplicación" aquí? Dirijo que se hace a través de un filtro de intención en el Manifiesto, pero no lo hice. ¡Gracias!
Gabriel
@Gabriel, parece que ya encontró la respuesta a su pregunta, pero para cualquier otra persona interesada, la respuesta está aquí .
Sam
¿Cómo abrir la categoría de notificación de la aplicación (predeterminada)? en orio. donde podemos cambiar el sonido, la vibración y otros entornos
Sagar

Respuestas:

144

Lo siguiente funcionará en Android 5.0 (Lollipop) y superior:

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

Notas: Esto no se admite oficialmente en Android 5-7, pero funciona bien. Es oficialmente compatible a partir de Android 8. Este código no es compatible con versiones anteriores de Android 5.0.

shhp
fuente
@shhp - Gracias por esta respuesta. También funciona en la vista previa N. ¿Podría decir en pocas palabras cómo encontró esta solución? Lo más lejos que llegué en esta investigación fue este mensaje de registro: com.android.settings D/SubSettings: Launching fragment com.android.settings.notification.AppNotificationSettingsal hacer clic en la línea "Notificaciones" en la configuración de la aplicación. link2src
Dev-iL
@ Dev-iL obtienes el primer paso. Luego verifiqué el código fuente para ver qué extras se deben poner en intent:-)
shhp
1
Esto es genial, pero los usuarios deben tener en cuenta algunas cosas: 1) Esta intención se basa en el código interno / oculto de la Settingsaplicación, por lo que no hay garantía de que en el futuro la Settingsaplicación no cambie y ya no use la misma acción String , componente o Intent extras para abrir la pantalla de notificación específica de la aplicación. 2) Este método no es completamente compatible con versiones anteriores. La acción String y los componentes utilizados se introdujeron hace aproximadamente 2 años. Ver compromiso aquí
Tony Chan
@TonyChan Gracias por el recordatorio. Los agregaré en la respuesta.
shhp
Recién editado para que funcione con Android O, además de Android 5-7. Nota: ¡esto es oficialmente compatible con Android O!
Mohamed Hafez
77

Fusioné la solución de Sergei y Shhp para respaldar todos los casos:

    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);
Hélice
fuente
12

Agregué la configuración de notificación de canal para Android 8.0 Oreo API 26 o posterior. Existe una solución de Android 4.4, KitKat.

Uso de la configuración de notificaciones del canal:

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

Uso para la configuración de notificaciones de la aplicación:

goToNotificationSettings(null, mContext);

El método de 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
fuente
1
Settings.ACTION_APP_NOTIFICATION_SETTINGS está disponible en API> = Build.VERSION_CODES.O por lo que no debe usarse en N_MR1 developer.android.com/reference/android/provider/…
Ante
el código interno if(Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1)nunca se ejecutará, en algunas partes está usando correctamente, Settings.ACTION_APP_NOTIFICATION_SETTINGSpero en otras está usando una cadena de código duro"android.settings.APP_NOTIFICATION_SETTINGS"
Hugo Allexis Cardona
5

Yo uso este código (kitkat y próximas versiones):

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
fuente
3

Fusioné el código de algunas de las respuestas anteriores y agregué una pequeña edición, lo probé y funciona bien en Android KitKat, Lollipop, Marshmallow, Nougat, Oreo y Pie, API nivel 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           

    }

}
NuevoDevin
fuente
3

Para los hombres perezosos, esta es la versión kotlin de la respuesta de @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
fuente
2

Me gustaría presentar una versión de código limpio de la respuesta de @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)
}

Uno puede ir aún más lejos y extraer cada uno cuando se ramifica en una clase compacta. Y crear una fábrica en la que whenestaría.

Kirill Starostin
fuente
1

El uso ACTION_APP_NOTIFICATION_SETTINGSenumerará todos los canales de la aplicación:

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

Para abrir la configuración de un solo canal, puede usar ACTION_CHANNEL_NOTIFICATION_SETTINGS:

Donde puede cambiar la sound,vibration.etcconfiguración de un canal individual.

 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
fuente
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
fuente
¿Qué es la constante SCHEME?
Atetc
Parece que la sucursal else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1)nunca se llamará
Atetc
0

Finalmente probé casi todos los dispositivos y funciona bien. El código dado de la siguiente manera

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
fuente