Improved deletion of notification channels

pull/212/head
M66B 3 years ago
parent ecc4e99356
commit 75f11e4d1b

@ -26,6 +26,7 @@ import android.app.NotificationManager;
import android.app.StatusBarManager; import android.app.StatusBarManager;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
@ -37,6 +38,8 @@ import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.provider.Settings; import android.provider.Settings;
import android.service.quicksettings.TileService; import android.service.quicksettings.TileService;
import android.text.TextUtils;
import android.util.Pair;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@ -54,11 +57,11 @@ import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.SwitchCompat; import androidx.appcompat.widget.SwitchCompat;
import androidx.constraintlayout.widget.Group; import androidx.constraintlayout.widget.Group;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
public class FragmentOptionsNotifications extends FragmentBase implements SharedPreferences.OnSharedPreferenceChangeListener { public class FragmentOptionsNotifications extends FragmentBase implements SharedPreferences.OnSharedPreferenceChangeListener {
@ -242,37 +245,107 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
(BuildConfig.DEBUG || debug) ? View.VISIBLE : View.GONE); (BuildConfig.DEBUG || debug) ? View.VISIBLE : View.GONE);
ibClear.setOnClickListener(new View.OnClickListener() { ibClear.setOnClickListener(new View.OnClickListener() {
@Override @Override
@RequiresApi(api = Build.VERSION_CODES.O)
public void onClick(View v) { public void onClick(View v) {
new SimpleTask<Pair<String[], String[]>>() {
@Override
protected Pair<String[], String[]> onExecute(Context context, Bundle args) throws Throwable {
String[] ids = NotificationHelper.getChannelIds(context);
String[] titles = new String[ids.length];
DB db = DB.getInstance(context);
for (int i = 0; i < ids.length; i++)
try {
if (ids[i].startsWith("notification.folder.")) {
long fid = Long.parseLong(ids[i].split("\\.")[2]);
EntityFolder folder = db.folder().getFolder(fid);
EntityAccount account = db.account().getAccount(folder == null ? -1L : folder.account);
titles[i] = (folder == null ? ids[i] : account.name + "/" + folder.name);
} else if (ids[i].startsWith("notification.")) {
String[] parts = ids[i].split("\\.");
if (parts.length == 2 && TextUtils.isDigitsOnly(parts[1])) {
long aid = Long.parseLong(parts[1]);
EntityAccount account = db.account().getAccount(aid);
titles[i] = (account == null ? ids[i] : account.name);
} else
titles[i] = ids[i].substring("notification.".length());
} else
titles[i] = ids[i];
} catch (Throwable ex) {
Log.e(ex);
titles[i] = ids[i];
}
return new Pair<>(ids, titles);
}
@Override
protected void onExecuted(Bundle args, Pair<String[], String[]> data) {
boolean[] selected = new boolean[data.first.length];
new AlertDialog.Builder(v.getContext())
.setIcon(R.drawable.twotone_delete_24)
.setTitle(R.string.title_advanced_notifications_delete)
.setMultiChoiceItems(data.second, selected, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
selected[which] = isChecked;
}
})
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Bundle args = new Bundle();
args.putStringArray("ids", data.first);
args.putBooleanArray("selected", selected);
new SimpleTask<Void>() { new SimpleTask<Void>() {
@Override @Override
protected Void onExecute(Context context, Bundle args) { protected Void onExecute(Context context, Bundle args) throws Throwable {
String[] ids = args.getStringArray("ids");
boolean[] selected = args.getBooleanArray("selected");
DB db = DB.getInstance(context); DB db = DB.getInstance(context);
List<EntityAccount> accounts = db.account().getAccounts(); for (int i = 0; i < selected.length; i++)
if (accounts == null) try {
return null; if (!selected[i])
continue;
if (ids[i].startsWith("notification.")) {
String[] parts = ids[i].split("\\.");
if (parts.length == 2 && TextUtils.isDigitsOnly(parts[1])) {
long aid = Long.parseLong(ids[i].split("\\.")[1]);
if (db.account().setAccountNotify(aid, false) != 1)
continue;
}
}
for (EntityAccount account : accounts) NotificationHelper.deleteChannel(context, ids[i]);
if (account.notify) { } catch (Throwable ex) {
EntityLog.log(context, account.name + " disabling notify"); Log.e(ex);
db.account().setAccountNotify(account.id, false);
} }
return null; return null;
} }
@Override @Override
@RequiresApi(api = Build.VERSION_CODES.O) protected void onException(Bundle args, Throwable ex) {
protected void onExecuted(Bundle args, Void data) { Log.unexpectedError(getParentFragmentManager(), ex);
NotificationHelper.clear(getContext()); }
ToastEx.makeText(getContext(), R.string.title_completed, Toast.LENGTH_LONG).show(); }.execute(FragmentOptionsNotifications.this, args, "channel:delete");
}
})
.setNegativeButton(android.R.string.cancel, null)
.show();
} }
@Override @Override
protected void onException(Bundle args, Throwable ex) { protected void onException(Bundle args, Throwable ex) {
Log.unexpectedError(getParentFragmentManager(), ex); Log.unexpectedError(getParentFragmentManager(), ex);
} }
}.execute(FragmentOptionsNotifications.this, new Bundle(), "notification:clear"); }.execute(FragmentOptionsNotifications.this, new Bundle(), "channel:list");
} }
}); });

