diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 81f914710..540d20be5 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -359,6 +359,9 @@
+
diff --git a/app/src/main/java/org/schabi/newpipe/App.java b/app/src/main/java/org/schabi/newpipe/App.java
index 766ebe834..35b0b2674 100644
--- a/app/src/main/java/org/schabi/newpipe/App.java
+++ b/app/src/main/java/org/schabi/newpipe/App.java
@@ -5,7 +5,6 @@ import android.content.SharedPreferences;
import android.util.Log;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import androidx.core.app.NotificationChannelCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.multidex.MultiDexApplication;
@@ -37,7 +36,6 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
-import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.exceptions.CompositeException;
import io.reactivex.rxjava3.exceptions.MissingBackpressureException;
import io.reactivex.rxjava3.exceptions.OnErrorNotImplementedException;
@@ -45,6 +43,8 @@ import io.reactivex.rxjava3.exceptions.UndeliverableException;
import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.plugins.RxJavaPlugins;
+import static org.schabi.newpipe.CheckForNewAppVersion.startNewVersionCheckService;
+
/*
* Copyright (C) Hans-Christoph Steiner 2016
* App.java is part of NewPipe.
@@ -68,9 +68,6 @@ public class App extends MultiDexApplication {
private static final String TAG = App.class.toString();
private static App app;
- @Nullable
- private Disposable disposable = null;
-
@NonNull
public static App getApp() {
return app;
@@ -118,14 +115,11 @@ public class App extends MultiDexApplication {
configureRxJavaErrorHandler();
// Check for new version
- disposable = CheckForNewAppVersion.checkNewVersion(this);
+ startNewVersionCheckService();
}
@Override
public void onTerminate() {
- if (disposable != null) {
- disposable.dispose();
- }
super.onTerminate();
PicassoHelper.terminate();
}
diff --git a/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java b/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java
index c8fa02186..64874cd93 100644
--- a/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java
+++ b/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java
@@ -1,6 +1,7 @@
package org.schabi.newpipe;
import android.app.Application;
+import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -25,8 +26,11 @@ import com.grack.nanojson.JsonParserException;
import org.schabi.newpipe.error.ErrorActivity;
import org.schabi.newpipe.error.ErrorInfo;
import org.schabi.newpipe.error.UserAction;
+import org.schabi.newpipe.extractor.downloader.Response;
+import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -36,13 +40,10 @@ import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.List;
-import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
-import io.reactivex.rxjava3.core.Maybe;
-import io.reactivex.rxjava3.disposables.Disposable;
-import io.reactivex.rxjava3.schedulers.Schedulers;
-
-public final class CheckForNewAppVersion {
- private CheckForNewAppVersion() { }
+public final class CheckForNewAppVersion extends IntentService {
+ public CheckForNewAppVersion() {
+ super("CheckForNewAppVersion");
+ }
private static final boolean DEBUG = MainActivity.DEBUG;
private static final String TAG = CheckForNewAppVersion.class.getSimpleName();
@@ -168,78 +169,87 @@ public final class CheckForNewAppVersion {
return getCertificateSHA1Fingerprint(app).equals(GITHUB_APK_SHA1);
}
- @Nullable
- public static Disposable checkNewVersion(@NonNull final App app) {
+ private void checkNewVersion() throws IOException, ReCaptchaException {
+ final App app = App.getApp();
+
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(app);
final NewVersionManager manager = new NewVersionManager();
// Check if user has enabled/disabled update checking
// and if the current apk is a github one or not.
if (!prefs.getBoolean(app.getString(R.string.update_app_key), true) || !isGithubApk(app)) {
- return null;
+ return;
}
// Check if the last request has happened a certain time ago
// to reduce the number of API requests.
final long expiry = prefs.getLong(app.getString(R.string.update_expiry_key), 0);
if (!manager.isExpired(expiry)) {
- return null;
+ return;
}
- return Maybe
- .fromCallable(() -> {
- if (!isConnected(app)) {
- return null;
- }
+ // Make a network request to get latest NewPipe data.
+ final Response response = DownloaderImpl.getInstance().get(NEWPIPE_API_URL);
+ handleResponse(response, manager, prefs, app);
+ }
- // Make a network request to get latest NewPipe data.
- return DownloaderImpl.getInstance().get(NEWPIPE_API_URL);
- })
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(
- response -> {
- try {
- // Store a timestamp which needs to be exceeded,
- // before a new request to the API is made.
- final long newExpiry = manager
- .coerceExpiry(response.getHeader("expires"));
- prefs.edit()
- .putLong(app.getString(R.string.update_expiry_key), newExpiry)
- .apply();
- } catch (final Exception e) {
- if (DEBUG) {
- Log.w(TAG, "Could not extract and save new expiry date", e);
- }
- }
+ private void handleResponse(@NonNull final Response response,
+ @NonNull final NewVersionManager manager,
+ @NonNull final SharedPreferences prefs,
+ @NonNull final App app) {
+ try {
+ // Store a timestamp which needs to be exceeded,
+ // before a new request to the API is made.
+ final long newExpiry = manager
+ .coerceExpiry(response.getHeader("expires"));
+ prefs.edit()
+ .putLong(app.getString(R.string.update_expiry_key), newExpiry)
+ .apply();
+ } catch (final Exception e) {
+ if (DEBUG) {
+ Log.w(TAG, "Could not extract and save new expiry date", e);
+ }
+ }
- // Parse the json from the response.
- try {
- final JsonObject githubStableObject = JsonParser.object()
- .from(response.responseBody()).getObject("flavors")
- .getObject("github").getObject("stable");
+ // Parse the json from the response.
+ try {
+ final JsonObject githubStableObject = JsonParser.object()
+ .from(response.responseBody()).getObject("flavors")
+ .getObject("github").getObject("stable");
- final String versionName = githubStableObject
- .getString("version");
- final int versionCode = githubStableObject
- .getInt("version_code");
- final String apkLocationUrl = githubStableObject
- .getString("apk");
+ final String versionName = githubStableObject
+ .getString("version");
+ final int versionCode = githubStableObject
+ .getInt("version_code");
+ final String apkLocationUrl = githubStableObject
+ .getString("apk");
+
+ compareAppVersionAndShowNotification(app, versionName,
+ apkLocationUrl, versionCode);
+ } catch (final JsonParserException e) {
+ // Most likely something is wrong in data received from NEWPIPE_API_URL.
+ // Do not alarm user and fail silently.
+ if (DEBUG) {
+ Log.w(TAG, "Could not get NewPipe API: invalid json", e);
+ }
+ }
+ }
+
+ public static void startNewVersionCheckService() {
+ final Intent intent = new Intent(App.getApp().getApplicationContext(),
+ CheckForNewAppVersion.class);
+ App.getApp().startService(intent);
+ }
+
+ @Override
+ protected void onHandleIntent(@Nullable final Intent intent) {
+ try {
+ checkNewVersion();
+ } catch (final IOException e) {
+ Log.w(TAG, "Could not fetch NewPipe API: probably network problem", e);
+ } catch (final ReCaptchaException e) {
+ Log.e(TAG, "ReCaptchaException should never happen here.", e);
+ }
- compareAppVersionAndShowNotification(app, versionName,
- apkLocationUrl, versionCode);
- } catch (final JsonParserException e) {
- // connectivity problems, do not alarm user and fail silently
- if (DEBUG) {
- Log.w(TAG, "Could not get NewPipe API: invalid json", e);
- }
- }
- },
- e -> {
- // connectivity problems, do not alarm user and fail silently
- if (DEBUG) {
- Log.w(TAG, "Could not get NewPipe API: network problem", e);
- }
- });
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/settings/UpdateSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/UpdateSettingsFragment.java
index 0ca15e245..d2f56b487 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/UpdateSettingsFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/UpdateSettingsFragment.java
@@ -6,11 +6,21 @@ import androidx.preference.Preference;
import org.schabi.newpipe.R;
+import static org.schabi.newpipe.CheckForNewAppVersion.startNewVersionCheckService;
+
public class UpdateSettingsFragment extends BasePreferenceFragment {
private final Preference.OnPreferenceChangeListener updatePreferenceChange
- = (preference, newValue) -> {
+ = (preference, checkForUpdates) -> {
defaultPreferences.edit()
- .putBoolean(getString(R.string.update_app_key), (boolean) newValue).apply();
+ .putBoolean(getString(R.string.update_app_key), (boolean) checkForUpdates).apply();
+
+ if ((boolean) checkForUpdates) {
+ // Search for updates immediately when update checks are enabled.
+ // Reset the expire time. This is necessary to check for an update immediately.
+ defaultPreferences.edit()
+ .putLong(getString(R.string.update_expiry_key), 0).apply();
+ startNewVersionCheckService();
+ }
return true;
};