Я сгенерировал локальные уведомления, используя Service
. Когда приложение открыто, окно уведомлений работает правильно, и они отображаются. Но когда приложение переходит в фоновый режим или получает закрытые уведомления, они не отображаются. Когда я снова открываю свое приложение, отображаются все уведомления.
Я прошел через множество тем об этой проблеме. Поэтому я попробовал startForeground
, AlarmManager
, BroadcastReceiver
и ничего не помогает. Тем не менее локальные уведомления отображаются, только если приложение открыто. Я выяснил, что когда я установил параметры батареи для запуска моего приложения в фоновом режиме в настройках телефона, то он работает правильно, и уведомления отображаются. Но пользователь не будет знать, что он должен сделать это.
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);
}
}