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