Menu
Who Do Is
  • Home
  • What
  • How
  • Is
  • Can
  • Are
  • Does
  • Do
  • Why
  • Who
  • Where
  • Which
  • Which
  • Should
  • Will
  • When
  • What’s
  • Did
Who Do Is

[ANSWERED] Show notification by an Android app through service running in background checking server (volley) even when the app is closed

Posted on November 14, 2022

Solution 1 :

Android has newer and better solution which perfectly suits your need

The WorkManager API is a suitable and recommended replacement for all previous Android background scheduling APIs

you can check official topics here : work manager

Solution 2 :

You have two options:

  1. Using WorkManager as stated in the above answers, but they may not be good if you want your task to be done at a very exact time. In some devices they work well, but in custom OS devices with battery optimizations they don’t work as you expect them to.

  2. if you want to do a task one a specific time use an alarm manager + broadcast recevier + intent service, just remember that you have to start the service as foreground service.

Solution 3 :

Thanks to @Farid for the solution.

Help links:

  1. Getting started
  2. WorkManager Periodicity
  3. Periodic Notification (enqueueUniquePeriodicWork)

Here is just the final piece of code:

  1. Add dependency in build.gradle(app):

     dependencies {
    
     ...
    
     def work_version = "2.4.0"
     implementation "androidx.work:work-runtime:$work_version"
     implementation "androidx.work:work-rxjava2:$work_version"
     androidTestImplementation "androidx.work:work-testing:$work_version"
     }
    
  2. Write the worker (NewNewsNotification.java)

     public class NewNewsNotification extends Worker {
    
     private static final String TAG="NewNewsNotification";
     private static Context rCtx;
     private RequestQueue reQueue;
    
     private String NEWS_TYPE= "post";
     private static final int EXEC_MIN= 15;
    
     AsyncJsonFetch mVolleyService;
     AsyncJsonData pResultCallback = null;
     //Context rCtx;
    
     public NewNewsNotification(
             @NonNull Context context,
             @NonNull WorkerParameters params) {
         super(context, params);
         rCtx= context;
     }
    
     public static void scheduleReminder() {
         Log.d(TAG, "queueing req");
         //WorkRequest notificationWork = new PeriodicWorkRequest.Builder(NewNewsNotification.class, 24, TimeUnit.HOURS).build();
    
         Constraints constraints = new Constraints.Builder()
                 .setRequiredNetworkType(NetworkType.CONNECTED)
                 .setRequiresStorageNotLow(true)
                 .build();
         PeriodicWorkRequest notificationWork = new PeriodicWorkRequest.Builder(NewNewsNotification.class, EXEC_MIN, TimeUnit.MINUTES).addTag(TAG).setConstraints(constraints).build();
         WorkManager instance = WorkManager.getInstance(rCtx);
         instance.enqueueUniquePeriodicWork(TAG, ExistingPeriodicWorkPolicy.KEEP, notificationWork);
     }
    
     @NonNull
     @Override
     public Result doWork() {
         try {
             Log.d(TAG, "fetch_last_update called");
             fetch_last_update();
             return Result.success();
         }catch (Throwable e) {
             e.printStackTrace();
             Log.e(TAG, "Error fetching data", e);
             return Result.failure();
         }
     }
    
     public void fetch_last_update()
     {
         postDetVolleyCallback();
         mVolleyService = new AsyncJsonFetch(pResultCallback, rCtx);
         try {
             JSONObject sendObj = new JSONObject();
             sendObj.put("lastdate", 1);
             sendObj.put("NEWS_TYPE", NEWS_TYPE);
             mVolleyService.newsDataVolley("POSTCALL", "news", sendObj);
         } catch (JSONException e) {
             e.printStackTrace();
         }
     }
    
     public void postDetVolleyCallback()
     {
         pResultCallback = new AsyncJsonData() {
             @RequiresApi(api = Build.VERSION_CODES.KITKAT)
             @Override
             public void notifySuccess(String requestType, JSONObject response) throws JSONException {
                 int stat = (int) response.get("status");
                 if (stat == 1) {
                     /***********************************************************/
                     JSONObject msgJSON = (JSONObject) response.get("msg");
                     int ldate= Integer.parseInt(msgJSON.get("date").toString());
                     JSONArray tparray= (JSONArray) msgJSON.get("news");
                     JSONObject tnews= (JSONObject) tparray.get(0);
                     String title= tnews.get("news_title").toString();
                     String excerpt= tnews.get("news_excerpt").toString();
                     int id= Integer.parseInt(tnews.get("ID").toString());
                     sendNotification(title, excerpt, id);
                 }
             }
             @Override
             public void notifyError(String requestType, VolleyError error) {
                 Log.d(TAG, "Volley requester " + requestType);
                 Log.d(TAG, "Volley JSON post" + "That didn't work!");
             }
         };
     }
    
     @RequiresApi(api = Build.VERSION_CODES.KITKAT)
     private void sendNotification(String title, String text, int id) {
         String cl_url= rCtx.getString(R.string.client_link);
         Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(cl_url+"?p="+id));
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
         PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
         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("default", "Default", NotificationManager.IMPORTANCE_DEFAULT);
             Objects.requireNonNull(notificationManager).createNotificationChannel(channel);
         }
         NotificationCompat.Builder notification = new NotificationCompat.Builder(getApplicationContext(), "default")
                 .setContentTitle(title)
                 .setContentText(text)
                 .setContentIntent(pendingIntent)
                 .setSmallIcon(R.mipmap.ic_launcher)
                 .setAutoCancel(true);
         Objects.requireNonNull(notificationManager).notify(id, notification.build());
     }
    

    }

  3. Call the Worker init in onCreate of MainActivity.java

     NewPostNotification.scheduleReminder();
    

