diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ce1af58505..7f9ce9ad97 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,6 @@ - + @@ -12,9 +12,9 @@ + android:name=".data.library.LibraryUpdateService$LibraryUpdateReceiver"> () val failedUpdates = ArrayList() - val cancelIntent = PendingIntent.getBroadcast(this, 0, - Intent(this, CancelUpdateReceiver::class.java), 0) + val cancelIntent = getLibraryUpdateReceiverIntent(LibraryUpdateReceiver.CANCEL_LIBRARY_UPDATE) // Get the manga list that is going to be updated. val allLibraryMangas = db.getFavoriteMangas().executeAsBlocking() @@ -179,16 +209,17 @@ class LibraryUpdateService : Service() { // Notify manga that will update. .doOnNext { showProgressNotification(it, count.andIncrement, toUpdate.size, cancelIntent) } // Update the chapters of the manga. - .concatMap { manga -> updateManga(manga) - // If there's any error, return empty update and continue. - .onErrorReturn { - failedUpdates.add(manga) - Pair(0, 0) - } - // Filter out mangas without new chapters (or failed). - .filter { pair -> pair.first > 0 } - // Convert to the manga that contains new chapters. - .map { manga } + .concatMap { manga -> + updateManga(manga) + // If there's any error, return empty update and continue. + .onErrorReturn { + failedUpdates.add(manga) + Pair(0, 0) + } + // Filter out mangas without new chapters (or failed). + .filter { pair -> pair.first > 0 } + // Convert to the manga that contains new chapters. + .map { manga } } // Add manga with new chapters to the list. .doOnNext { newUpdates.add(it) } @@ -288,7 +319,27 @@ class LibraryUpdateService : Service() { setContentTitle(manga.title) setProgress(total, current, false) setOngoing(true) - addAction(R.drawable.ic_clear_grey_24dp_img, getString(R.string.action_cancel), cancelIntent) + addAction(R.drawable.ic_clear_grey_24dp_img, getString(android.R.string.cancel), cancelIntent) + } + notificationManager.notify(UPDATE_NOTIFICATION_ID, n) + } + + /** + * Show warning message when library can't be updated + * @param warningTitle title of warning + * @param warningBody warning information + * @param pendingIntent Intent called when action clicked + */ + private fun showWarningNotification(warningTitle: String, warningBody: String, pendingIntent: PendingIntent? = null) { + val n = notification() { + setSmallIcon(R.drawable.ic_warning_white_24dp_img) + setContentTitle(warningTitle) + setStyle(NotificationCompat.BigTextStyle().bigText(warningBody)) + setContentIntent(notificationIntent) + if (pendingIntent != null) { + addAction(R.drawable.ic_refresh_grey_24dp_img, getString(R.string.action_force), pendingIntent) + } + setAutoCancel(true) } notificationManager.notify(UPDATE_NOTIFICATION_ID, n) } @@ -341,23 +392,37 @@ class LibraryUpdateService : Service() { * @param intent the intent received. */ override fun onReceive(context: Context, intent: Intent) { - if (NetworkUtil.isNetworkConnected(context)) { + if (DeviceUtil.isNetworkConnected(context)) { AndroidComponentUtil.toggleComponent(context, this.javaClass, false) context.startService(getIntent(context)) } } } - class CancelUpdateReceiver : BroadcastReceiver() { + /** + * Class that triggers the library to update. + */ + class LibraryUpdateReceiver : BroadcastReceiver() { + companion object { + // Cancel library update action + val CANCEL_LIBRARY_UPDATE = "eu.kanade.CANCEL_LIBRARY_UPDATE" + // Force library update + val FORCE_LIBRARY_UPDATE = "eu.kanade.FORCE_LIBRARY_UPDATE" + } /** - * Method called when user stops the update. + * Method called when user wants a library update. * @param context the application context. * @param intent the intent received. */ override fun onReceive(context: Context, intent: Intent) { - LibraryUpdateService.stop(context) - context.notificationManager.cancel(UPDATE_NOTIFICATION_ID) + when (intent.action) { + CANCEL_LIBRARY_UPDATE -> { + LibraryUpdateService.stop(context) + context.notificationManager.cancel(UPDATE_NOTIFICATION_ID) + } + FORCE_LIBRARY_UPDATE -> LibraryUpdateService.start(context, true) + } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index abf7b963e4..d7821d1ba3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -197,16 +197,20 @@ class PreferencesHelper(private val context: Context) { return prefs.getBoolean(getKey(R.string.pref_remove_after_marked_as_read_key), false) } + fun updateOnlyWhenCharging(): Boolean { + return prefs.getBoolean(getKey(R.string.pref_update_only_when_charging_key), false) + } + fun libraryUpdateInterval(): Preference { return rxPrefs.getInteger(getKey(R.string.pref_library_update_interval_key), 0) } fun filterDownloaded(): Preference { - return rxPrefs.getBoolean(getKey(R.string.pref_filter_downloaded), false) + return rxPrefs.getBoolean(getKey(R.string.pref_filter_downloaded_key), false) } fun filterUnread(): Preference { - return rxPrefs.getBoolean(getKey(R.string.pref_filter_unread), false) + return rxPrefs.getBoolean(getKey(R.string.pref_filter_unread_key), false) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryFragment.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryFragment.kt index cf267b2de9..afe18b30e5 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryFragment.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryFragment.kt @@ -207,7 +207,7 @@ class LibraryFragment : BaseRxFragment(), ActionMode.Callback // Apply filter onFilterCheckboxChanged() } - R.id.action_refresh -> LibraryUpdateService.start(activity) + R.id.action_refresh -> LibraryUpdateService.start(activity, true) // Force refresh R.id.action_edit_categories -> { val intent = CategoryActivity.newIntent(activity) startActivity(intent) diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/DeviceUtil.kt b/app/src/main/java/eu/kanade/tachiyomi/util/DeviceUtil.kt new file mode 100644 index 0000000000..beab475dd6 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/util/DeviceUtil.kt @@ -0,0 +1,24 @@ +package eu.kanade.tachiyomi.util + +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.net.ConnectivityManager +import android.os.BatteryManager + +object DeviceUtil { + fun isPowerConnected(context: Context): Boolean { + val intent = context.registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED)) + intent?.let { + val plugged = it.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) + return plugged == BatteryManager.BATTERY_PLUGGED_AC || plugged == BatteryManager.BATTERY_PLUGGED_USB + } + return false + } + + fun isNetworkConnected(context: Context): Boolean { + val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + val activeNetwork = cm.activeNetworkInfo + return activeNetwork != null && activeNetwork.isConnectedOrConnecting + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/NetworkUtil.java b/app/src/main/java/eu/kanade/tachiyomi/util/NetworkUtil.java deleted file mode 100644 index 3ecac2f72b..0000000000 --- a/app/src/main/java/eu/kanade/tachiyomi/util/NetworkUtil.java +++ /dev/null @@ -1,16 +0,0 @@ -package eu.kanade.tachiyomi.util; - -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; - -public class NetworkUtil { - - public static boolean isNetworkConnected(Context context) { - ConnectivityManager cm = - (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); - return activeNetwork != null && activeNetwork.isConnectedOrConnecting(); - } - -} \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/ic_refresh_grey_24dp_img.png b/app/src/main/res/drawable-hdpi/ic_refresh_grey_24dp_img.png new file mode 100644 index 0000000000..8ee6206643 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_refresh_grey_24dp_img.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_warning_white_24dp_img.png b/app/src/main/res/drawable-hdpi/ic_warning_white_24dp_img.png new file mode 100644 index 0000000000..55c68431b1 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_warning_white_24dp_img.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_refresh_grey_24dp_img.png b/app/src/main/res/drawable-mdpi/ic_refresh_grey_24dp_img.png new file mode 100644 index 0000000000..895d64406f Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_refresh_grey_24dp_img.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_warning_white_24dp_img.png b/app/src/main/res/drawable-mdpi/ic_warning_white_24dp_img.png new file mode 100644 index 0000000000..04365b98a8 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_warning_white_24dp_img.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_refresh_grey_24dp_img.png b/app/src/main/res/drawable-xhdpi/ic_refresh_grey_24dp_img.png new file mode 100644 index 0000000000..848f2fb5a3 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_refresh_grey_24dp_img.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_warning_white_24dp_img.png b/app/src/main/res/drawable-xhdpi/ic_warning_white_24dp_img.png new file mode 100644 index 0000000000..a43fa3c27d Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_warning_white_24dp_img.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_refresh_grey_24dp_img.png b/app/src/main/res/drawable-xxhdpi/ic_refresh_grey_24dp_img.png new file mode 100644 index 0000000000..945fd729df Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_refresh_grey_24dp_img.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_warning_white_24dp_img.png b/app/src/main/res/drawable-xxhdpi/ic_warning_white_24dp_img.png new file mode 100644 index 0000000000..807b9fa184 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_warning_white_24dp_img.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_refresh_grey_24dp_img.png b/app/src/main/res/drawable-xxxhdpi/ic_refresh_grey_24dp_img.png new file mode 100644 index 0000000000..7fc4e4799d Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_refresh_grey_24dp_img.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_warning_white_24dp_img.png b/app/src/main/res/drawable-xxxhdpi/ic_warning_white_24dp_img.png new file mode 100644 index 0000000000..8683a2ea9a Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_warning_white_24dp_img.png differ diff --git a/app/src/main/res/values/keys.xml b/app/src/main/res/values/keys.xml index 3690052d10..35ed2fbc19 100644 --- a/app/src/main/res/values/keys.xml +++ b/app/src/main/res/values/keys.xml @@ -13,6 +13,7 @@ pref_library_columns_landscape_key pref_library_update_interval_key pref_update_only_non_completed_key + pref_update_only_when_charging_key pref_auto_update_manga_sync_key pref_ask_update_manga_sync_key pref_theme_key @@ -30,8 +31,8 @@ pref_reader_theme_key pref_image_decoder_key pref_seamless_mode_key - pref_filter_downloaded - pref_filter_unread + pref_filter_downloaded_key + pref_filter_unread_key pref_download_directory_key pref_download_slots_key diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6e23653c05..fa73030f7e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -50,6 +50,7 @@ Change display mode Cancel Sort + Force refresh Deleting… @@ -72,6 +73,7 @@ Default Library update frequency Only update incomplete manga + Only update when charging Manual Hourly Every 2 hours @@ -256,6 +258,10 @@ New chapters found for: Failed to update manga: Please add the manga to your library before doing this + Sync canceled + Not connected to AC power + Sync canceled + Connection not available Select cover image diff --git a/app/src/main/res/xml/pref_general.xml b/app/src/main/res/xml/pref_general.xml index 7450c8bf2f..72584f3bf3 100644 --- a/app/src/main/res/xml/pref_general.xml +++ b/app/src/main/res/xml/pref_general.xml @@ -3,30 +3,35 @@ xmlns:android="http://schemas.android.com/apk/res/android"> + android:title="@string/pref_library_columns"/> + android:key="@string/pref_library_update_interval_key" + android:summary="%s" + android:title="@string/pref_library_update_interval"/> + android:key="@string/pref_theme_key" + android:summary="%s" + android:title="@string/pref_theme"/> + android:title="@string/pref_update_only_non_completed"/> + + \ No newline at end of file diff --git a/app/src/test/java/eu/kanade/tachiyomi/data/library/LibraryUpdateAlarmTest.java b/app/src/test/java/eu/kanade/tachiyomi/data/library/LibraryUpdateAlarmTest.java index ea5d04019b..d6f7115fe6 100644 --- a/app/src/test/java/eu/kanade/tachiyomi/data/library/LibraryUpdateAlarmTest.java +++ b/app/src/test/java/eu/kanade/tachiyomi/data/library/LibraryUpdateAlarmTest.java @@ -101,6 +101,7 @@ public class LibraryUpdateAlarmTest { @Test public void testLibraryUpdateServiceIsStartedWhenUpdateIntentIsReceived() { Intent intent = new Intent(context, LibraryUpdateService.class); + intent.putExtra("is_forced", false); assertThat(app.getNextStartedService()).isNotEqualTo(intent); LibraryUpdateAlarm alarm = new LibraryUpdateAlarm();