Обходной путь для AlarmManager, не запускающийся, когда приложение убито на определенных устройствах - PullRequest
0 голосов
/ 05 февраля 2019

В моем приложении я хочу добавить некоторые данные приложения в базу данных SQLite, но он должен быть в состоянии сделать это также в фоновом режиме и в определенное время (11:59:10 вечера последнего дня каждого месяца).И поэтому я использую AlarmManager и Foreground Service для этого.Это прекрасно работает, когда приложение все еще находится в меню последних приложений.Но когда я убиваю приложение, сигнал тревоги не срабатывает.Я где-то читал, что некоторые производители делают это для оптимизации батареи и прочего.Я пробовал другие вещи, такие как WorkManager API и класс JobIntentService, но основная проблема заключается в срабатывании AlarmManager.Таким образом, есть ли что-нибудь, что я могу сделать, чтобы преодолеть эту проблему?

Мой AlarmManager в MainActivity:

AlarmManager alarmManager = (AlarmManager) getApplicationContext().getSystemService(ALARM_SERVICE);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(this,123,
            new Intent(this,Receiver.class), PendingIntent.FLAG_CANCEL_CURRENT);
    if (alarmManager != null)
    {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.DAY_OF_MONTH,c.getActualMaximum(Calendar.DAY_OF_MONTH));
        c.set(Calendar.HOUR_OF_DAY,23);
        c.set(Calendar.MINUTE,59);
        c.set(Calendar.SECOND,10);
        c.set(Calendar.MILLISECOND,0);
        alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(),pendingIntent);
    }

Мой класс BroadcastReceiver:

public class Receiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    Intent intent1 = new Intent(context,BackgroundService.class);
    context.startService(intent1);
}

}

Мой класс обслуживания:

public class BackgroundService extends Service {

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onCreate() {
    super.onCreate();
}

@Override
public void onDestroy() {
    super.onDestroy();
}

Cursor cursor;
private static final String CHANNEL_ID = "ServiceChannel";

//Some Other Method:
public  Double getMonthlyIncome()
{
    double sum = 0, value;
    cursor = MyDb.TblClients.getFeesData();
    if(cursor != null)
    {
        cursor.moveToPosition(-1);
        while (cursor.moveToNext())
        {
            String dur = cursor.getString(cursor.getColumnIndex(CLDUR));
            Double fee = Double.parseDouble(cursor.getString(cursor.getColumnIndex(CLFEE)));

            if(dur.equalsIgnoreCase("1 month"))
            {sum += fee;}
            else if(dur.equalsIgnoreCase("3 month"))
            {sum += (fee/3);}
            else if(dur.equalsIgnoreCase("6 month"))
            {sum += (fee/6);}
            else if(dur.equalsIgnoreCase("1 year"))
            {sum += (fee/12);}
        }
        cursor.close();
    }

    if((sum % 10) != 0)
    {
        DecimalFormat decf = new DecimalFormat(".##");
        value = Double.parseDouble(decf.format(sum));
        return value;
    }

    return  sum;
}

//Some Other Method:
public int getActCltNum()
{
    cursor = MyDb.TblClients.getActClients("Active");
    if (cursor != null) {
        return cursor.getCount();
    }

    return 0;
}

//Some Other Method:
private long getInterval()
{
    Calendar c = Calendar.getInstance();
    int currentMonth = c.get(Calendar.MONTH);
    currentMonth++;

    if(currentMonth > Calendar.DECEMBER)
    {
        currentMonth = Calendar.JANUARY;
        c.set(Calendar.YEAR, c.get(Calendar.YEAR)+1);
    }

    c.set(Calendar.MONTH,currentMonth);

    int maxDays = c.getActualMaximum(Calendar.DAY_OF_MONTH);
    c.set(Calendar.DAY_OF_MONTH,maxDays);
    c.set(Calendar.HOUR_OF_DAY,23);
    c.set(Calendar.SECOND,10);
    c.set(Calendar.MILLISECOND,0);

    return c.getTimeInMillis();
}

// Method to re-create next Alarm:
private void Alarm()
{
    AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(this,1,
            new Intent(this,Receiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
    if (alarmManager != null)
    {
        alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,getInterval(),pendingIntent);
    }
}

//Service-Handling Method:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    NotificationManager notificationManager = getApplicationContext().getSystemService(NotificationManager.class);
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
        {
            NotificationChannel notificationChannel = new NotificationChannel(CHANNEL_ID,"serviceChannel",
                    NotificationManager.IMPORTANCE_DEFAULT);

            if (notificationManager != null) {
                notificationManager.createNotificationChannel(notificationChannel);
            }
        }

    NotificationCompat.Builder notification = new NotificationCompat.Builder(this,CHANNEL_ID)
            .setContentTitle("Financial Report")
            .setContentText("Creating the new Financial Report")
            .setSmallIcon(R.drawable.ic_notif_finance);

    startForeground(1,notification.build());

    long inserted = MyDb.Tbl_Income_Act.insertIncData(String.valueOf(getMonthlyIncome()), String.valueOf(getActCltNum())
            , new SimpleDateFormat("yyyy-MM-dd").format(Calendar.getInstance().getTime()));

    if(inserted > 0)
    {
        PendingIntent pendingIntent = PendingIntent.getActivity(this,111,
                new Intent(this,Payments.class),PendingIntent.FLAG_UPDATE_CURRENT);
        NotificationCompat.Builder notification2 = new NotificationCompat.Builder(this,CHANNEL_ID)
                .setContentTitle("Financial Report")
                .setContentText("New Financial Report has been created.")
                .setContentIntent(pendingIntent)
                .setAutoCancel(true)
                .setSmallIcon(R.drawable.ic_notif_finance);
        if (notificationManager != null) {
            notificationManager.notify(2,notification2.build());
        }

        Alarm();
        stopSelf();
    }

    return START_NOT_STICKY;
}

}

Мои регистрации в манифесте:

<receiver
        android:name=".Receiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
        </intent-filter>
    </receiver>

    <service
        android:name=".BackgroundService">
    </service>

Заранее спасибо.

...