Android 8/9 Notification scheduling
Try below code, i have used it in one of my application which works fine for me.
private void startWorkForWeekNotification() {
OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(
OpenAppNotifyWorker.class)
.setInitialDelay(OpenAppNotifyWorker.NOTIFY_TO_OPEN_APP_IN_DAYS, TimeUnit.DAYS)
.build();
WorkManager.getInstance().beginUniqueWork(
OpenAppNotifyWorker.WORKER_NAME,
ExistingWorkPolicy.REPLACE,
oneTimeWorkRequest).enqueue();
}
Worker Class
public class OpenAppNotifyWorker extends Worker {
public static final String WORKER_NAME = "OpenAppNotifyWorker";
public static final int NOTIFY_TO_OPEN_APP_IN_DAYS = 7;
public OpenAppNotifyWorker(@NonNull Context context,
@NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
@NonNull
@Override
public Result doWork() {
NotificationUtils
.showNotification(getApplicationContext(), NotificationUtils.UPDATE_CHANNEL_ID,
NotificationUtils.UPDATE_NOTIFICATION_ID);
return Result.success();
}
}
NotificationUtils Class
public class NotificationUtils {
public static final String UPDATE_CHANNEL_ID = "updates";
public static final int UPDATE_NOTIFICATION_ID = 1;
public static final int NOTIFICATION_REQUEST_CODE = 50;
public static void showNotification(Context context, String channelId, int notificationId) {
createNotificationChannel(context, channelId);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
context, channelId)
.setSmallIcon(R.drawable.ic_splash_logo)
.setContentTitle(context.getString(R.string.title_notification))
.setContentText(context.getString(R.string.msg_body_notification))
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
NotificationManagerCompat notificationManager = NotificationManagerCompat
.from(context);
notificationManager.notify(notificationId, mBuilder.build());
}
public static void createNotificationChannel(Context context, String channelId) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//TODO change channel name and description
CharSequence name = context.getString(R.string.notification_channel_updates);
String description = context.getString(R.string.desc_notification_channel);
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(
channelId, name, importance);
channel.setDescription(description);
NotificationManager notificationManager = context
.getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
public static void createPushNotification(Context context, String message) {
NotificationUtils
.createNotificationChannel(context, NotificationUtils.UPDATE_CHANNEL_ID);
Intent notificationIntent = new Intent(context, SplashActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
notificationIntent.setAction(Intent.ACTION_MAIN);
notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
notificationIntent.putExtra(FcmPushListenerService.EXTRAS_NOTIFICATION_DATA, message);
PendingIntent contentIntent = PendingIntent
.getActivity(context, NOTIFICATION_REQUEST_CODE, notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
context, NotificationUtils.UPDATE_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification_app_logo)
.setContentTitle(context.getString(R.string.app_name))
.setContentText(message)
.setAutoCancel(true)
.setContentIntent(contentIntent)
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
NotificationManagerCompat notificationManager = NotificationManagerCompat
.from(context);
notificationManager.notify(NotificationUtils.UPDATE_NOTIFICATION_ID, mBuilder.build());
}
public static void cancelAllNotification(Context context) {
NotificationManagerCompat notificationManager = NotificationManagerCompat
.from(context);
notificationManager.cancelAll();
}
}
if you want to start service you can do that by following :
public class OpenAppNotifyWorker extends Worker {
public static final String WORKER_NAME = "OpenAppNotifyWorker";
public static final int NOTIFY_TO_OPEN_APP_IN_DAYS = 7;
public Context context;
public OpenAppNotifyWorker(@NonNull Context context,
@NonNull WorkerParameters workerParams) {
this.context = context
super(context, workerParams);
}
@NonNull
@Override
public Result doWork() {
context.startService(new NotificationIntentService())
return Result.success();
}
}
Here is one working implementation that I've used in one of my project.
Add this to your build.gradle (app)
(Since it's in Kotlin)
//android-jet pack
implementation 'android.arch.work:work-runtime-ktx:1.0.1'
or using Android X:
implementation "androidx.work:work-runtime-ktx:2.5.0"
https://developer.android.com/jetpack/androidx/releases/work
Create a method scheduleNotification
.
Pass your necessary data
fun scheduleNotification(timeDelay: Long, tag: String, body: String) {
val data = Data.Builder().putString("body", body)
val work = OneTimeWorkRequestBuilder<NotificationSchedule>()
.setInitialDelay(timeDelay, TimeUnit.MILLISECONDS)
.setConstraints(Constraints.Builder().setTriggerContentMaxDelay(Constant.ONE_SECOND, TimeUnit.MILLISECONDS).build()) // API Level 24
.setInputData(data.build())
.addTag(tag)
.build()
WorkManager.getInstance().enqueue(work)
}
NotificationSchedule
Class
class NotificationSchedule (var context: Context, var params: WorkerParameters) : Worker(context, params) {
override fun doWork(): Result {
val data = params.inputData
val title = "Title"
val body = data.getString("body")
TriggerNotification(context, title, body)
return Result.success()
}
}
TriggerNotification
Class. Customize this class according to your need
class TriggerNotification(context: Context, title: String, body: String) {
init {
sendNotification(context, title, body)
}
private fun createNotificationChannel(context: Context, name: String, description: String): String {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
val chanelId = UUID.randomUUID().toString()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val importance = NotificationManager.IMPORTANCE_HIGH
val channel = NotificationChannel(chanelId, name, importance)
channel.enableLights(true)
channel.enableVibration(true)
channel.description = description
channel.lightColor = Color.BLUE
channel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
val notificationManager = context.getSystemService(NotificationManager::class.java)
notificationManager?.createNotificationChannel(channel)
}
return chanelId
}
private fun sendNotification(context: Context, title: String, body: String) {
val notificationManager = NotificationManagerCompat.from(context)
val mBuilder = NotificationCompat.Builder(context, createNotificationChannel(context, title, body))
val notificationId = (System.currentTimeMillis() and 0xfffffff).toInt()
mBuilder.setDefaults(Notification.DEFAULT_ALL)
.setTicker("Hearty365")
.setContentTitle(title)
.setContentText(body)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setSmallIcon(R.drawable.icon)
.setContentInfo("Content Info")
.setAutoCancel(true)
notificationManager.notify(notificationId, mBuilder.build())
}
}