当某些设备上的应用被杀死时,AlarmManager不会触发的解决方法

时间:2019-02-05 14:47:28

标签: android android-service alarmmanager

在我的应用程序中,我想将应用程序的一些数据添加到SQLite数据库中,但是它也应该能够在后台以及特定时间(每月最后一天的晚上11:59:10 pm)进行操作)。因此,我正在使用AlarmManager和Foreground Service来执行此操作。当应用程序仍在“最近使用的应用程序”菜单中时,这可以很好地工作。但是,当我杀死该应用程序时,不会触发警报。我读过某处一些OEM进行此操作以进行电池优化和处理的东西。我已经尝试了其他类似WorkManager API和JobIntentService类的方法,但是主要问题在于AlarmManager的启动。因此,有什么我可以克服的问题吗?

MainActivity中的我的AlarmManager:

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>

谢谢。

0 个答案:

没有答案