La notificación local con AlarmManager y BroadcastReceiver no se enciende en Android O(oreo)
(4)
Pruebe este código para Android O 8.1
Intent nIntent = new Intent("android.media.action.DISPLAY_NOTIFICATION");
nIntent.addCategory("android.intent.category.DEFAULT");
nIntent.putExtra("message", "test");
nIntent.setClass(this, AlarmReceiver.class);
PendingIntent broadcast = PendingIntent.getBroadcast(getAppContext(), 100, nIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Hola , tengo mis notificaciones locales ejecutándose en Android antes del SDK 26
Pero en un Android O tengo la siguiente advertencia, y el receptor de difusión no se activa.
W/BroadcastQueue: Background execution not allowed: receiving Intent { act=package.name.action.LOCAL_NOTIFICATION cat=[com.category.LocalNotification] flg=0x14 (has extras) } to package.name/com.category.localnotifications.LocalNotificationReceiver
Por lo que he leído, los receptores de difusión están más restringidos en Android O, pero si es así, ¿cómo debería programar la transmisión si quiero que se inicie incluso si la actividad principal no se está ejecutando?
¿Debo usar servicios en lugar de receptores?
Este es el código de inicio de AlarmManager:
public void Schedule(String aID, String aTitle, String aBody, int aNotificationCode, long aEpochTime)
{
Bundle lExtras = new Bundle();
lExtras.putInt("icon", f.getDefaultIcon());
lExtras.putString("title", aTitle);
lExtras.putString("message", aBody);
lExtras.putString("id", aID);
lExtras.putInt("requestcode", aNotificationCode);
Intent lIntent =
new Intent(LocalNotificationScheduler.ACTION_NAME)
.addCategory(NotificationsUtils.LocalNotifCategory)
.putExtras(lExtras);
PendingIntent lPendIntent = PendingIntent.getBroadcast(f.getApplicationContext(), aNotificationCode,
lIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager lAlarmMgr = (AlarmManager) f.getSystemService(Context.ALARM_SERVICE);
lAlarmMgr.set(AlarmManager.RTC, 1000, lPendIntent);
}
Este es el código del receptor:
public class LocalNotificationReceiver extends BroadcastReceiver {
public static native void nativeReceiveLocalNotification (String aID, String aTitle, String aMessage, boolean aOnForeground );
/** This method receives the alarms set by LocalNotificationScheduler,
* notifies the CAndroidNotifications c++ class, and (if needed) ships a notification banner
*/
@Override
public void onReceive(Context aContext, Intent aIntent)
{
Toast.makeText(context, text, duration).show();
}
}
Este es el manifiesto:
<receiver android:name="com.category.localnotifications.LocalNotificationReceiver">
<intent-filter>
<action android:name="${applicationId}.action.LOCAL_NOTIFICATION" />
<category android:name="com.category.LocalNotification" />
</intent-filter>
</receiver>
Android O son bastante nuevos hasta la fecha. Por lo tanto, trato de digerir y proporcionar la información más precisa posible.
Desde https://developer.android.com/about/versions/oreo/background.html#broadcasts
- Las aplicaciones dirigidas a Android 8.0 o superior ya no pueden registrar receptores de difusión para transmisiones implícitas en su manifiesto.
- Las aplicaciones pueden usar
Context.registerReceiver()
en tiempo de ejecución para registrar un receptor para cualquier transmisión, ya sea implícita o explícita .
- Las aplicaciones pueden usar
- Las aplicaciones pueden seguir registrando emisiones explícitas en su manifiesto.
Además, en https://developer.android.com/training/scheduling/alarms.html , los ejemplos usan transmisión explícita, y no menciona nada especial con respecto a Android O.
¿Puedo sugerirte que pruebes la transmisión explícita como sigue?
public static void startAlarmBroadcastReceiver(Context context, long delay) {
Intent _intent = new Intent(context, AlarmBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, _intent, 0);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
// Remove any previous pending intent.
alarmManager.cancel(pendingIntent);
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + delay, pendingIntent);
}
AlarmBroadcastReceiver
public class AlarmBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
}
}
En AndroidManifest
, solo define la clase como
<receiver android:name="org.yccheok.AlarmBroadcastReceiver" >
</receiver>
Cree el AlarmManager definiendo una intención explícita (defina explícitamente el nombre de la clase del receptor de difusión):
private static PendingIntent getReminderReceiverIntent(Context context) {
Intent intent = new Intent("your_package_name.ReminderReceiver");
// create an explicit intent by defining a class
intent.setClass(context, ReminderReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return pendingIntent;
}
Tampoco olvide crear un canal de notificación para Android Oreo (API 26) al crear la notificación real:
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (VERSION.SDK_INT >= VERSION_CODES.O) {
notificationManager.createNotificationChannel(NotificationFactory.createNotificationChannel(context));
} else {
notificationManager.notify(NotificationsHelper.NOTIFICATION_ID_REMINDER, notificationBuilder.build());
}
Hoy tuve el mismo problema y mi notificación no funcionaba. Pensé que el administrador de alarmas no está funcionando en Oreo, pero el problema era con la Notificación . En Oreo tenemos que añadir Channel id
. Por favor, eche un vistazo a mi nuevo código:
int notifyID = 1;
String CHANNEL_ID = "your_name";// The id of the channel.
CharSequence name = getString(R.string.channel_name);// The user-visible name of the channel.
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, name, importance);
// Create a notification and set the notification channel.
Notification notification = new Notification.Builder(HomeActivity.this)
.setContentTitle("Your title")
.setContentText("Your message")
.setSmallIcon(R.drawable.notification)
.setChannelId(CHANNEL_ID)
.build();
Compruebe esta solución. Funcionó a la perfección.
https://.com/a/43093261/4698320
Estoy mostrando mi método:
public static void pendingListNotification(Context context, String totalCount) {
String CHANNEL_ID = "your_name";// The id of the channel.
CharSequence name = context.getResources().getString(R.string.app_name);// The user-visible name of the channel.
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationCompat.Builder mBuilder;
Intent notificationIntent = new Intent(context, HomeActivity.class);
Bundle bundle = new Bundle();
bundle.putString(AppConstant.PENDING_NOTIFICATION, AppConstant.TRUE);//PENDING_NOTIFICATION TRUE
notificationIntent.putExtras(bundle);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= 26) {
NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, name, importance);
mNotificationManager.createNotificationChannel(mChannel);
mBuilder = new NotificationCompat.Builder(context)
// .setContentText("4")
.setSmallIcon(R.mipmap.logo)
.setPriority(Notification.PRIORITY_HIGH)
.setLights(Color.RED, 300, 300)
.setChannelId(CHANNEL_ID)
.setContentTitle(context.getResources().getString(R.string.yankee));
} else {
mBuilder = new NotificationCompat.Builder(context)
// .setContentText("4")
.setSmallIcon(R.mipmap.logo)
.setPriority(Notification.PRIORITY_HIGH)
.setLights(Color.RED, 300, 300)
.setContentTitle(context.getResources().getString(R.string.yankee));
}
mBuilder.setContentIntent(contentIntent);
int defaults = 0;
defaults = defaults | Notification.DEFAULT_LIGHTS;
defaults = defaults | Notification.DEFAULT_VIBRATE;
defaults = defaults | Notification.DEFAULT_SOUND;
mBuilder.setDefaults(defaults);
mBuilder.setContentText(context.getResources().getString(R.string.you_have) + " " + totalCount + " " + context.getResources().getString(R.string.new_pending_delivery));//You have new pending delivery.
mBuilder.setAutoCancel(true);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}