#StackBounty: #android #android-notifications #android-8.0-oreo Android 8/9 Notification scheduling

Bounty: 50

I have tried to schedule notifications for a specific date and time, but on majority of devices it seems that the notifications are not showing up. Before android 9/8 I have used AlarmManager which was pretty easy to use and it worked but the last 2 versions of android have changed this…(thanks google for making everything easier…)
So, here is my code that I use to schedule the notification. I’m using OneTimeWorkRequest

tag = new AlertsManager(this).getCarId(nrInmatriculare);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

    Data inputData = new Data.Builder().putString("type", alarmType).putString("nrInmatriculare", nrInmatriculare).build();

    OneTimeWorkRequest notificationWork = new OneTimeWorkRequest.Builder(NotifyWorker.class)
            .setInitialDelay(calculateDelay(when), TimeUnit.MILLISECONDS)
            .setInputData(inputData)
            .addTag(String.valueOf(tag))
            .build();
    WorkManager.getInstance().enqueue(notificationWork);
}
else {
    AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, when, (24 * 60 * 60 * 1000), pendingIntent);
}

Then the class that I’m using to show the notification is this:

public class NotifyWorker extends Worker {

    public NotifyWorker(@NonNull Context context, @NonNull WorkerParameters params) {
        super(context, params);
    }

    @NonNull
    @Override
    public Worker.Result doWork() {
        // Method to trigger an instant notification


        new NotificationIntentService().showNotification(getInputData().getString("type"),getInputData().getString("nrInmatriculare"), getApplicationContext());

        return Worker.Result.SUCCESS;
        // (Returning RETRY tells WorkManager to try this task again
        // later; FAILURE says not to try again.)
    }
}

and this one :

public class NotificationIntentService extends IntentService {
    final Uri notificationSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    int alarmId = 0;


    public NotificationIntentService() {
        super("NotificationIntentService");
    }


    @Override
    protected void onHandleIntent(Intent intent) {
            showNotification(intent);
    }

    //show notification with workmanager
    public void showNotification(String type, String nrInmatriculare, Context context){
        try
        {
            if (!TextUtils.isEmpty(type) && !TextUtils.isEmpty(nrInmatriculare)) {

                AlertsManager alertsManager = new AlertsManager(context);
                Notifications notification = alertsManager.getAlertForCar(nrInmatriculare);
                String text ="";
                Calendar endDate = null;
                String date = notification.EndDate.get(Calendar.YEAR) + "-" + (notification.EndDate.get(Calendar.MONTH)/10==0 ? "0"+(notification.EndDate.get(Calendar.MONTH)+1) : (notification.EndDate.get(Calendar.MONTH))+1) + "-" + (notification.EndDate.get(Calendar.DAY_OF_MONTH)/10==0 ? "0"+notification.EndDate.get(Calendar.DAY_OF_MONTH) : notification.EndDate.get(Calendar.DAY_OF_MONTH));
                text = context.getString(R.string.notificationText).toString().replace("#type#", type.toUpperCase()).replace("#nrInmatriculare#", nrInmatriculare).replace("#date#", date ).replace("#days#", String.valueOf(new Utils().getDateDifferenceInDays(Calendar.getInstance(), notification.EndDate)));
                alarmId = alertsManager.getCarId(nrInmatriculare);
                endDate = (Calendar)notification.EndDate.clone();

                if (Calendar.getInstance().getTimeInMillis() > endDate.getTimeInMillis()){ //current time is after the end date (somehow the alarm is fired)
                }
                else {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        //define the importance level of the notification
                        int importance = NotificationManager.IMPORTANCE_HIGH;
                        //build the actual notification channel, giving it a unique ID and name
                        NotificationChannel channel = new NotificationChannel("AppName", "AppName", importance);
                        //we can optionally add a description for the channel
                        String description = "A channel which shows notifications about events at Masina";
                        channel.setDescription(description);
                        //we can optionally set notification LED colour
                        channel.setLightColor(Color.MAGENTA);

                        // Register the channel with the system
                        NotificationManager notificationManager = (NotificationManager)context.
                                getSystemService(Context.NOTIFICATION_SERVICE);
                        if (notificationManager != null) {
                            notificationManager.createNotificationChannel(channel);
                        }

                        //---------

                        NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "AppName");
                        builder.setContentTitle(context.getString(R.string.app_name));
                        builder.setContentText(text);
                        builder.setSmallIcon(R.mipmap.ic_launcher);
                        builder.setAutoCancel(true);
                        builder.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS);
                        builder.setLights(Color.CYAN, 1000, 2000);
                        builder.setPriority(NotificationCompat.PRIORITY_HIGH);
                        builder.setSound(notificationSound);
                        builder.setStyle(new NotificationCompat.BigTextStyle().bigText(text));
                        Intent notifyIntent = null;
                        if (type.equals("CarteDeIdentitate") || type.equals("PermisDeConducere"))
                            notifyIntent = new Intent(context, PersonalDataActivity.class);
                        else
                            notifyIntent = new Intent(context, DetailActivity.class);
                        notifyIntent.putExtra("car", new SharedPreference(context).getCarDetailString(nrInmatriculare));
                        // Create the TaskStackBuilder and add the intent, which inflates the back stack
                        TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
                        stackBuilder.addNextIntentWithParentStack(notifyIntent);
                        //PendingIntent pendingIntent = PendingIntent.getActivity(context, alarmId, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
                        PendingIntent pendingIntent = stackBuilder.getPendingIntent(alarmId, PendingIntent.FLAG_UPDATE_CURRENT);
                        //to be able to launch your activity from the notification
                        builder.setContentIntent(pendingIntent);

                        //trigger the notification
                        NotificationManagerCompat notificationAlert = NotificationManagerCompat.from(context);
                        notificationManager.notify(alarmId, builder.build());
                    }
                }
            }
            else
            {
                Log.d("here","No extra");
            }

        }
        catch(Exception ex)
        {
            Log.d("here","Error");
        }
    }

}

