mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2024-12-23 16:40:32 +00:00
Merge pull request #4948 from Stypox/fix-crash-startup
Fix crash on startup when there is no internet connection
This commit is contained in:
commit
c88b4032ef
@ -8,6 +8,7 @@ import android.os.Build;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.multidex.MultiDexApplication;
|
import androidx.multidex.MultiDexApplication;
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
|
|
||||||
@ -67,7 +68,7 @@ public class App extends MultiDexApplication {
|
|||||||
protected static final String TAG = App.class.toString();
|
protected static final String TAG = App.class.toString();
|
||||||
private static App app;
|
private static App app;
|
||||||
|
|
||||||
private Disposable disposable = null;
|
@Nullable private Disposable disposable = null;
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public static App getApp() {
|
public static App getApp() {
|
||||||
|
@ -12,6 +12,7 @@ import android.net.Uri;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.core.app.NotificationCompat;
|
import androidx.core.app.NotificationCompat;
|
||||||
import androidx.core.app.NotificationManagerCompat;
|
import androidx.core.app.NotificationManagerCompat;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
@ -21,13 +22,11 @@ import com.grack.nanojson.JsonObject;
|
|||||||
import com.grack.nanojson.JsonParser;
|
import com.grack.nanojson.JsonParser;
|
||||||
import com.grack.nanojson.JsonParserException;
|
import com.grack.nanojson.JsonParserException;
|
||||||
|
|
||||||
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
|
|
||||||
import org.schabi.newpipe.report.ErrorActivity;
|
import org.schabi.newpipe.report.ErrorActivity;
|
||||||
import org.schabi.newpipe.report.ErrorInfo;
|
import org.schabi.newpipe.report.ErrorInfo;
|
||||||
import org.schabi.newpipe.report.UserAction;
|
import org.schabi.newpipe.report.UserAction;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
@ -36,10 +35,9 @@ import java.security.cert.CertificateException;
|
|||||||
import java.security.cert.CertificateFactory;
|
import java.security.cert.CertificateFactory;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Maybe;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
import io.reactivex.disposables.Disposable;
|
import io.reactivex.disposables.Disposable;
|
||||||
import io.reactivex.disposables.Disposables;
|
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
|
|
||||||
public final class CheckForNewAppVersion {
|
public final class CheckForNewAppVersion {
|
||||||
@ -58,48 +56,43 @@ public final class CheckForNewAppVersion {
|
|||||||
* @param application The application
|
* @param application The application
|
||||||
* @return String with the apk's SHA1 fingeprint in hexadecimal
|
* @return String with the apk's SHA1 fingeprint in hexadecimal
|
||||||
*/
|
*/
|
||||||
|
@NonNull
|
||||||
private static String getCertificateSHA1Fingerprint(@NonNull final Application application) {
|
private static String getCertificateSHA1Fingerprint(@NonNull final Application application) {
|
||||||
final PackageManager pm = application.getPackageManager();
|
final PackageInfo packageInfo;
|
||||||
final String packageName = application.getPackageName();
|
|
||||||
final int flags = PackageManager.GET_SIGNATURES;
|
|
||||||
PackageInfo packageInfo = null;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
packageInfo = pm.getPackageInfo(packageName, flags);
|
packageInfo = application.getPackageManager().getPackageInfo(
|
||||||
|
application.getPackageName(), PackageManager.GET_SIGNATURES);
|
||||||
} catch (final PackageManager.NameNotFoundException e) {
|
} catch (final PackageManager.NameNotFoundException e) {
|
||||||
ErrorActivity.reportError(application, e, null, null,
|
ErrorActivity.reportError(application, e, null, null,
|
||||||
ErrorInfo.make(UserAction.SOMETHING_ELSE, "none",
|
ErrorInfo.make(UserAction.SOMETHING_ELSE, "none",
|
||||||
"Could not find package info", R.string.app_ui_crash));
|
"Could not find package info", R.string.app_ui_crash));
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
final Signature[] signatures = packageInfo.signatures;
|
final X509Certificate c;
|
||||||
final byte[] cert = signatures[0].toByteArray();
|
|
||||||
final InputStream input = new ByteArrayInputStream(cert);
|
|
||||||
|
|
||||||
X509Certificate c = null;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
final Signature[] signatures = packageInfo.signatures;
|
||||||
|
final byte[] cert = signatures[0].toByteArray();
|
||||||
|
final InputStream input = new ByteArrayInputStream(cert);
|
||||||
final CertificateFactory cf = CertificateFactory.getInstance("X509");
|
final CertificateFactory cf = CertificateFactory.getInstance("X509");
|
||||||
c = (X509Certificate) cf.generateCertificate(input);
|
c = (X509Certificate) cf.generateCertificate(input);
|
||||||
} catch (final CertificateException e) {
|
} catch (final CertificateException e) {
|
||||||
ErrorActivity.reportError(application, e, null, null,
|
ErrorActivity.reportError(application, e, null, null,
|
||||||
ErrorInfo.make(UserAction.SOMETHING_ELSE, "none",
|
ErrorInfo.make(UserAction.SOMETHING_ELSE, "none",
|
||||||
"Certificate error", R.string.app_ui_crash));
|
"Certificate error", R.string.app_ui_crash));
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
String hexString = null;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final MessageDigest md = MessageDigest.getInstance("SHA1");
|
final MessageDigest md = MessageDigest.getInstance("SHA1");
|
||||||
final byte[] publicKey = md.digest(c.getEncoded());
|
final byte[] publicKey = md.digest(c.getEncoded());
|
||||||
hexString = byte2HexFormatted(publicKey);
|
return byte2HexFormatted(publicKey);
|
||||||
} catch (NoSuchAlgorithmException | CertificateEncodingException e) {
|
} catch (NoSuchAlgorithmException | CertificateEncodingException e) {
|
||||||
ErrorActivity.reportError(application, e, null, null,
|
ErrorActivity.reportError(application, e, null, null,
|
||||||
ErrorInfo.make(UserAction.SOMETHING_ELSE, "none",
|
ErrorInfo.make(UserAction.SOMETHING_ELSE, "none",
|
||||||
"Could not retrieve SHA1 key", R.string.app_ui_crash));
|
"Could not retrieve SHA1 key", R.string.app_ui_crash));
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
return hexString;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String byte2HexFormatted(final byte[] arr) {
|
private static String byte2HexFormatted(final byte[] arr) {
|
||||||
@ -164,66 +157,66 @@ public final class CheckForNewAppVersion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isConnected(@NonNull final App app) {
|
private static boolean isConnected(@NonNull final App app) {
|
||||||
final ConnectivityManager cm = ContextCompat.getSystemService(app,
|
final ConnectivityManager connectivityManager =
|
||||||
ConnectivityManager.class);
|
ContextCompat.getSystemService(app, ConnectivityManager.class);
|
||||||
return cm.getActiveNetworkInfo() != null
|
return connectivityManager != null && connectivityManager.getActiveNetworkInfo() != null
|
||||||
&& cm.getActiveNetworkInfo().isConnected();
|
&& connectivityManager.getActiveNetworkInfo().isConnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isGithubApk(@NonNull final App app) {
|
public static boolean isGithubApk(@NonNull final App app) {
|
||||||
return getCertificateSHA1Fingerprint(app).equals(GITHUB_APK_SHA1);
|
return getCertificateSHA1Fingerprint(app).equals(GITHUB_APK_SHA1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@Nullable
|
||||||
public static Disposable checkNewVersion(@NonNull final App app) {
|
public static Disposable checkNewVersion(@NonNull final App app) {
|
||||||
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(app);
|
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(app);
|
||||||
|
|
||||||
// Check if user has enabled/disabled update checking
|
// Check if user has enabled/disabled update checking
|
||||||
// and if the current apk is a github one or not.
|
// and if the current apk is a github one or not.
|
||||||
if (!prefs.getBoolean(app.getString(R.string.update_app_key), true)
|
if (!prefs.getBoolean(app.getString(R.string.update_app_key), true) || !isGithubApk(app)) {
|
||||||
|| !isGithubApk(app)) {
|
return null;
|
||||||
return Disposables.empty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Observable.fromCallable(() -> {
|
return Maybe
|
||||||
if (!isConnected(app)) {
|
.fromCallable(() -> {
|
||||||
return null;
|
if (!isConnected(app)) {
|
||||||
}
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// Make a network request to get latest NewPipe data.
|
// Make a network request to get latest NewPipe data.
|
||||||
try {
|
return DownloaderImpl.getInstance().get(NEWPIPE_API_URL).responseBody();
|
||||||
return DownloaderImpl.getInstance().get(NEWPIPE_API_URL).responseBody();
|
})
|
||||||
} catch (IOException | ReCaptchaException e) {
|
|
||||||
// connectivity problems, do not alarm user and fail silently
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.w(TAG, Log.getStackTraceString(e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
})
|
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(response -> {
|
.subscribe(
|
||||||
// Parse the json from the response.
|
response -> {
|
||||||
if (response != null) {
|
// Parse the json from the response.
|
||||||
try {
|
try {
|
||||||
final JsonObject githubStableObject = JsonParser.object().from(response)
|
final JsonObject githubStableObject = JsonParser.object()
|
||||||
.getObject("flavors").getObject("github").getObject("stable");
|
.from(response).getObject("flavors").getObject("github")
|
||||||
|
.getObject("stable");
|
||||||
|
|
||||||
final String versionName = githubStableObject.getString("version");
|
final String versionName = githubStableObject
|
||||||
final int versionCode = githubStableObject.getInt("version_code");
|
.getString("version");
|
||||||
final String apkLocationUrl = githubStableObject.getString("apk");
|
final int versionCode = githubStableObject
|
||||||
|
.getInt("version_code");
|
||||||
|
final String apkLocationUrl = githubStableObject
|
||||||
|
.getString("apk");
|
||||||
|
|
||||||
compareAppVersionAndShowNotification(app, versionName, apkLocationUrl,
|
compareAppVersionAndShowNotification(app, versionName,
|
||||||
versionCode);
|
apkLocationUrl, versionCode);
|
||||||
} catch (final JsonParserException e) {
|
} 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
|
// connectivity problems, do not alarm user and fail silently
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.w(TAG, Log.getStackTraceString(e));
|
Log.w(TAG, "Could not get NewPipe API: network problem", e);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user