web-dev-qa-db-fra.com

LocalNotification avec AlarmManager et BroadcastReceiver ne se déclenche pas dans Android O (oreo)

J'ai mes notifications locales en cours d'exécution sur androïdes avant SDK 26

Mais dans un Android O j'ai l'avertissement suivant, et le récepteur de diffusion n'est pas renvoyé.

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

D'après ce que j'ai lu, les récepteurs de diffusion sont plus restreints dans Android O, mais si oui, comment dois-je planifier la diffusion si je veux qu'elle se lance même si l'activité principale ne fonctionne pas?

Dois-je utiliser des services plutôt que des récepteurs?

Voici le code de lancement 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);
}

Voici le code du récepteur:

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

}

Manifeste Android:

<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>
19
Hug

Android O est assez récent à ce jour. Par conséquent, j'essaie de digérer et de fournir des informations aussi précises que possible.

De https://developer.Android.com/about/versions/oreo/background.html#broadcasts

  • Les applications qui ciblent Android 8.0 ou supérieur ne peuvent plus enregistrer de récepteurs de diffusion pour les diffusions implicites dans leur manifeste.
    • Les applications peuvent utiliser Context.registerReceiver() au moment de l'exécution pour enregistrer un récepteur pour toute diffusion , que implicite ou explicite .
  • Les applications peuvent continuer à enregistrer des émissions explicites dans leur manifeste.

De plus, dans https://developer.Android.com/training/scheduling/alarms.html , les exemples utilisent une diffusion explicite et ne mentionnent rien de spécial concernant Android O.


Puis-je vous suggérer d'essayer la diffusion explicite comme suit?

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

}

Dans AndroidManifest, définissez simplement la classe comme

<receiver Android:name="org.yccheok.AlarmBroadcastReceiver" >
</receiver>
20
Cheok Yan Cheng

Aujourd'hui, j'ai eu le même problème et ma notification ne fonctionnait pas. Je pensais Le gestionnaire d'alarmes ne fonctionne pas dans Oreo mais le problème était avec Notification . Dans Oreo , nous devons ajouter Channel id. Veuillez jeter un œil à mon nouveau code:

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

Vérifiez cette solution. Cela a fonctionné comme par enchantement.

https://stackoverflow.com/a/43093261/469832

Je montre ma méthode:

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());
    }
5
Däñish Shärmà

Créez AlarmManager en définissant une intention explicite (définissez explicitement le nom de classe du récepteur de diffusion):

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

N'oubliez pas non plus de créer un canal de notification pour Android Oreo (API 26) lors de la création de la notification réelle:

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());
}
2
box

essayez ce code pour 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);
2
keyur sojitra