diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c03c9b95..80e1c62d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,6 +6,7 @@ + adapterProtocols = new ArrayAdapter<>(LoginActivity.this, R.layout.list_spinner_items, Protocol.values()); protocolSpinner.setAdapter(adapterProtocols); - + protocolSpinner.setSelection(0); protocolSpinner.setOnItemClickListener((parent, view, position, id) -> { selectedProtocol = String.valueOf(parent.getItemAtPosition(position)); @@ -115,18 +116,24 @@ public class LoginActivity extends BaseActivity { } }); - networkMonitor.onInternetStateListener(isAvailable -> { + Handler handler = new Handler(getMainLooper()); - if(isAvailable) { + networkStatusObserver.registerNetworkStatusListener(hasNetworkConnection -> { - enableProcessButton(); - } - else { + handler.post(() -> { - disableProcessButton(); - loginButton.setText(getResources().getString(R.string.btnLogin)); - Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); - } + if(hasNetworkConnection) { + + enableProcessButton(); + } + else { + + disableProcessButton(); + loginButton.setText(getResources().getString(R.string.btnLogin)); + Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); + } + + }); }); loadDefaults(); @@ -267,8 +274,10 @@ public class LoginActivity extends BaseActivity { if(gitea_version.less(getString(R.string.versionLow))) { - AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ctx).setTitle(getString(R.string.versionAlertDialogHeader)) - .setMessage(getResources().getString(R.string.versionUnsupportedOld, version.getVersion())).setIcon(R.drawable.ic_warning) + AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ctx) + .setTitle(getString(R.string.versionAlertDialogHeader)) + .setMessage(getResources().getString(R.string.versionUnsupportedOld, version.getVersion())) + .setIcon(R.drawable.ic_warning) .setCancelable(true); alertDialogBuilder.setNegativeButton(getString(R.string.cancelButton), (dialog, which) -> { diff --git a/app/src/main/java/org/mian/gitnex/clients/RetrofitClient.java b/app/src/main/java/org/mian/gitnex/clients/RetrofitClient.java index 2a6fd6d2..9304d051 100644 --- a/app/src/main/java/org/mian/gitnex/clients/RetrofitClient.java +++ b/app/src/main/java/org/mian/gitnex/clients/RetrofitClient.java @@ -36,8 +36,6 @@ public class RetrofitClient { TinyDB tinyDB = TinyDB.getInstance(context); - final boolean connToInternet = AppUtil.hasNetworkConnection(context); - int cacheSize = FilesData.returnOnlyNumber(tinyDB.getString("cacheSizeStr")) * 1024 * 1024; Cache cache = new Cache(new File(context.getCacheDir(), "responses"), cacheSize); @@ -59,7 +57,7 @@ public class RetrofitClient { Request request = chain.request(); - request = connToInternet ? + request = AppUtil.hasNetworkConnection(context) ? request.newBuilder().header("Cache-Control", "public, max-age=" + 60).build() : request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 30).build(); diff --git a/app/src/main/java/org/mian/gitnex/helpers/AppUtil.java b/app/src/main/java/org/mian/gitnex/helpers/AppUtil.java index fdfefe85..6b3e7d5c 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/AppUtil.java +++ b/app/src/main/java/org/mian/gitnex/helpers/AppUtil.java @@ -5,13 +5,12 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Resources; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; import android.util.Base64; import android.util.DisplayMetrics; import android.util.TypedValue; import android.view.View; import androidx.annotation.ColorInt; +import androidx.core.content.pm.PackageInfoCompat; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; @@ -34,32 +33,14 @@ public class AppUtil { public static boolean hasNetworkConnection(Context context) { - boolean haveConnectedWifi = false; - boolean haveConnectedMobile = false; - - ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - assert cm != null; - NetworkInfo[] netInfo = cm.getAllNetworkInfo(); - for(NetworkInfo ni : netInfo) { - if(ni.getTypeName().equalsIgnoreCase("WIFI")) { - if(ni.isConnected()) { - haveConnectedWifi = true; - } - } - if(ni.getTypeName().equalsIgnoreCase("MOBILE")) { - if(ni.isConnected()) { - haveConnectedMobile = true; - } - } - } - return haveConnectedWifi || haveConnectedMobile; + return NetworkStatusObserver.get(context).hasNetworkConnection(); } public static int getAppBuildNo(Context context) { try { PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); - return packageInfo.versionCode; + return (int) PackageInfoCompat.getLongVersionCode(packageInfo); } catch(PackageManager.NameNotFoundException e) { throw new RuntimeException("Could not get package name: " + e); diff --git a/app/src/main/java/org/mian/gitnex/helpers/NetworkObserver.java b/app/src/main/java/org/mian/gitnex/helpers/NetworkObserver.java deleted file mode 100644 index 6d557f20..00000000 --- a/app/src/main/java/org/mian/gitnex/helpers/NetworkObserver.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.mian.gitnex.helpers; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import androidx.appcompat.app.AppCompatActivity; -import androidx.lifecycle.Lifecycle; -import androidx.lifecycle.LifecycleObserver; -import androidx.lifecycle.OnLifecycleEvent; - -/** - * Author M M Arif - */ - -public class NetworkObserver implements LifecycleObserver { - - private ConnectivityManager mConnectivityMgr; - private Context mContext; - private NetworkStateReceiver mNetworkStateReceiver; - - public interface ConnectionStateListener { - void onAvailable(boolean isAvailable); - } - - public NetworkObserver(Context context) { - mContext = context; - mConnectivityMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - ((AppCompatActivity) mContext).getLifecycle().addObserver(this); - } - - - public void onInternetStateListener(ConnectionStateListener listener) { - - mNetworkStateReceiver = new NetworkStateReceiver(listener); - IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); - mContext.registerReceiver(mNetworkStateReceiver, intentFilter); - - } - - - @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) - public void onDestroy() { - - ((AppCompatActivity) mContext).getLifecycle().removeObserver(this); - - if (mNetworkStateReceiver != null) { - mContext.unregisterReceiver(mNetworkStateReceiver); - } - - } - - - public class NetworkStateReceiver extends BroadcastReceiver { - - ConnectionStateListener mListener; - - public NetworkStateReceiver(ConnectionStateListener listener) { - mListener = listener; - } - - @Override - public void onReceive(Context context, Intent intent) { - if (intent.getExtras() != null) { - NetworkInfo activeNetworkInfo = mConnectivityMgr.getActiveNetworkInfo(); - - if (activeNetworkInfo != null && activeNetworkInfo.getState() == NetworkInfo.State.CONNECTED) { - - mListener.onAvailable(true); // connected - - } else if (intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE)) { - - mListener.onAvailable(false); // disconnected - - } - } - } - } - -} diff --git a/app/src/main/java/org/mian/gitnex/helpers/NetworkStatusObserver.java b/app/src/main/java/org/mian/gitnex/helpers/NetworkStatusObserver.java new file mode 100644 index 00000000..5845be53 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/helpers/NetworkStatusObserver.java @@ -0,0 +1,109 @@ +package org.mian.gitnex.helpers; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.NetworkRequest; +import androidx.annotation.NonNull; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * @author opyale + */ +public class NetworkStatusObserver { + + private static NetworkStatusObserver networkStatusObserver; + + private final AtomicBoolean hasNetworkConnection = new AtomicBoolean(false); + private final List networkStatusListeners = new ArrayList<>(); + + private final Object mutex = new Object(); + private boolean hasInitialized = false; + + private NetworkStatusObserver(Context context) { + + ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + + NetworkRequest networkRequest = new NetworkRequest.Builder() + .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) + .build(); + + cm.requestNetwork(networkRequest, new ConnectivityManager.NetworkCallback() { + + @Override + public void onAvailable(@NonNull Network network) { + hasNetworkConnection.set(true); + networkStatusChanged(); + checkInitialized(); + } + + @Override + public void onLost(@NonNull Network network) { + hasNetworkConnection.set(false); + networkStatusChanged(); + checkInitialized(); + } + + private void checkInitialized() { + + if(!hasInitialized) { + hasInitialized = true; + synchronized(mutex) { + mutex.notify(); + } + } + } + + }); + + synchronized(mutex) { + try { + // This is actually not the recommended way to do this, but there + // is no other option besides upgrading to API level 26 + // in order to use the built-in timeout functionality of {@code requestNetwork()} + // which in turn gives us access to {@code onUnavailable()} . + mutex.wait(5); + } catch(InterruptedException ignored) {} + } + + if(!hasInitialized) { + hasInitialized = true; + } + } + + private void networkStatusChanged() { + boolean hasNetworkConnection = hasNetworkConnection(); + + for(NetworkStatusListener networkStatusListener : networkStatusListeners) { + networkStatusListener.onNetworkStatusChanged(hasNetworkConnection); + } + } + + public boolean hasNetworkConnection() { + return hasNetworkConnection.get(); + } + + public void registerNetworkStatusListener(NetworkStatusListener networkStatusListener) { + networkStatusListeners.add(networkStatusListener); + networkStatusListener.onNetworkStatusChanged(hasNetworkConnection()); + } + + public void unregisterNetworkStatusListener(NetworkStatusListener networkStatusListener) { + networkStatusListeners.remove(networkStatusListener); + } + + public interface NetworkStatusListener { void onNetworkStatusChanged(boolean hasNetworkConnection); } + + public static NetworkStatusObserver get(Context context) { + if(networkStatusObserver == null) { + networkStatusObserver = new NetworkStatusObserver(context); + } + + return networkStatusObserver; + } + +} diff --git a/app/src/main/java/org/mian/gitnex/helpers/TinyDB.java b/app/src/main/java/org/mian/gitnex/helpers/TinyDB.java index 0cc7486f..d4e782a8 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/TinyDB.java +++ b/app/src/main/java/org/mian/gitnex/helpers/TinyDB.java @@ -6,7 +6,6 @@ import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.graphics.BitmapFactory; import android.os.Environment; -import android.preference.PreferenceManager; import android.text.TextUtils; import android.util.Log; import java.io.File; @@ -25,7 +24,7 @@ public class TinyDB { private String lastImagePath = ""; private TinyDB(Context appContext) { - preferences = PreferenceManager.getDefaultSharedPreferences(appContext); + preferences = appContext.getSharedPreferences(appContext.getPackageName() + "_preferences", Context.MODE_PRIVATE); } public static synchronized TinyDB getInstance(Context context) {