i am trying to write a periodic workmanager script but it just run when i open the app and it just run one time (not periodic) !
here is my main activity :
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_work);
Intent intent = new Intent();
PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this,0,intent,0);
NotifyWorker.pendingIntent = pendingIntent;
NotifyWorker.context = this;
PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest.Builder(NotifyWorker.class, 1, TimeUnit.MINUTES).build();
WorkManager.getInstance().enqueue(periodicWorkRequest);
}
}
and this is my dowork method :
public Result doWork() {
Log.i("wd","wd");
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context,"ctx")
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(),R.mipmap.ic_launcher))
.setSmallIcon(R.drawable.logo)
.setContentTitle("Title")
.setContentText("Desc")
.setContentIntent(pendingIntent);
android.app.NotificationManager notificationManager =
(android.app.NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 , notificationBuilder.build());
return Result.SUCCESS;
}
why its not run every 1 minute ? what i miss ?
Per the PeriodicWorkRequest.Builder documentation:
The intervalMillis must be greater than or equal to PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS
That value is currently set to 900000 - i.e, 15 minutes.
First of all, you can disagree with my answer but here is the hack which I used in my project and this work very accurately without gives any problem.
It's time to see the code. One thing I pointed later and must read this point after the code. SECTION IMP
//this code in your activity, fragment or any other class
notify_switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked)
{
OneTimeWorkRequest track_share_market = new OneTimeWorkRequest.Builder(NotificationWorker.class).setInitialDelay(1,TimeUnit.MINUTES).addTag("Stock_Market").build();
WorkManager.getInstance().enqueue(track_share_market);
Log.d("RishabhNotification","SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSs");
}
else {
Log.d("RishabhNotification","FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
WorkManager.getInstance().cancelAllWorkByTag("Stock_Market");
}
}
});
Now your Worker class Code
public class NotificationWorker extends Worker {
public NotificationWorker(#NonNull Context context, #NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
#NonNull
#Override
public Result doWork() {
try {
//Some heavy operation as you want there is no need to make another thread here
//track some website for weather changes or stock market changes
//In my case doWork takes only 10sec for executing this method
ShowNotification("Market Up","Gold Price goes upto ₹25,000 ","Check the app for the new update");
StartNewRequest();
return Result.success();
} catch (Exception e) {
e.printStackTrace();
StartNewRequest();
Log.d("RishabhNotification","ERERERERERERERERERERERERERERERERERERERERERERERERERERERE");
return Result.failure();
}
}
private void StartNewRequest()
{
OneTimeWorkRequest track_market = new OneTimeWorkRequest.Builder(NotificationWorker.class).setInitialDelay(1,TimeUnit.MINUTES).addTag("Stock_Market").build();
WorkManager.getInstance().enqueue(track_market);
}
private void ShowNotification(String Message, String name, String Information)
{
NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
String NOTIFICATION_CHANNEL_ID = "my_channel_id_01";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "Stock Market", NotificationManager.IMPORTANCE_HIGH);
// Configure the notification channel.
notificationChannel.setDescription("Channel description");
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.GREEN);
notificationChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
notificationChannel.enableVibration(true);
notificationChannel.setSound(null,null );
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
notificationManager.createNotificationChannel(notificationChannel);
}
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(getApplicationContext(), NOTIFICATION_CHANNEL_ID);
Uri uri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
notificationBuilder.setAutoCancel(false)
.setDefaults(Notification.DEFAULT_SOUND|Notification.DEFAULT_VIBRATE|Notification.DEFAULT_LIGHTS)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setSound(uri)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setPriority(Notification.PRIORITY_MAX)
.setContentTitle(Message)
.setContentText(name)
.setContentInfo(Information);
notificationManager.notify(/*notification id*/1, notificationBuilder.build());
}
}
Now Read the SECTION IMP point
This Code perfectly working in Emulator, Pixel phone, Samsung phone, Moto phone, Asus Phone, One plus phone but this same code I tested in the Xioami Devices and Huawei devices they both devices not run the code for every specific time interval(They both run the code but time may be changed) which I define in my code. I don't know why is this happen on both devices. Maybe some optimization. Check this link for more https://www.reddit.com/r/androiddev/comments/9ra0iq/workmanager_reliability_for_periodic_tasks_on/
I have not tested this code in vivo and Oppo devices.
Related
In my app it is important to display a notification at a certain point in time (as alarm for Accident detection if the user does not move anymore).
This alarm is working on all Android versions < 10 and is also working with the most Phones with android 10. One of the exceptions seams to be the Samsung S10 (Plus). With this Phone all notifications are for 1-2 minutes delayed if the Phone is in Sleep-Mode (Display is black)!
Here some code snippets to show the Problem.
First we tried to do it with an JobIntentService:
public class MyNotificationService extends JobIntentService {
....
#Override
protected void onHandleWork(#NonNull Intent intent) {
NotificationType notificationType = NotificationType.valueOf(intent.getExtras().getInt(INTENT_EXTRA_NOTIFICATION_TYPE));
boolean alarmingNotification = intent.getBooleanExtra(INTENT_EXTRA_NOTIFICATION_TYPE_ALARM, false);
NotificationStorage notificationStorage = NotificationStorage.getInstance(context);
notificationStorage.setPendingNotificationType(notificationType);
intent.putExtra(INTENT_EXTRA_ALARM_NOTIFICATION, alarmingNotification);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.setClass(context, PopupOnLockScreenActivity.class);
startActivity(notificationStarterIntent)
}
...
}
Result: Popup does not open immediately as expected (1-2 minutes delayed)
Then i tried as workaround with Notification with a NotificationChannel (IMPORTANCE_HIGH) and NotificationCompat.Builder (PRIORITY_MAX):
public class MyNotificationService extends JobIntentService {
....
#Override
protected void onHandleWork(#NonNull Intent intent) {
NotificationType notificationType = NotificationType.valueOf(intent.getExtras().getInt(INTENT_EXTRA_NOTIFICATION_TYPE));
boolean alarmingNotification = intent.getBooleanExtra(INTENT_EXTRA_NOTIFICATION_TYPE_ALARM, false);
NotificationStorage notificationStorage = NotificationStorage.getInstance(context);
notificationStorage.setPendingNotificationType(notificationType);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Log.d(TAG, "showPopupOnLockScreen XXX");
String channelName = getResources().getString(R.string.safety_notification_channel_name);
//String description = getString(R.string.channel_description);
String description = "XXXXX";
int importance = NotificationManager.IMPORTANCE_HIGH;
android.app.NotificationChannel channel = new android.app.NotificationChannel(UepaaNetAndroidConstants.ANDROID_NOTIFICATION_CHANNEL_ID, channelName, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
android.app.NotificationManager notificationManager = getSystemService(android.app.NotificationManager.class);
notificationManager.createNotificationChannel(channel);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channel.getId())
.setSmallIcon(R.drawable.notification_symptom_small)
.setContentTitle("My notification")
.setContentText("Hello World!")
.setPriority(NotificationCompat.PRIORITY_MAX)
.setContentIntent(pendingIntent)
.setAutoCancel(true);
notificationManager.notify(123, builder.build());
}
}
...
}
Result: Notification will be not showed immediately as expected (1-2 minutes delayed)
Wake-Up does not work on Samsung S10
I also tried to put the app in the lists to prevent the app from Battery-Manager and Sleep-Modes. (https://www.youtube.com/watch?v=npGw_r-v25k) But the problem still exists!
Can somebody help me? Our app is useless without notifications.
To reproduce this problem I pushed a project on github: https://github.com/gatschet/androidAlarmTest.git
I have created a foreground service using the following code which is in the override method OnStartCommand inside a service class called DemoIntentService.cs.
base.OnStartCommand(intent,flags,startId);
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
Intent notificationIntent = new Intent(this, Java.Lang.Class.FromType(typeof(DemoIntentService)));
PendingIntent pendingIntent = PendingIntent.GetActivity(this, 0, notificationIntent, 0);
Notification.Builder notificationBuilder = new Notification.Builder(this, "Example_Service_Channel")
.SetSmallIcon(Resource.Drawable.AlertLightFrame)
.SetContentTitle(Resources.GetString(Resource.String.DialogAlertTitle))
.SetContentText(Resources.GetString(Resource.String.SelectTextMode))
.SetContentIntent(pendingIntent);
Notification notificationAfterBuild = notificationBuilder.Build();
StartForeground(123, notificationAfterBuild);
InitializeAlarmManager();
setAlarm();
}
return StartCommandResult.RedeliverIntent;
Obviously, the code above is only for Android Oreo 8.0 and above, the service works fine and the notification will not be cleared even though I close the app manually. (That's good, that's what I want !). However, when I use the above code to test on Android Nougat 7.1.1, it would not work.
Firstly, I have researched online they said there is no need to create a notification channel for Android below 8.0, so I remove the "Example_Service_Channel" which is the channelID. The app was deployed successfully, but the notification gone when I kill the app. Second thing, when I removed the channelID, Xamarin throw me a warning said "Notification.Builder.Builder(Context) is obsolete : deprecated" and the line has turn yellow. I ignore the error and deploy the app. The service did run as it is visible in the running service inside the developer options. But when I killed the app, the service and notification gone together. Is there any other way to create a foreground notification service that will never end for Android below 8.0? Thanks for any comment and idea.
i write a simple sample,and it works on Android 7.1. i just delete the Notification Channel from Android 8.0
1.Create a Service MyService.cs :
[Service(Enabled = true)]
public class MyService : Service
{
private Handler handler;
private Action runnable;
private bool isStarted;
private int DELAY_BETWEEN_LOG_MESSAGES = 5000;
private int NOTIFICATION_SERVICE_ID = 1001;
private int NOTIFICATION_AlARM_ID = 1002;
public override void OnCreate()
{
base.OnCreate();
handler = new Handler();
//here is what you want to do always, i just want to push a notification every 5 seconds here
runnable = new Action(() =>
{
if (isStarted)
{
DispatchNotificationThatAlarmIsGenerated("I'm running");
handler.PostDelayed(runnable, DELAY_BETWEEN_LOG_MESSAGES);
}
});
}
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
if (isStarted)
{
// service is already started
}
else
{
DispatchNotificationThatServiceIsRunning();
handler.PostDelayed(runnable, DELAY_BETWEEN_LOG_MESSAGES);
isStarted = true;
}
return StartCommandResult.Sticky;
}
public override void OnTaskRemoved(Intent rootIntent)
{
//base.OnTaskRemoved(rootIntent);
}
public override IBinder OnBind(Intent intent)
{
// Return null because this is a pure started service. A hybrid service would return a binder that would
// allow access to the GetFormattedStamp() method.
return null;
}
public override void OnDestroy()
{
// Stop the handler.
handler.RemoveCallbacks(runnable);
// Remove the notification from the status bar.
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.Cancel(NOTIFICATION_SERVICE_ID);
isStarted = false;
base.OnDestroy();
}
//start a foreground notification to keep alive
private void DispatchNotificationThatServiceIsRunning()
{
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.SetDefaults((int)NotificationDefaults.All)
.SetSmallIcon(Resource.Drawable.Icon)
.SetVibrate(new long[] { 100, 200, 300, 400, 500, 400, 300, 200, 400 })
.SetSound(null)
.SetPriority(NotificationCompat.PriorityDefault)
.SetAutoCancel(false)
.SetContentTitle("Mobile")
.SetContentText("My service started")
.SetOngoing(true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.From(this);
StartForeground(NOTIFICATION_SERVICE_ID, builder.Build());
}
//every 5 seconds push a notificaition
private void DispatchNotificationThatAlarmIsGenerated(string message)
{
var intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop);
var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);
Notification.Builder notificationBuilder = new Notification.Builder(this)
.SetSmallIcon(Resource.Drawable.Icon)
.SetContentTitle("Alarm")
.SetContentText(message)
.SetAutoCancel(true)
.SetContentIntent(pendingIntent);
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.Notify(NOTIFICATION_AlARM_ID, notificationBuilder.Build());
}
}
2.in your activity :
protected override void OnResume()
{
base.OnResume();
StartMyRequestService();
}
public void StartMyRequestService()
{
var serviceToStart = new Intent(this, typeof(MyService));
StartService(serviceToStart);
}
try to start the service with
ContextCompat.startForegroundService(context,intent)
build the notification then call
startForeground(1, notification)
in onCreate() or onStartCommand() whatever works for you but after the service started and running don't forget to ask for permission
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
I'm trying to periodically run a service even when the app is killed or is in the background using workManager.
My RequestService class is given below:-
public class RequestService extends Worker {
public RequestService(#NonNull Context context, #NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
#NonNull
#Override
public Result doWork() {
displayNotification("MY Worker", "Background work Started");
Log.i("BackJob","Running");
return Result.SUCCESS;
}
private void displayNotification(String title, String task){
NotificationManager notificationManager = (NotificationManager)getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel("MyApp","My Notifications",
NotificationManager.IMPORTANCE_HIGH);
notificationManager.createNotificationChannel(channel);
}
NotificationCompat.Builder notification = new NotificationCompat.Builder(getApplicationContext(), "My Notifications").
setContentTitle(title).setContentText(task)
.setSmallIcon(R.mipmap.ic_launcher);
notificationManager.notify(130, notification.build());
}}
This is the main activity code:-
final PeriodicWorkRequest WorkReq = new PeriodicWorkRequest.Builder(RequestService.class,15,TimeUnit.MINUTES).build();
WorkManager.getInstance().enqueue(WorkReq);
The issue is if the app is killed or is in the background then workmanager stops working.
I'm testing this on a samsung device with android version pie.
P.S :- if the app is open then i see notifications continuously after 15 mins....however as soon as i close the app.....it stops working.....and there are no more notifications
You can use foreground Service for this , Foreground Service work when app is in background.
add this method in downork method
setForegroundAsync(createForegroundInfo(progress));
Override this method in workermanager class
#NonNull
private ForegroundInfo createForegroundInfo(#NonNull String progress) {
Context context = getApplicationContext();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel chan = new NotificationChannel("1", "channelName", NotificationManager.IMPORTANCE_NONE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);
}
Notification notification = new NotificationCompat.Builder(context, "1")
.setContentTitle("title")
.setTicker("title")
.setSmallIcon(R.drawable.ic_launcher_background)
.setOngoing(true)
.build();
return new ForegroundInfo(1,notification);
}
Now you app will work in the background.
As Per the PeriodicWorkRequest.Builder official documentation available here
The intervalMillis must be greater than or equal to PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS
This value is currently set to 900000 ms i.e, 15 minutes.
This is a working example that currently shows any notification regarding the version of the SO. But seemingly the problem can be related with the notify method from NotificationManagerCompat
private void makeStatusNotification(String message, Context context) {
String channelId = context.getString(R.string.worker_sync_notif_channel_id);
// Make a channel if necessary
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Create the NotificationChannel, but only on API 26+
CharSequence name = context.getString(R.string.worker_sync_notif_channel_name);
String description = context.getString(R.string.worker_sync_notif_channel_description);
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel channel = new NotificationChannel(channelId, name, importance);
channel.setDescription(description);
// Add the channel
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager != null) {
notificationManager.createNotificationChannel(channel);
}
}
// Create the notification
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, channelId)
.setSmallIcon(R.drawable.ic_cloud_upload)
.setContentTitle(context.getString(R.string.worker_sync_notif_title))
.setContentText(context.getString(R.string.worker_sync_notif_subject))
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(message))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setVibrate(new long[0])
.setAutoCancel(true);
// Show the notification
NotificationManagerCompat.from(context).notify(NOTIFICATION_ID, builder.build());
}
I have a messenger application and now I'm doing push notifications part. I'm using FCM (Firebase Cloud Messaging)for this. Now I have a problem. For example introduce 2 users (user1 and user2). If user1 writes me, I'm getting notification with FCM and show it. When user2 writes me, I'm creating new notification for it. But when user1 writes me again and I don't removed my user1 notification, I need to update the notification, else create new. I think you understand me. Now I am stuck at update part, because every time I'm create a new notification on message income.
I searched and found something. It says I have to use NotificationListenerService for this and use getActiveNotifications() for getting all active notifications in status bar.
So I tried something, but I'm getting null. I enabled this application in Notification Access, so I think this is not the problem.
I registered my services in manifest file.
Here is my code, where I created my FCM service. If I done something wrong in my code, please fix it.
public class FireBaseService extends FirebaseMessagingService {
private static final String TAG = "FireBaseMessagingServiceTag";
#SuppressLint("LongLogTag")
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// Handle FCM messages here.
Intent service = new Intent(FireBaseService.this, NotificationService.class);
startService(service);
//I think I'm doing wrong here.
NotificationService notificationService = new NotificationService();
StatusBarNotification[] activeNotifications = notificationService.getActiveNotifications();
Log.d(TAG, "Array: " + Arrays.toString(activeNotifications));
//show notification
}
}
And here is the NotificationService class.
public class NotificationService extends NotificationListenerService {
#Override
public IBinder onBind(Intent intent) {
return super.onBind(intent);
}
#Override
public void onListenerConnected() {
super.onListenerConnected();
}
#Override
public void onNotificationPosted(StatusBarNotification sbn){
// Implement what you want here
}
#Override
public void onNotificationRemoved(StatusBarNotification sbn){
// Implement what you want here
}
#Override
public StatusBarNotification[] getActiveNotifications() {
return super.getActiveNotifications();
}
}
So this is all I done. Can you help me? Thank you and please fix my code, if I done something wrong instead of giving bad vote to my question.
Here is the notification part.
private void showNotification(String title, String body) {
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
String NOTIFICATION_CHANNEL_ID = "com.example.fcmnotification.FireBaseService";
if(notificationManager != null) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel(
NOTIFICATION_CHANNEL_ID, "NotificationManager",
NotificationManager.IMPORTANCE_DEFAULT);
notificationChannel.setDescription("My Channel");
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.BLUE);
notificationChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
notificationManager.createNotificationChannel(notificationChannel);
}
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
notificationBuilder.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_ALL)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher_notification)
.setContentTitle(title)
.setContentText(body)
.setContentInfo("info");
notificationManager.notify(new Random().nextInt(), notificationBuilder.build());
}
}
You don't need a NotificationListenerService. Just get the active notifications from the NotificationManager
NotificationManager nm = (NotificationManager)ctx.getSystemService(Activity.NOTIFICATION_SERVICE);
StatusBarNotification[] statusNotifs = null;
try {
statusNotifs = nm.getActiveNotifications();
} catch (Throwable t) {
// it can crash
}
if (statusNotifs != null) for (StatusBarNotification n : statusNotifs) {
Notification notif = n.getNotification();
try {
String ntext = notif.extras.getCharSequence(Notification.EXTRA_TEXT).toString();
// do something
} catch (Throwable t) {
// can crash
}
}
Am Using androidx Work manager API, in Work manager am using PeriodicWorkRequest to trigger the Work for every 4 hours. But it works only once after run the application.
PeriodicWorkRequest Coding:-
Constraints constraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build();
PeriodicWorkRequestpendingCampaignWork = new PeriodicWorkRequest.Builder(PendingCampaignWorker.class, 4, TimeUnit.HOURS)
.setConstraints(constraints)
.build();
Work Manger Code to Enqueue the Request:-
WorkManager.getInstance().enqueueUniquePeriodicWork(LATEST_CAMPAIGN_WORK, ExistingPeriodicWorkPolicy.KEEP, pendingCampaignWork);
For testing am change System time Manually to 4 hours after run the application in emulator to trigger the Work.
Is there any issue in my code help me to solve the issue.
Update:-
Work Manager is working fine, its not working based on System time as m.hassan said in answer section. Am test to trigger the work for every 20 minutes, its working fine.
Work Manager Not not based on system time. You can make a periodic work request of 15 minutes. This way you can test your code.
here's an example:
My Periodic Work Request:
private static final String TAG = "PeriodicWorkTag";
private static final int PERIODIC_WORK_INTERVAL = 15;
public static void schedulePeriodicWork() {
androidx.work.PeriodicWorkRequest periodicWorkRequest = new androidx.work.PeriodicWorkRequest.Builder(PeriodicWorkRequest.class, PERIODIC_WORK_INTERVAL,
TimeUnit.MINUTES)
.addTag(TAG)
.build();
WorkManager.getInstance().enqueueUniquePeriodicWork(TAG, ExistingPeriodicWorkPolicy.KEEP, periodicWorkRequest);
}
public static void cancelPeriodicWork() {
WorkManager.getInstance().cancelAllWorkByTag(TAG);
}
My Worker Class:
public static final String CHANNEL_ID = "VERBOSE_NOTIFICATION" ;
public PeriodicWorkRequest(#NonNull Context context, #NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
#NonNull
#Override
public Result doWork() {
showNotification(getApplicationContext());
return Result.SUCCESS;
}
private void showNotification(Context context) {
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("My notification")
.setContentText("ddd")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText("ddd"))
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "Channel_name";
String description = "description";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
notificationManager.notify(100, mBuilder.build());
}
This did the trick in my case: Add your app to IGNORE_BATTERY_OPTIMIZATIONS list.
#SuppressLint("BatteryLife")
public void showIgnoreBatteryOpt() {
String packageName = getPackageName();
Intent intent = new Intent();
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (!pm.isIgnoringBatteryOptimizations(packageName)) {
Log.d(TAG, "showIgnoreBatteryOpt: NOT ignoring");
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
startActivity(intent);
}
else {
Log.d(TAG, "showIgnoreBatteryOpt: ignoring");
}
}
Add to AndroidManifest.xml:
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>