From 18469219d6e17f59e9c888293e8bf39d920c2825 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=80lex=20Magaz=20Gra=C3=A7a?= Date: Fri, 9 Feb 2018 19:57:27 +0100 Subject: [PATCH] Avoid ScheduledActionService crashing due to new Android 8 restrictions Fixes https://github.com/codinguser/gnucash-android/issues/768 --- app/src/main/AndroidManifest.xml | 1 + .../android/app/GnuCashApplication.java | 10 +-- .../receivers/PeriodicJobReceiver.java | 4 ++ .../service/ScheduledActionService.java | 64 +++++++++---------- 4 files changed, 40 insertions(+), 39 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f212cde86..05a95ae34 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -120,6 +120,7 @@ diff --git a/app/src/main/java/org/gnucash/android/app/GnuCashApplication.java b/app/src/main/java/org/gnucash/android/app/GnuCashApplication.java index 90eb23c80..3e0acc912 100644 --- a/app/src/main/java/org/gnucash/android/app/GnuCashApplication.java +++ b/app/src/main/java/org/gnucash/android/app/GnuCashApplication.java @@ -50,9 +50,9 @@ import org.gnucash.android.db.adapter.ScheduledActionDbAdapter; import org.gnucash.android.db.adapter.SplitsDbAdapter; import org.gnucash.android.db.adapter.TransactionsDbAdapter; -import org.gnucash.android.model.Book; import org.gnucash.android.model.Commodity; import org.gnucash.android.model.Money; +import org.gnucash.android.receivers.PeriodicJobReceiver; import org.gnucash.android.service.ScheduledActionService; import org.gnucash.android.ui.settings.PreferenceActivity; @@ -333,8 +333,10 @@ public static Locale getDefaultLocale() { * @param context Application context */ public static void startScheduledActionExecutionService(Context context){ - Intent alarmIntent = new Intent(context, ScheduledActionService.class); - PendingIntent pendingIntent = PendingIntent.getService(context, 0, alarmIntent, PendingIntent.FLAG_NO_CREATE); + Intent alarmIntent = new Intent(context, PeriodicJobReceiver.class); + alarmIntent.setAction(PeriodicJobReceiver.ACTION_BACKUP); + PendingIntent pendingIntent = PendingIntent.getBroadcast(context,0, alarmIntent, + PendingIntent.FLAG_NO_CREATE); if (pendingIntent != null) //if service is already scheduled, just return return; @@ -346,7 +348,7 @@ public static void startScheduledActionExecutionService(Context context){ SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_FIFTEEN_MINUTES, AlarmManager.INTERVAL_HOUR, pendingIntent); - context.startService(alarmIntent); //run the service the first time + ScheduledActionService.enqueueWork(context); } /** diff --git a/app/src/main/java/org/gnucash/android/receivers/PeriodicJobReceiver.java b/app/src/main/java/org/gnucash/android/receivers/PeriodicJobReceiver.java index e0af3aa46..60cdaafb3 100644 --- a/app/src/main/java/org/gnucash/android/receivers/PeriodicJobReceiver.java +++ b/app/src/main/java/org/gnucash/android/receivers/PeriodicJobReceiver.java @@ -20,6 +20,7 @@ import android.content.Intent; import android.util.Log; +import org.gnucash.android.service.ScheduledActionService; import org.gnucash.android.util.BackupJob; /** @@ -31,6 +32,7 @@ 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 +43,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..2df48dced 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; @@ -55,46 +55,40 @@ * Scheduled runs of the service should be achieved using an {@link android.app.AlarmManager}

* @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())); } /**