From dea1741a65c5e9dd1ace8c9045555026878dcf6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=80lex=20Magaz=20Gra=C3=A7a?= Date: Sun, 18 Feb 2018 12:16:04 +0100 Subject: [PATCH] Avoid ScheduledActionService crashing due to new Android 8 restrictions See https://developer.android.com/about/versions/oreo/background.html#services Fixes https://github.com/codinguser/gnucash-android/issues/768 --- app/src/main/AndroidManifest.xml | 2 + .../android/app/GnuCashApplication.java | 12 +-- .../receivers/PeriodicJobReceiver.java | 6 ++ .../service/ScheduledActionService.java | 75 +++++++++---------- 4 files changed, 52 insertions(+), 43 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f212cde86..b2f2575f8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -120,6 +120,7 @@ @@ -160,6 +161,7 @@ android:name=".receivers.PeriodicJobReceiver" android:exported="false"> + For now, backups and scheduled actions.

+ * * @author Àlex Magaz Graça */ public class PeriodicJobReceiver extends BroadcastReceiver { private static final String LOG_TAG = "PeriodicJobReceiver"; public static final String ACTION_BACKUP = "org.gnucash.android.action_backup"; + public static final String ACTION_SCHEDULED_ACTIONS = "org.gnucash.android.action_scheduled_actions"; @Override public void onReceive(Context context, Intent intent) { @@ -41,6 +45,8 @@ public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(ACTION_BACKUP)) { BackupJob.enqueueWork(context); + } else if (intent.getAction().equals(ACTION_SCHEDULED_ACTIONS)) { + ScheduledActionService.enqueueWork(context); } } } diff --git a/app/src/main/java/org/gnucash/android/service/ScheduledActionService.java b/app/src/main/java/org/gnucash/android/service/ScheduledActionService.java index c345d52c3..71ab0cac3 100644 --- a/app/src/main/java/org/gnucash/android/service/ScheduledActionService.java +++ b/app/src/main/java/org/gnucash/android/service/ScheduledActionService.java @@ -16,12 +16,13 @@ package org.gnucash.android.service; -import android.app.IntentService; import android.content.ContentValues; +import android.content.Context; import android.content.Intent; import android.database.sqlite.SQLiteDatabase; -import android.os.PowerManager; +import android.support.annotation.NonNull; import android.support.annotation.VisibleForTesting; +import android.support.v4.app.JobIntentService; import android.util.Log; import com.crashlytics.android.Crashlytics; @@ -40,7 +41,6 @@ import org.gnucash.android.model.Book; import org.gnucash.android.model.ScheduledAction; import org.gnucash.android.model.Transaction; -import org.gnucash.android.util.BackupManager; import java.sql.Timestamp; import java.util.ArrayList; @@ -50,51 +50,50 @@ /** * Service for running scheduled events. - *

The service is started and goes through all scheduled event entries in the the database and executes them. - * Then it is stopped until the next time it is run.
- * Scheduled runs of the service should be achieved using an {@link android.app.AlarmManager}

+ * + *

It's run every time the enqueueWork is called. It goes + * through all scheduled event entries in the the database and executes them.

+ * + *

Scheduled runs of the service should be achieved using an + * {@link android.app.AlarmManager}, with + * {@link org.gnucash.android.receivers.PeriodicJobReceiver} as an intermediary.

+ * * @author Ngewi Fet */ -public class ScheduledActionService extends IntentService { +public class ScheduledActionService extends JobIntentService { - public static final String LOG_TAG = "ScheduledActionService"; + private static final String LOG_TAG = "ScheduledActionService"; + private static final int JOB_ID = 1001; - public ScheduledActionService() { - super(LOG_TAG); + + public static void enqueueWork(Context context) { + Intent intent = new Intent(context, ScheduledActionService.class); + enqueueWork(context, ScheduledActionService.class, JOB_ID, intent); } @Override - protected void onHandleIntent(Intent intent) { + protected void onHandleWork(@NonNull Intent intent) { Log.i(LOG_TAG, "Starting scheduled action service"); - PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); - PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG); - wakeLock.acquire(); - - try { - BooksDbAdapter booksDbAdapter = BooksDbAdapter.getInstance(); - List books = booksDbAdapter.getAllRecords(); - for (Book book : books) { //// TODO: 20.04.2017 Retrieve only the book UIDs with new method - DatabaseHelper dbHelper = new DatabaseHelper(GnuCashApplication.getAppContext(), book.getUID()); - SQLiteDatabase db = dbHelper.getWritableDatabase(); - RecurrenceDbAdapter recurrenceDbAdapter = new RecurrenceDbAdapter(db); - ScheduledActionDbAdapter scheduledActionDbAdapter = new ScheduledActionDbAdapter(db, recurrenceDbAdapter); - - List scheduledActions = scheduledActionDbAdapter.getAllEnabledScheduledActions(); - Log.i(LOG_TAG, String.format("Processing %d total scheduled actions for Book: %s", - scheduledActions.size(), book.getDisplayName())); - processScheduledActions(scheduledActions, db); - - //close all databases except the currently active database - if (!db.getPath().equals(GnuCashApplication.getActiveDb().getPath())) - db.close(); - } - - Log.i(LOG_TAG, "Completed service @ " + java.text.DateFormat.getDateTimeInstance().format(new Date())); - - } finally { //release the lock either way - wakeLock.release(); + BooksDbAdapter booksDbAdapter = BooksDbAdapter.getInstance(); + List books = booksDbAdapter.getAllRecords(); + for (Book book : books) { //// TODO: 20.04.2017 Retrieve only the book UIDs with new method + DatabaseHelper dbHelper = new DatabaseHelper(GnuCashApplication.getAppContext(), book.getUID()); + SQLiteDatabase db = dbHelper.getWritableDatabase(); + RecurrenceDbAdapter recurrenceDbAdapter = new RecurrenceDbAdapter(db); + ScheduledActionDbAdapter scheduledActionDbAdapter = new ScheduledActionDbAdapter(db, recurrenceDbAdapter); + + List scheduledActions = scheduledActionDbAdapter.getAllEnabledScheduledActions(); + Log.i(LOG_TAG, String.format("Processing %d total scheduled actions for Book: %s", + scheduledActions.size(), book.getDisplayName())); + processScheduledActions(scheduledActions, db); + + //close all databases except the currently active database + if (!db.getPath().equals(GnuCashApplication.getActiveDb().getPath())) + db.close(); } + + Log.i(LOG_TAG, "Completed service @ " + java.text.DateFormat.getDateTimeInstance().format(new Date())); } /**