"No internet" banner on main, categories, and updates screen

An alternate implementation of @pserwylo's fdroidclient!724

closes #884
This commit is contained in:
Hans-Christoph Steiner 2021-04-13 14:40:09 +02:00
parent d9a86d4c16
commit a505850110
2 changed files with 59 additions and 25 deletions

View File

@ -4,21 +4,40 @@ import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.Gravity; import android.view.Gravity;
import android.view.View; import android.view.View;
import org.fdroid.fdroid.R; import org.fdroid.fdroid.R;
import org.fdroid.fdroid.UpdateService; import org.fdroid.fdroid.UpdateService;
import org.fdroid.fdroid.net.ConnectivityMonitorService;
import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
/** /**
* Widget which reflects whether or not a repo update is currently in progress or not. If so, shows * Banner widget which reflects current status related to repository updates.
* some sort of feedback to the user. * It will display whether repositories area actively being updated, or
* whether there is no Internet connection, so repositories cannot be updated
* from the Internet.
* <p>
* It shows a "No Internet" message when it identifies the device is not
* connected. Will only monitor the wifi state when attached to the window.
* Note that this does a pretty poor job of responding to network changes in
* real time. It only knows how to respond to the <em>enabling</em> of WiFi
* (not disabling of WiFi, nor enabling/disabling of mobile data). However it
* will always query the network state when it is shown to the user. This way
* if they change between tabs, hide and then open F-Droid, or do other things
* which require the view to attach to the window again then it will update the
* network state. In practice this works pretty well.
*
* @see <a href="https://gitlab.com/fdroid/fdroidclient/-/merge_requests/724">"No internet" banner on main, categories, and updates screen</a>
*/ */
public class BannerUpdatingRepos extends androidx.appcompat.widget.AppCompatTextView { public class BannerUpdatingRepos extends androidx.appcompat.widget.AppCompatTextView {
private int updateServiceStatus = UpdateService.STATUS_COMPLETE_WITH_CHANGES;
private int networkState = ConnectivityMonitorService.FLAG_NET_NO_LIMIT;
public BannerUpdatingRepos(Context context) { public BannerUpdatingRepos(Context context) {
this(context, null); this(context, null);
} }
@ -33,51 +52,65 @@ public class BannerUpdatingRepos extends androidx.appcompat.widget.AppCompatText
setPadding(padding, padding, padding, padding); setPadding(padding, padding, padding, padding);
setBackgroundColor(0xFF4A4A4A); setBackgroundColor(0xFF4A4A4A);
setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL); setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
setText(R.string.banner_updating_repositories);
setTextColor(0xFFFFFFFF); setTextColor(0xFFFFFFFF);
} }
@Override @Override
protected void onAttachedToWindow() { protected void onAttachedToWindow() {
super.onAttachedToWindow(); super.onAttachedToWindow();
monitorRepoUpdates(); Context context = getContext();
networkState = ConnectivityMonitorService.getNetworkState(context);
context.registerReceiver(onNetworkStateChanged,
new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
if (UpdateService.isUpdating()) {
updateServiceStatus = UpdateService.STATUS_INFO;
}
LocalBroadcastManager.getInstance(context).registerReceiver(onRepoFeedback,
new IntentFilter(UpdateService.LOCAL_ACTION_STATUS));
setBannerTextAndVisibility();
} }
@Override @Override
protected void onDetachedFromWindow() { protected void onDetachedFromWindow() {
super.onDetachedFromWindow(); super.onDetachedFromWindow();
stopMonitoringRepoUpdates(); Context context = getContext();
LocalBroadcastManager.getInstance(context).unregisterReceiver(onRepoFeedback);
context.unregisterReceiver(onNetworkStateChanged);
} }
private void monitorRepoUpdates() { private void setBannerTextAndVisibility() {
if (isInEditMode()) { if (updateServiceStatus == UpdateService.STATUS_INFO) {
return; setText(R.string.banner_updating_repositories);
} setVisibility(View.VISIBLE);
} else if (networkState == ConnectivityMonitorService.FLAG_NET_UNAVAILABLE
LocalBroadcastManager.getInstance(getContext()).registerReceiver(onRepoFeedback, || networkState == ConnectivityMonitorService.FLAG_NET_DEVICE_AP_WITHOUT_INTERNET) {
new IntentFilter(UpdateService.LOCAL_ACTION_STATUS)); setText(R.string.banner_no_internet);
setBannerIsVisible(UpdateService.isUpdating());
}
private void setBannerIsVisible(boolean isUpdating) {
if (isUpdating) {
setVisibility(View.VISIBLE); setVisibility(View.VISIBLE);
} else { } else {
setVisibility(View.GONE); setVisibility(View.GONE);
} }
} }
private void stopMonitoringRepoUpdates() { /**
LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(onRepoFeedback); * Anything other than a {@link UpdateService#STATUS_INFO} broadcast
} * signifies that it was complete (and out banner should be removed).
*/
private final BroadcastReceiver onRepoFeedback = new BroadcastReceiver() { private final BroadcastReceiver onRepoFeedback = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
// Anything other than a STATUS_INFO broadcast signifies that it was complete (and out updateServiceStatus = intent.getIntExtra(UpdateService.EXTRA_STATUS_CODE,
// banner should be removed). UpdateService.STATUS_COMPLETE_WITH_CHANGES);
boolean isInfo = intent.getIntExtra(UpdateService.EXTRA_STATUS_CODE, 0) == UpdateService.STATUS_INFO; setBannerTextAndVisibility();
setBannerIsVisible(isInfo); }
};
private final BroadcastReceiver onNetworkStateChanged = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
networkState = ConnectivityMonitorService.getNetworkState(context);
setBannerTextAndVisibility();
} }
}; };
} }

View File

@ -379,6 +379,7 @@ This often occurs with apps installed via Google Play or other sources, if they
<string name="status_download_unknown_size">Downloading\n%2$s from\n%1$s</string> <string name="status_download_unknown_size">Downloading\n%2$s from\n%1$s</string>
<string name="download_404">The requested file was not found.</string> <string name="download_404">The requested file was not found.</string>
<string name="banner_updating_repositories">Updating repositories</string> <string name="banner_updating_repositories">Updating repositories</string>
<string name="banner_no_internet">No Internet</string>
<string name="status_processing_xml_percent">Processing %2$s / %3$s (%4$d%%) from %1$s</string> <string name="status_processing_xml_percent">Processing %2$s / %3$s (%4$d%%) from %1$s</string>
<string name="status_connecting_to_repo">Connecting to\n%1$s</string> <string name="status_connecting_to_repo">Connecting to\n%1$s</string>
<string name="status_inserting_apps">Saving app details</string> <string name="status_inserting_apps">Saving app details</string>