Thats it.

READ  [ANSWERED] java - android.content.Context.getResources() on a null object reference
Powered by Inline Related Posts

Problem :

As stated in the question, I want a background process to run from an app (daily at 21:30) which makes a volley request to the server and display a notification depending upon the result. On clicking the notification, a specific link is opened (handled by the app).

The server request and response from the class (through async Volley) is working perfectly. The link-handler is also set up.

I did a research and is confused about the class to use. It seems, I can use:

  • Service OR
  • BroadcastReceiver (with AlarmManager)

Using AlarmManager (with the receiver tag added in the manifest), I have setup the following method called in the onCreate of MainActivity.java:

private void setAlarms()
{
    AlarmManager alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    Intent i = new Intent(this, NewNewsNotification.class);
    PendingIntent alarmIntent = PendingIntent.getBroadcast(this, 0, i, 0);



    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR_OF_DAY, 8);
    calendar.set(Calendar.MINUTE, 30);
    alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
            1000 * 60 * 60, alarmIntent);

    if (alarmMgr!= null) {
        alarmMgr.cancel(alarmIntent);
    }

}

NewNewsNotification.java

@Override
public void onReceive(Context context, Intent intent) {
    rCtx= context;
    fetch_last_update();
}

public void fetch_last_update()
{
    VolleyCallback();
    VolleyService = new AsyncJsonFetch(ResultCallback, rCtx);
    try {
        JSONObject sendObj = new JSONObject();
        mVolleyService.postDataVolley("POSTCALL", "news", sendObj);
    } catch (JSONException e) {
        e.printStackTrace();
    }
}
public void VolleyCallback()
{
    pResultCallback = new AsyncJsonData() {
        @Override
        public void notifySuccess(String requestType, JSONObject response) throws JSONException             {
            int stat = (int) response.get("status");

            if (stat == 1) {
                JSONObject msgJSON = (JSONObject) response.get("msg");
                Log.d(TAG, "msgJSON: "+msgJSON);
                /*The above log is working correctly. PROCESS THE JSON HERE AND GENERATE THE NOTIFICATION*/
            }
        }
        @Override
        public void notifyError(String requestType, VolleyError error) {
            Log.d(TAG, "Volley requester " + requestType);
            Log.d(TAG, "Volley JSON post" + "That didn't work!");
        }
    };
}

What is the correct way and how to implement it? How to initiate the clickable notification?

Comments

Comment posted by Martin S

Yes the WorkManager API is definitely what you are looking for. I’ve also implemented it in one of my projects and it works like a charm.

READ  [ANSWERED] android - Is there a way to store images directly into Firestore?
Powered by Inline Related Posts

Comment posted by sariDon

Thank to you all. Starting at once and will keep you updated…

Comment posted by sariDon

Thank you. Can I set weekly 21:30 with alarm manager?

Comment posted by Keivan.k

yes you can just set it’s time for a week later. As simple as that. Just remember to have BOOT_COMPLETED_RECEIVER because when you restart your device, alarms are all cleared.

Comment posted by sariDon

Ok. Thanks. Will give it a try.

Comment posted by sariDon

The ‘alarm manager’ is not working when the app is closed or phone is locked. It works fine when the app is open.

Comment posted by Keivan.k

are you opening the app via android studio?

Recent Posts

  • How can I play with my cat without toys?
  • What is a bag pipe band called?
  • Are Honda Civics actually fast?
  • Are Yankee candles toxic?
  • How do I pair my Michael Kors smartwatch with my Android?

Recent Comments

No comments to show.

Archives

  • January 2023
  • December 2022
  • November 2022
  • October 2022
  • September 2022

Categories

  • ¿Cómo
  • ¿Cuál
  • ¿Cuántas
  • ¿Cuánto
  • ¿Que
  • ¿Quién
  • 90” and 108” so you may have to round up to the nearest size.
  • and delete any Spotify folders from it. Once this is done
  • Android
  • Are
  • At
  • Bei
  • blink
  • C'est
  • Can
  • carbs
  • Comment
  • Did
  • Do
  • Does
  • During
  • For
  • Has
  • How
  • In
  • Is
  • Ist
  • Kann
  • Können
  • nouveau
  • On
  • or 108 inches.2020-08-03
  • Où
  • owning
  • Pourquoi
  • Puis-je
  • Quand
  • Quante
  • Quel
  • Quelle
  • Quelles
  • Quels
  • Qui
  • Should
  • Sind
  • Sollte
  • spiritual
  • tap the downward-facing arrow on the top left. A downward-facing arrow will appear underneath each song in the album; they'll turn green as the download completes.2020-07-28
  • Uncategorized
  • Wann
  • Warum
  • Was
  • Welche
  • Welcher
  • Welches
  • Welke
  • Wer
  • Were
  • What
  • What's
  • When
  • Where
  • Which
  • Who
  • Whose
  • Why
  • Wie
  • Will
  • Wo
  • Woher
  • you will receive two curtains each with the same measurements of width 66"" (168cm) x drop 54""(137cm).
  • you'll see a green downward-facing arrow next to each song.2021-02-26
©2023 Who Do Is | Powered by SuperbThemes & WordPress