I have generated local notifications using Service
. When the app is open, window the notifications works properly and they are show up. But when app is going to background or gets closed notifications, they are not showing. When I reopen my app all notifications shows up.
I have gone through lots of threads about this problem. So I tried startForeground
, AlarmManager
, BroadcastReceiver
and nothing helps. Still local notifications are showing only if app is open. I figured out that when I set battery settings to set to run my app in the background in phone settings, then it is working properly and notifications do show up. But the user will not know that he should do this.
MyService:
public class MyService2 extends Service {
private boolean running = true;
private MyAsyncTask myAsyncTask;
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startForeground(1, showAndGetNotification(getApplicationContext(), "Twoja aplikacja działa w tle", "", new Intent(getApplicationContext(), MainActivity.class)));
myAsyncTask = new MyAsyncTask();
myAsyncTask.execute();
return START_STICKY;
}
public void onDestroy() {
super.onDestroy();
stopForeground(true);
stopSelf();
if (myAsyncTask != null) {
myAsyncTask.cancel(true);
}
running = false;
SharedPreferences sharedPref = getSharedPreferences("service", Activity.MODE_PRIVATE);
boolean fromAppStop = sharedPref.getBoolean("fromAppStop", false);
if (!fromAppStop) {
Intent broadcastIntent = new Intent(this, SensorRestarterBroadcastReceiver.class);
sendBroadcast(broadcastIntent);
}
SharedPreferences.Editor editor = sharedPref.edit();
editor.putBoolean("fromAppStop", false);
editor.commit();
}
private class MyAsyncTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... voids) {
try {
while (running) {
List<Map<String, String>> medicinesToTake = getMedicinesToTake();
for (Map<String, String> medicineToTake : medicinesToTake) {
String medicineName = medicineToTake.keySet().toArray()[0].toString();
Thread.sleep(countSleepToNextTake(medicineToTake.get(medicineName)));
doAlarm("Czas na lek", medicineName, medicineName);
}
Thread.sleep(countLeftTimeForNextDay());
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
}
private void doAlarm(String title, String medicineName, String body) {
Intent intent = new Intent(getApplicationContext(), AlarmReceiver.class);
intent.putExtra("title", title);
intent.putExtra("medicineName", medicineName);
intent.putExtra("body", body);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
int id = generateUniqueId();
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), id, intent, PendingIntent.FLAG_CANCEL_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), pendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), pendingIntent);
}
}
public Notification showAndGetNotification(Context context, String title, String body, Intent intent) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Date now = new Date();
int notificationId = Integer.parseInt(new SimpleDateFormat("ddHHmmss", Locale.UK).format(now)) + new Random().nextInt();
//String channelId = "channel-01";
String channelId = UUID.randomUUID().toString();
String channelName = "Channel Name";
int importance = NotificationManager.IMPORTANCE_HIGH;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel mChannel = new NotificationChannel(
channelId, channelName, importance);
notificationManager.createNotificationChannel(mChannel);
}
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context, channelId)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setAutoCancel(true)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setContentText(body);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addNextIntent(intent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(
generateUniqueId(),
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
notificationManager.notify(notificationId, mBuilder.build());
return mBuilder.build();
}
private int generateUniqueId() {
UUID idOne = UUID.randomUUID();
String str = "" + idOne;
int uid = str.hashCode();
String filterStr = "" + uid;
str = filterStr.replaceAll("-", "");
return Integer.parseInt(str);
}
}
MyAlarmReceiver:
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String medicineName = intent.getStringExtra("medicineName");
String body = intent.getStringExtra("body");
Intent notificationIntent = null;
String title = intent.getStringExtra("title");
if (title.equals("Czas na lek")) {
notificationIntent = new Intent(context, TimeForMedicineActivity.class);
notificationIntent.putExtra("medicineName", medicineName);
} else if (title.equals("Twój lek się skończył")) {
notificationIntent = new Intent(context, AddOrDeleteMyMedicineActivity.class);
} else if (title.equals("Twój lek się kończy")) {
notificationIntent = new Intent(context, MainActivity.class);
}
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Date now = new Date();
int notificationId = Integer.parseInt(new SimpleDateFormat("ddHHmmss", Locale.UK).format(now)) + new Random().nextInt();
String channelId = UUID.randomUUID().toString();
String channelName = "Channel Name";
int importance = NotificationManager.IMPORTANCE_HIGH;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel mChannel = new NotificationChannel(
channelId, channelName, importance);
notificationManager.createNotificationChannel(mChannel);
}
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context, channelId)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setAutoCancel(true)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setContentText(body);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addNextIntent(notificationIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(
generateUniqueId(),
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
notificationManager.notify(notificationId, mBuilder.build());
}
private int generateUniqueId() {
UUID idOne = UUID.randomUUID();
String str = "" + idOne;
int uid = str.hashCode();
String filterStr = "" + uid;
str = filterStr.replaceAll("-", "");
return Integer.parseInt(str);
}
}