Я создаю приложение, которое создает службу, которая запускает будильник, когда у людей дни рождения (в 12.00). Приложение основано на базе данных реального времени firebase. Проблема, с которой я столкнулся, следующая:
Служба не работает в первый раз при запуске приложения, например: Я получаю тост "Служба запущена "но служба отсутствует в запущенных службах, когда приложение очищено.
2. Когда приложение открывается во второй раз, служба работает нормально (также подает сигналы тревоги)
3. Я пытался реализовать Диспетчер работ, но, похоже, он не работает на Android Nougat и выше. (Где как он должен работать!)
4. Уведомления запускаются при открытии приложения, а также есть 2 или более уведомлений когда приложение находится в фоновом режиме.
Итак, что здесь не так?
Вот мои классы:
NotificationHelper. java
public class NotificationHelper extends ContextWrapper {
public NotificationHelper(Context base, int peopleCount) {
super(base);
this.peopleCount = peopleCount;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelID, channelName, NotificationManager.IMPORTANCE_HIGH);
getManager().createNotificationChannel(channel);
}
}
private int peopleCount;
public static final String channelID = "channel_145";
public static final String channelName = "Birthday Notification";
private NotificationManager mManager;
public NotificationManager getManager() {
if (mManager == null) {
mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
return mManager;
}
public NotificationCompat.Builder getChannelNotification() {
return new NotificationCompat.Builder(getApplicationContext(), channelID)
.setContentTitle("Birthday Reminder!")
.setContentText( peopleCount + " people have birthday today!")
.setSmallIcon(R.drawable.ic_stat_notify)
.setColor(Color.GREEN)
.setAutoCancel(true)
.setContentIntent(PendingIntent.getActivity(this, 0, new Intent(this, Birthday.class), PendingIntent.FLAG_UPDATE_CURRENT));
}
}
Myservice. java
public class MyService extends Service {
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Toast.makeText(getApplicationContext(),"Service Started",Toast.LENGTH_LONG).show();
//StartWorker();
StartAlarm();
return Service.START_REDELIVER_INTENT;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
public void StartWorker()
{
Calendar currentDate = Calendar.getInstance();
Calendar dueDate = Calendar.getInstance();
dueDate.set(Calendar.HOUR_OF_DAY, 0);
dueDate.set(Calendar.MINUTE, 0);
dueDate.set(Calendar.SECOND, 0);
if (dueDate.before(currentDate)) {
dueDate.add(Calendar.HOUR_OF_DAY, 24);
}
long timeDiff = ((dueDate.getTimeInMillis())-(currentDate.getTimeInMillis()));
final OneTimeWorkRequest oneTimeWorkRequest = new
OneTimeWorkRequest.Builder(Myworker.class)
.setInitialDelay(timeDiff, TimeUnit.MILLISECONDS)
.build();
WorkManager.getInstance(getApplicationContext()).enqueue(oneTimeWorkRequest);
}
public void StartAlarm()
{
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE,0);
calendar.set(Calendar.SECOND,1);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent alarmIntent = new Intent(this, AlarmReceiver.class);
alarmIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1456, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent);
}
@Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(getApplicationContext(),"Service Destroyed",Toast.LENGTH_LONG).show();
Intent intent = new Intent(this, MyService.class);
startService(intent);
}
}
AlarmReceiver. java
public class AlarmReceiver extends BroadcastReceiver {
private DatabaseReference myRef;
private ArrayList<String> allPeoples;
private int numberOfPeoples;
private Context ctx;
@Override
public void onReceive(Context context, Intent intent) {
ctx = context;
FirebaseDatabase database = FirebaseDatabase.getInstance();
myRef = database.getReference("Users");
myRef.keepSynced(true);
initPeoples();
}
public String getCurrentDate() {
Calendar calendar = Calendar.getInstance();
SimpleDateFormat mdformat = new SimpleDateFormat("d MMMM");
String strDate = mdformat.format(calendar.getTime());
return strDate;
}
private void initPeoples() {
FirebaseDatabase database = FirebaseDatabase.getInstance();
myRef = database.getReference("Users");
myRef.keepSynced(true);
myRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
allPeoples = new ArrayList<>();
for(DataSnapshot snapshot : dataSnapshot.getChildren()){
if(snapshot.getKey().equals("Teacher") || snapshot.getKey().equals("Staff")){
for(DataSnapshot faculty : snapshot.child("peoples").getChildren()){
String birthday = (String) faculty.child("DOB").getValue();
if(birthday.equals(getCurrentDate())) {
String member = birthday;
allPeoples.add(member);
}
}
}else{
for(DataSnapshot student : snapshot.child("peoples").getChildren()){
String birthday = (String) student.child("DOB").getValue();
if(birthday.equals(getCurrentDate())) {
String member = birthday;
allPeoples.add(member);
}
}
}
}
numberOfPeoples = allPeoples.size();
NotificationHelper notificationHelper = new NotificationHelper(ctx, numberOfPeoples);
NotificationCompat.Builder nb = notificationHelper.getChannelNotification();
notificationHelper.getManager().notify(1, nb.build());
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
}
Автозапуск. java
public class AutoStart extends BroadcastReceiver
{
public void onReceive(Context context, Intent arg1)
{
Intent intent = new Intent(context, MyService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent);
} else {
context.startService(intent);
}
Log.i("Autostart", "started");
}
}
Манифест
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="......">
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:name="......"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning"
android:usesCleartextTraffic="true"
>
<activity android:name=".Activities.Birthday"></activity>
<activity android:name=".Activities.Contributors" />
<activity
android:name=".Activities.SearchDetails"
android:theme="@style/AppTheme.Fullscreen" />
<activity android:name=".Activities.Search" />
<activity android:name=".Activities.Students" />
<activity android:name=".Activities.Settings" />
<activity
android:name=".Activities.FacultySlider"
android:theme="@style/AppTheme.Fullscreen" />
<activity
android:name=".Activities.StudentSlider"
android:theme="@style/AppTheme.Fullscreen" />
<activity android:name=".Activities.PeopleList" />
<activity android:name=".Activities.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".AlarmReceiver"/>
<service android:name=".MyService"
android:label="Birthday Notification Service"
android:enabled="true"/>
<receiver android:name=".AutoStart"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.QUICKBOOT_POWERON"/>
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permission.CALL_PHONE"
tools:ignore="ManifestOrder" />
</manifest>
Редактировать: я запускаю свой сервис h это в методе onCreate MainActivity:
Intent intent = new Intent(this, MyService.class);
startService(intent);
Edit 2: On Android Oreo уведомление автоматически запускается при открытии приложения