what am I doing wrong? there is a best and more efficient way of doing this?

EDIT:
I would like to see an example about how to schedule a notification to a specific date + time, that really works.


Get this bounty!!!

#StackBounty: #android #android-service #android-notifications #foreground-service How to make notification dismissible when playing mu…

Bounty: 50

Spotify and Google Music allows a user to play music in background allowing also the media notification to be dismissible.
When you move one of these apps to background, then pause the playback, you are able to dismiss the media notification. However if you don’t dismiss the notification, so it is left in paused state for long time, the System won’t kill the “audio service” as the notification is always visible and immediately react to play/pause.

As far as I know it is not possible using foreground services as in order to dismiss the notification, we’d need to call stopForeground(false), which would let system to kill the service.

Here is how we do it right now, in our app:

When playback is started, we run MusicService as a foreground service with following code:

startForeground(mediaNotification)

Then, when user leave the app, he is able to control the playback via media notification. As the notification is tightly coupled with the MusicService, user won’t be able to dismiss it until we call:

stopForeground(false)

That’s why we call this method when user press pause button.
However this makes a Service background, so system will kill it in short period of time.

How Spotify and Google Music could workaround it? What is the way to achieve it?


Get this bounty!!!

#StackBounty: #android #android-notifications #huawei Strange allow/deny question on Huawei 5.1 phone when showing notification

Bounty: 50

So it turns out that Huawei phones with 5.1 can’t display MediaStyle notifications so while fixing that, I made a very simple notification test and I get a strange question asking Allow App Name to push messages to the notification panel.

I don’t use push in any way, in fact the screenshot below is for an app that all it does is show a sample notification, nothing else.

How can I make it not show that?

This is the code:

 Notification notification = new Notification.Builder(getApplicationContext())
                .setSmallIcon(R.drawable.ic_launcher_background)
                .setContentTitle("Track title")
                .setContentText("Artist - Album")
                .setOngoing(true)

                .addAction(R.drawable.ic_add_black_24dp, "fwd", pi)
                .addAction(R.drawable.ic_android_black_24dp, "fwd", pi)
                .addAction(R.drawable.ic_archive_black_24dp, "fwd", pi)
                .addAction(R.drawable.ic_arrow_back_black_24dp, "fwd", pi)
                .addAction(R.drawable.ic_aspect_ratio_black_24dp, "fwd", pi)
                .addAction(R.drawable.ic_fast_forward_black_24dp, "fwd", pi)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.vectors_525058875))
                .setAutoCancel(false)


                .build();
        notificationManager.notify(300, notification);

This is the screenshot.

enter image description here

What am I doing wrong? I tried taking out all the actions, that didn’t help. Took out title and context, that didn’t help. Took out large icon, auto cancel, ongoing, etc, didn’t help.

Please note that I am not using Push in any way and this doesn’t seem to be related to that. Also I a using the support compat libraries to make my notification but on this example I didn’t just to make sure that wasn’t the issue.


Get this bounty!!!