Added announcements

This commit is contained in:
M66B
2023-01-08 12:29:30 +01:00
parent 16baa2a336
commit 244f3e58ee
6 changed files with 256 additions and 8 deletions

View File

@@ -41,6 +41,7 @@ import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.text.Spanned;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Pair;
@@ -94,9 +95,12 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.Callable;
@@ -163,8 +167,9 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
static final int PI_THREAD = 3;
static final int PI_OUTBOX = 4;
static final int PI_UPDATE = 5;
static final int PI_WIDGET = 6;
static final int PI_POWER = 7;
static final int PI_ANNOUNCEMENT = 6;
static final int PI_WIDGET = 7;
static final int PI_POWER = 8;
static final String ACTION_VIEW_FOLDERS = BuildConfig.APPLICATION_ID + ".VIEW_FOLDERS";
static final String ACTION_VIEW_MESSAGES = BuildConfig.APPLICATION_ID + ".VIEW_MESSAGES";
@@ -183,6 +188,9 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
static final long UPDATE_DAILY = (BuildConfig.BETA_RELEASE ? 4 : 12) * 3600 * 1000L; // milliseconds
static final long UPDATE_WEEKLY = 7 * 24 * 3600 * 1000L; // milliseconds
private static final int ANNOUNCEMENT_TIMEOUT = 15 * 1000; // milliseconds
private static final long ANNOUNCEMENT_INTERVAL = 4 * 3600 * 1000L; // milliseconds
private static final int REQUEST_RULES_ACCOUNT = 2001;
private static final int REQUEST_RULES_FOLDER = 2002;
@@ -939,6 +947,7 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
if (!drawerLayout.isLocked(drawerContainer))
drawerLayout.closeDrawer(drawerContainer);
checkUpdate(true);
checkAnnouncements(true);
}
return !play;
}
@@ -1090,6 +1099,7 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
owner.start();
checkUpdate(false);
checkAnnouncements(false);
checkIntent();
}
@@ -1734,6 +1744,150 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
}.execute(this, args, "update:check");
}
private void checkAnnouncements(boolean always) {
if (TextUtils.isEmpty(BuildConfig.ANNOUNCEMENT_URI))
return;
long now = new Date().getTime();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
boolean announcements = prefs.getBoolean("announcements", true);
long last_announcement_check = prefs.getLong("last_announcement_check", 0);
if (!always && !announcements)
return;
if (!always && last_announcement_check + ANNOUNCEMENT_INTERVAL > now)
return;
prefs.edit().putLong("last_announcement_check", now).apply();
Bundle args = new Bundle();
args.putBoolean("always", always);
new SimpleTask<List<Announcement>>() {
@Override
protected List<Announcement> onExecute(Context context, Bundle args) throws Throwable {
StringBuilder response = new StringBuilder();
HttpsURLConnection urlConnection = null;
try {
URL latest = new URL(BuildConfig.ANNOUNCEMENT_URI);
urlConnection = (HttpsURLConnection) latest.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setReadTimeout(ANNOUNCEMENT_TIMEOUT);
urlConnection.setConnectTimeout(ANNOUNCEMENT_TIMEOUT);
urlConnection.setDoOutput(false);
ConnectionHelper.setUserAgent(context, urlConnection);
urlConnection.connect();
int status = urlConnection.getResponseCode();
InputStream inputStream = (status == HttpsURLConnection.HTTP_OK
? urlConnection.getInputStream() : urlConnection.getErrorStream());
if (inputStream != null) {
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = br.readLine()) != null)
response.append(line);
}
if (status != HttpsURLConnection.HTTP_OK)
throw new IOException("HTTP " + status + ": " + response);
DateFormat DTF = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.US);
List<Announcement> announcements = new ArrayList<>();
JSONObject jroot = new JSONObject(response.toString());
JSONArray jannouncements = jroot.getJSONArray("Announcements");
for (int i = 0; i < jannouncements.length(); i++) {
JSONObject jannouncement = jannouncements.getJSONObject(i);
String language = Locale.getDefault().getLanguage();
String title = jannouncement.optString("Title." + language);
if (TextUtils.isEmpty(title))
title = jannouncement.getString("Title");
String text = jannouncement.optString("Text." + language);
if (TextUtils.isEmpty(text))
text = jannouncement.getString("Text");
Announcement announcement = new Announcement();
announcement.id = jannouncement.getInt("ID");
announcement.test = jannouncement.optBoolean("Test");
announcement.title = title;
announcement.text = HtmlHelper.fromHtml(text, context);
if (jannouncement.has("Link"))
announcement.link = Uri.parse(jannouncement.getString("Link"));
announcement.expires = DTF.parse(jannouncement.getString("Expires")
.replace("Z", "+00:00"));
announcements.add(announcement);
}
return announcements;
} finally {
if (urlConnection != null)
urlConnection.disconnect();
}
}
@Override
protected void onExecuted(Bundle args, List<Announcement> announcements) {
boolean always = args.getBoolean("always");
NotificationManager nm =
Helper.getSystemService(ActivityView.this, NotificationManager.class);
if (!NotificationHelper.areNotificationsEnabled(nm))
return;
SharedPreferences.Editor editor = prefs.edit();
for (Announcement announcement : announcements) {
String key = "announcement." + announcement.id;
if (announcement.isExpired()) {
editor.remove(key);
nm.cancel(announcement.id);
} else {
boolean notified = prefs.getBoolean(key, false);
if (notified && !always)
continue;
editor.putBoolean(key, true);
NotificationCompat.Builder builder =
new NotificationCompat.Builder(ActivityView.this, "announcements")
.setSmallIcon(R.drawable.baseline_warning_white_24)
.setContentTitle(announcement.title)
.setContentText(announcement.text)
.setAutoCancel(true)
.setShowWhen(true)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setCategory(NotificationCompat.CATEGORY_REMINDER)
.setVisibility(NotificationCompat.VISIBILITY_SECRET);
if (announcement.link != null) {
Intent update = new Intent(Intent.ACTION_VIEW, announcement.link)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent piUpdate = PendingIntentCompat.getActivity(
ActivityView.this, PI_ANNOUNCEMENT, update, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(piUpdate);
}
nm.notify(announcement.id, builder.build());
}
}
editor.apply();
}
@Override
protected void onException(Bundle args, Throwable ex) {
if (args.getBoolean("always"))
Log.unexpectedError(getSupportFragmentManager(), ex);
}
}.execute(this, args, "announcements:check");
}
private void checkIntent() {
Intent intent = getIntent();
Log.i("View intent=" + intent +
@@ -2288,6 +2442,23 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
String download_url;
}
private class Announcement {
int id;
boolean test;
String title;
Spanned text;
Uri link;
Date expires;
boolean isExpired() {
if (this.test && !BuildConfig.DEBUG)
return true;
if (expires == null)
return true;
return (expires.getTime() < new Date().getTime());
}
}
public static class FragmentDialogFirst extends FragmentDialogBase {
@NonNull
@Override