"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.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.UpdateService;
import org.fdroid.fdroid.net.ConnectivityMonitorService;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
/**
* Widget which reflects whether or not a repo update is currently in progress or not. If so, shows
* some sort of feedback to the user.
* Banner widget which reflects current status related to repository updates.
* 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 {
private int updateServiceStatus = UpdateService.STATUS_COMPLETE_WITH_CHANGES;
private int networkState = ConnectivityMonitorService.FLAG_NET_NO_LIMIT;
public BannerUpdatingRepos(Context context) {
this(context, null);
}
@ -33,51 +52,65 @@ public class BannerUpdatingRepos extends androidx.appcompat.widget.AppCompatText
setPadding(padding, padding, padding, padding);
setBackgroundColor(0xFF4A4A4A);
setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
setText(R.string.banner_updating_repositories);
setTextColor(0xFFFFFFFF);
}
@Override
protected void 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
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
stopMonitoringRepoUpdates();
Context context = getContext();
LocalBroadcastManager.getInstance(context).unregisterReceiver(onRepoFeedback);
context.unregisterReceiver(onNetworkStateChanged);
}
private void monitorRepoUpdates() {
if (isInEditMode()) {
return;
}
LocalBroadcastManager.getInstance(getContext()).registerReceiver(onRepoFeedback,
new IntentFilter(UpdateService.LOCAL_ACTION_STATUS));
setBannerIsVisible(UpdateService.isUpdating());
}
private void setBannerIsVisible(boolean isUpdating) {
if (isUpdating) {
private void setBannerTextAndVisibility() {
if (updateServiceStatus == UpdateService.STATUS_INFO) {
setText(R.string.banner_updating_repositories);
setVisibility(View.VISIBLE);
} else if (networkState == ConnectivityMonitorService.FLAG_NET_UNAVAILABLE
|| networkState == ConnectivityMonitorService.FLAG_NET_DEVICE_AP_WITHOUT_INTERNET) {
setText(R.string.banner_no_internet);
setVisibility(View.VISIBLE);
} else {
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() {
@Override
public void onReceive(Context context, Intent intent) {
// Anything other than a STATUS_INFO broadcast signifies that it was complete (and out
// banner should be removed).
boolean isInfo = intent.getIntExtra(UpdateService.EXTRA_STATUS_CODE, 0) == UpdateService.STATUS_INFO;
setBannerIsVisible(isInfo);
updateServiceStatus = intent.getIntExtra(UpdateService.EXTRA_STATUS_CODE,
UpdateService.STATUS_COMPLETE_WITH_CHANGES);
setBannerTextAndVisibility();
}
};
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="download_404">The requested file was not found.</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_connecting_to_repo">Connecting to\n%1$s</string>
<string name="status_inserting_apps">Saving app details</string>