I want to send a notification to user if there is any changes in firebase database. I have tried using Broadcast-Receiver
, Service
, Work-Manager
, Alarm-Manager
. But none of them works perfectly. It only works when app is running or in background and also working in some devices[tested in android 7] when app is closed. But In android 10[tested in Samsung and Xiaomi], it's not working when app is closed. When I turn off battery saver in my app in Xiaomi, it works sometime after closing app, then stops working. Some people said, You have turn-off battery saver
and turn-on auto-start mode
in Xiaomi
and do something
in other manufacturers phone
. But there are many app that shows notification even though I haven't open the app for more that 10/15 days and I have checked in app-info of those app that battery-saver in on and auto-start is off[checked in Xiaomi-android10]. What am I doing wrong?
Service:
public class ServiceManager extends Service {
public ServiceManager() {}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
getLastModifiedTime2(new HomePage.MyCallback() {
@Override
public void onCallback(String roll) {
SharedPreferences spExtra = getSharedPreferences("spExtra",MODE_PRIVATE);
if(!Objects.equals(spExtra.getString("1", "No changes"), roll)){
SharedPreferences.Editor editor = spExtra.edit();
editor.putString("1",roll);
editor.apply();
showNotification(getApplicationContext());
//
}
}
});
}
@Override
public void onDestroy() {
}
@Override
public int onStartCommand(Intent intent, int flags, int startid) {
System.out.println("called start command");
//
getLastModifiedTime2(new HomePage.MyCallback() {
@Override
public void onCallback(String roll) {
SharedPreferences spExtra = getSharedPreferences("spExtra",MODE_PRIVATE);
if(!Objects.equals(spExtra.getString("1", "No changes"), roll)){
SharedPreferences.Editor editor = spExtra.edit();
editor.putString("1",roll);
editor.apply();
showNotification(getApplicationContext());
}
}
});
//
return START_STICKY;
}
private void stopService() {
}
//not showing the method getlastmodifiedtime2 and shownotification;
}
and starting service that below:
startService(new Intent(this, ServiceManager.class));
Work-manager:
public class UploadWorker extends Worker {
public UploadWorker(
@NonNull Context context,
@NonNull WorkerParameters workerParams){
super(context, workerParams);
}
@NonNull
@Override
public Result doWork() {
System.out.println("UploadWorker called");
getLastModifiedTime2(new HomePage.MyCallback() {
@Override
public void onCallback(String roll) {
SharedPreferences spExtra = getApplicationContext().getSharedPreferences("spExtra",MODE_PRIVATE);
if(!Objects.equals(spExtra.getString("1", "No changes"), roll)){
SharedPreferences.Editor editor = spExtra.edit();
editor.putString("1",roll);
editor.apply();
showNotification(getApplicationContext());
//
}
//startNewRequest();
}
});
return Result.success();
//return Result.Retry.retry();
}
//not showing function getlastmodifiedtime2 and shownotification
}
calling worker like below:
PeriodicWorkRequest workRequest = new PeriodicWorkRequest
.Builder(UploadWorker.class,15,TimeUnit.MINUTES).build();
WorkManager.getInstance(this).enqueueUniquePeriodicWork("firebaseTest",
ExistingPeriodicWorkPolicy.KEEP,workRequest);
and alarm-manager code:
Calendar cal = Calendar.getInstance();
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 12);
calendar.set(Calendar.MINUTE, 25);
calendar.set(Calendar.SECOND, 30);
Intent intent = new Intent(HomePage.this, ServiceManager.class);
PendingIntent pintent = PendingIntent.getService(HomePage.this, 0, intent, 0);
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
System.out.println("called alarm-intent");
System.out.println("called"+cal.getTimeInMillis());
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 60*1000, pintent);
All of them are not working when app is closed. Some people says to use foreground services, but won't it show a notification all the time. What process should I use to do my work[notifying user when data is changed in firebase].
All of them given above aren't working when app is killed or closed. Then I tried Firebase cloud messaging
and it worked[tested in android 7,10] even if app is closed or killed.
RequestQueue requestQueue;
requestQueue = Volley.newRequestQueue(this);
--
public void sendNotificationToUser() {
JSONObject mainObj = new JSONObject();
try {
mainObj.put("to", "/topics/" + topic_name);//
JSONObject notificationObj = new JSONObject();
notificationObj.put("title", "About title");
notificationObj.put("body", "Enter you message here");
mainObj.put("notification", notificationObj);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, value,
mainObj, new Response.Listener<JSONObject>() {//value="https://fcm.googleapis.com/fcm/send"
@Override
public void onResponse(JSONObject response) {
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
}) {
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> header = new HashMap<>();
header.put("content-type", "application/json");
header.put("authorization", "key=" + server-key);
return header;
}
};
Toast.makeText(this, "Successfully added", Toast.LENGTH_SHORT).show();
requestQueue.add(jsonObjectRequest);
//
}
}
Make sure to import
implementation 'com.mcxiaoke.volley:library:1.0.19'
Don't put your server-key inside your app. You can use Firebase cloud function
for this[not free]. Above code will send notification to all of the user who are subcribed to topic_name
.