@ -36,6 +36,7 @@ import androidx.annotation.RequiresApi;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -53,9 +54,12 @@ class NotificationHelper {
"notification", "notification",
"progress", "progress",
"update", "update",
"announcements",
"warning", "warning",
"error", "error",
"alerts" "alerts",
"LEAKCANARY_LOW",
"LEAKCANARY_MAX"
)); ));
@RequiresApi(api = Build.VERSION_CODES.O) @RequiresApi(api = Build.VERSION_CODES.O)
@ -165,15 +169,25 @@ class NotificationHelper {
} }
@RequiresApi(api = Build.VERSION_CODES.O) @RequiresApi(api = Build.VERSION_CODES.O)
static void clear(Context context) { static String[] getChannelIds(Context context) {
List<String> result = new ArrayList();
NotificationManager nm = Helper.getSystemService(context, NotificationManager.class); NotificationManager nm = Helper.getSystemService(context, NotificationManager.class);
for (NotificationChannel channel : nm.getNotificationChannels()) { for (NotificationChannel channel : nm.getNotificationChannels()) {
String id = channel.getId(); String id = channel.getId();
if (!PERSISTENT_IDS.contains(id)) { if (!PERSISTENT_IDS.contains(id))
EntityLog.log(context, "Deleting channel=" + id); result.add(id);
nm.deleteNotificationChannel(id);
} }
Collections.sort(result);
return result.toArray(new String[0]);
} }
@RequiresApi(api = Build.VERSION_CODES.O)
static void deleteChannel(Context context, String id) {
NotificationManager nm = Helper.getSystemService(context, NotificationManager.class);
nm.deleteNotificationChannel(id);
} }
@RequiresApi(api = Build.VERSION_CODES.O) @RequiresApi(api = Build.VERSION_CODES.O)

@ -664,6 +664,7 @@
<string name="title_advanced_default_folder">Select default folder</string> <string name="title_advanced_default_folder">Select default folder</string>
<string name="title_advanced_notifications">Manage notifications</string> <string name="title_advanced_notifications">Manage notifications</string>
<string name="title_advanced_notifications_delete">Delete notification channels</string>
<string name="title_advanced_notifications_default">Default channel</string> <string name="title_advanced_notifications_default">Default channel</string>
<string name="title_advanced_notifications_service">Monitoring channel</string> <string name="title_advanced_notifications_service">Monitoring channel</string>
<string name="title_advanced_notifications_newest_first">Show newest notifications first</string> <string name="title_advanced_notifications_newest_first">Show newest notifications first</string>

Loading…
Cancel
Save