From 8cce2d1362f64fc8e6a323284b7dc7a81432643c Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Fri, 18 Aug 2017 10:30:19 +0200 Subject: [PATCH] Pebble: allow to blacklist certain calendars As requested in #736, this adds an entry in the settings menu that allows to blacklist certain calendars. To avoid confusion, all the former blacklist methods and fields have been renamed to apps_blacklist. The new entries are called calendars_blacklist. Importing the settings has not been tested with the current changes. Closes #736 Future improvements TODO: The new setting lives in the Pebble section, i believe in the future the blackslist functionality should be centralized and put in the sidebar. --- CHANGELOG.md | 1 + app/src/main/AndroidManifest.xml | 4 + .../gadgetbridge/GBApplication.java | 110 +++++++++---- .../activities/CalBlacklistActivity.java | 152 ++++++++++++++++++ .../activities/SettingsActivity.java | 9 ++ .../adapter/AppBlacklistAdapter.java | 8 +- .../externalevents/CalendarReceiver.java | 1 - .../externalevents/NotificationListener.java | 4 +- .../gadgetbridge/model/CalendarEvents.java | 9 +- .../gadgetbridge/util/GBPrefs.java | 1 + .../util/ImportExportSharedPreferences.java | 25 +-- .../main/res/layout/activity_calblacklist.xml | 14 ++ .../main/res/layout/item_cal_blacklist.xml | 50 ++++++ app/src/main/res/values/strings.xml | 4 + app/src/main/res/xml/changelog_master.xml | 4 +- app/src/main/res/xml/preferences.xml | 3 + 16 files changed, 350 insertions(+), 49 deletions(-) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/CalBlacklistActivity.java create mode 100644 app/src/main/res/layout/activity_calblacklist.xml create mode 100644 app/src/main/res/layout/item_cal_blacklist.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index c3060aba..cbd03f1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * Handle resetting language to default properly * Pebble: Pass booleans from Javascript Appmessage correctly * Pebble: Make local configuration pages work on most recent webview implementation +* Pebble: Allow to blacklist calendars * Add greek transliteration support * Various visual improvements to charts diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 140de6d7..5dbae662 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -63,6 +63,10 @@ android:name=".activities.AppBlacklistActivity" android:label="@string/title_activity_appblacklist" android:parentActivityName=".activities.SettingsActivity" /> + blacklist = null; + private static HashSet apps_blacklist = null; - public static boolean isBlacklisted(String packageName) { - if (blacklist == null) { - GB.log("isBlacklisted: blacklisti is null!", GB.INFO, null); + public static boolean appIsBlacklisted(String packageName) { + if (apps_blacklist == null) { + GB.log("appIsBlacklisted: apps_blacklist is null!", GB.INFO, null); } - return blacklist != null && blacklist.contains(packageName); + return apps_blacklist != null && apps_blacklist.contains(packageName); } - public static void setBlackList(Set packageNames) { + public static void setAppsBlackList(Set packageNames) { if (packageNames == null) { - GB.log("Set null blacklist", GB.INFO, null); - blacklist = new HashSet<>(); + GB.log("Set null apps_blacklist", GB.INFO, null); + apps_blacklist = new HashSet<>(); } else { - blacklist = new HashSet<>(packageNames); + apps_blacklist = new HashSet<>(packageNames); } - GB.log("New blacklist has " + blacklist.size() + " entries", GB.INFO, null); - saveBlackList(); + GB.log("New apps_blacklist has " + apps_blacklist.size() + " entries", GB.INFO, null); + saveAppsBlackList(); } - private static void loadBlackList() { - GB.log("Loading blacklist", GB.INFO, null); - blacklist = (HashSet) sharedPrefs.getStringSet(GBPrefs.PACKAGE_BLACKLIST, null); - if (blacklist == null) { - blacklist = new HashSet<>(); + private static void loadAppsBlackList() { + GB.log("Loading apps_blacklist", GB.INFO, null); + apps_blacklist = (HashSet) sharedPrefs.getStringSet(GBPrefs.PACKAGE_BLACKLIST, null); + if (apps_blacklist == null) { + apps_blacklist = new HashSet<>(); } - GB.log("Loaded blacklist has " + blacklist.size() + " entries", GB.INFO, null); + GB.log("Loaded apps_blacklist has " + apps_blacklist.size() + " entries", GB.INFO, null); } - private static void saveBlackList() { - GB.log("Saving blacklist with " + blacklist.size() + " entries", GB.INFO, null); + private static void saveAppsBlackList() { + GB.log("Saving apps_blacklist with " + apps_blacklist.size() + " entries", GB.INFO, null); SharedPreferences.Editor editor = sharedPrefs.edit(); - if (blacklist.isEmpty()) { + if (apps_blacklist.isEmpty()) { editor.putStringSet(GBPrefs.PACKAGE_BLACKLIST, null); } else { - Prefs.putStringSet(editor, GBPrefs.PACKAGE_BLACKLIST, blacklist); + Prefs.putStringSet(editor, GBPrefs.PACKAGE_BLACKLIST, apps_blacklist); } editor.apply(); } - public static void addToBlacklist(String packageName) { - if (blacklist.add(packageName)) { - saveBlackList(); + public static void addAppToBlacklist(String packageName) { + if (apps_blacklist.add(packageName)) { + saveAppsBlackList(); } } - public static synchronized void removeFromBlacklist(String packageName) { - GB.log("Removing from blacklist: " + packageName, GB.INFO, null); - blacklist.remove(packageName); - saveBlackList(); + public static synchronized void removeFromAppsBlacklist(String packageName) { + GB.log("Removing from apps_blacklist: " + packageName, GB.INFO, null); + apps_blacklist.remove(packageName); + saveAppsBlackList(); + } + + private static HashSet calendars_blacklist = null; + + public static boolean calendarIsBlacklisted(String calendarDisplayName) { + if (calendars_blacklist == null) { + GB.log("calendarIsBlacklisted: calendars_blacklist is null!", GB.INFO, null); + } + return calendars_blacklist != null && calendars_blacklist.contains(calendarDisplayName); + } + + public static void setCalendarsBlackList(Set calendarNames) { + if (calendarNames == null) { + GB.log("Set null apps_blacklist", GB.INFO, null); + calendars_blacklist = new HashSet<>(); + } else { + calendars_blacklist = new HashSet<>(calendarNames); + } + GB.log("New calendars_blacklist has " + calendars_blacklist.size() + " entries", GB.INFO, null); + saveCalendarsBlackList(); + } + + public static void addCalendarToBlacklist(String calendarDisplayName) { + if (calendars_blacklist.add(calendarDisplayName)) { + saveCalendarsBlackList(); + } + } + + public static void removeFromCalendarBlacklist(String calendarDisplayName) { + calendars_blacklist.remove(calendarDisplayName); + saveCalendarsBlackList(); + } + + private static void loadCalendarsBlackList() { + GB.log("Loading calendars_blacklist", GB.INFO, null); + calendars_blacklist = (HashSet) sharedPrefs.getStringSet(GBPrefs.CALENDAR_BLACKLIST, null); + if (calendars_blacklist == null) { + calendars_blacklist = new HashSet<>(); + } + GB.log("Loaded calendars_blacklist has " + calendars_blacklist.size() + " entries", GB.INFO, null); + } + + private static void saveCalendarsBlackList() { + GB.log("Saving calendars_blacklist with " + calendars_blacklist.size() + " entries", GB.INFO, null); + SharedPreferences.Editor editor = sharedPrefs.edit(); + if (calendars_blacklist.isEmpty()) { + editor.putStringSet(GBPrefs.CALENDAR_BLACKLIST, null); + } else { + Prefs.putStringSet(editor, GBPrefs.CALENDAR_BLACKLIST, calendars_blacklist); + } + editor.apply(); } /** diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/CalBlacklistActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/CalBlacklistActivity.java new file mode 100644 index 00000000..15307a32 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/CalBlacklistActivity.java @@ -0,0 +1,152 @@ +/* Copyright (C) 2017 Daniele Gobbetti + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.activities; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.database.Cursor; +import android.graphics.Paint; +import android.net.Uri; +import android.os.Bundle; +import android.provider.CalendarContract; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.ActivityCompat; +import android.support.v4.app.NavUtils; +import android.view.LayoutInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.CheckBox; +import android.widget.ListView; +import android.widget.TextView; +import android.widget.Toast; + +import java.util.ArrayList; +import java.util.List; + +import nodomain.freeyourgadget.gadgetbridge.GBApplication; +import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.util.GB; + + +public class CalBlacklistActivity extends GBActivity { + + private final String[] EVENT_PROJECTION = new String[]{ + CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, + CalendarContract.Calendars.CALENDAR_COLOR + }; + private ArrayList calendarsArrayList; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_calblacklist); + ListView calListView = (ListView) findViewById(R.id.calListView); + + final Uri uri = CalendarContract.Calendars.CONTENT_URI; + if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) != PackageManager.PERMISSION_GRANTED) { + GB.toast(this, "Calendar permission not granted. Nothing to do.", Toast.LENGTH_SHORT, GB.WARN); + return; + } + try (Cursor cur = getContentResolver().query(uri, EVENT_PROJECTION, null, null, null)) { + calendarsArrayList = new ArrayList<>(); + while (cur != null && cur.moveToNext()) { + calendarsArrayList.add(new Calendar(cur.getString(0), cur.getInt(1))); + } + } + + ArrayAdapter calAdapter = new CalendarListAdapter(this, calendarsArrayList); + calListView.setAdapter(calAdapter); + calListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int i, long id) { + Calendar item = calendarsArrayList.get(i); + CheckBox selected = (CheckBox) view.findViewById(R.id.item_checkbox); + toggleEntry(view); + if (selected.isChecked()) { + GBApplication.addCalendarToBlacklist(item.displayName); + } else { + GBApplication.removeFromCalendarBlacklist(item.displayName); + } + } + }); + + + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + NavUtils.navigateUpFromSameTask(this); + return true; + } + return super.onOptionsItemSelected(item); + } + + private void toggleEntry(View view) { + TextView name = (TextView) view.findViewById(R.id.calendar_name); + CheckBox checked = (CheckBox) view.findViewById(R.id.item_checkbox); + + name.setPaintFlags(name.getPaintFlags() ^ Paint.STRIKE_THRU_TEXT_FLAG); + checked.toggle(); + } + + class Calendar { + private final String displayName; + private final int color; + + public Calendar(String displayName, int color) { + this.displayName = displayName; + this.color = color; + } + } + + private class CalendarListAdapter extends ArrayAdapter { + + CalendarListAdapter(@NonNull Context context, @NonNull List calendars) { + super(context, 0, calendars); + } + + @NonNull + @Override + public View getView(int position, @Nullable View view, @NonNull ViewGroup parent) { + Calendar item = getItem(position); + + if (view == null) { + LayoutInflater inflater = (LayoutInflater) super.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); + view = inflater.inflate(R.layout.item_cal_blacklist, parent, false); + } + + View color = view.findViewById(R.id.calendar_color); + TextView name = (TextView) view.findViewById(R.id.calendar_name); + CheckBox checked = (CheckBox) view.findViewById(R.id.item_checkbox); + + if (GBApplication.calendarIsBlacklisted(item.displayName) && !checked.isChecked()) { + toggleEntry(view); + } + color.setBackgroundColor(item.color); + name.setText(item.displayName); + + return view; + } + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java index 3e0066bc..94419a15 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java @@ -97,6 +97,15 @@ public class SettingsActivity extends AbstractSettingsActivity { } }); + pref = findPreference("pref_key_blacklist_calendars"); + pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + public boolean onPreferenceClick(Preference preference) { + Intent enableIntent = new Intent(SettingsActivity.this, CalBlacklistActivity.class); + startActivity(enableIntent); + return true; + } + }); + pref = findPreference("pebble_emu_addr"); pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/AppBlacklistAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/AppBlacklistAdapter.java index eb9c1693..f7ae70bf 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/AppBlacklistAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/AppBlacklistAdapter.java @@ -62,7 +62,7 @@ public class AppBlacklistAdapter extends RecyclerView.Adapter blacklist = new HashSet<>(); + Set apps_blacklist = new HashSet<>(); text=text.replace("[","").replace("]",""); for (int z=0;z calendars_blacklist = new HashSet<>(); + text = text.replace("[", "").replace("]", ""); + for (int z = 0; z < text.split(",").length; z++) { + calendars_blacklist.add(text.split(",")[z].trim()); + } + GBApplication.setCalendarsBlackList(calendars_blacklist); } } else if (!PREFERENCES.equals(name)) { throw new Exception("Unkown type " + name); diff --git a/app/src/main/res/layout/activity_calblacklist.xml b/app/src/main/res/layout/activity_calblacklist.xml new file mode 100644 index 00000000..60788e94 --- /dev/null +++ b/app/src/main/res/layout/activity_calblacklist.xml @@ -0,0 +1,14 @@ + + + + + diff --git a/app/src/main/res/layout/item_cal_blacklist.xml b/app/src/main/res/layout/item_cal_blacklist.xml new file mode 100644 index 00000000..7de67c23 --- /dev/null +++ b/app/src/main/res/layout/item_cal_blacklist.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index da2dec3f..07561eef 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -46,6 +46,9 @@ Notification Blacklist + + Blacklisted Calendars + FW/App installer You are about to install firmware %s instead of the one currently on your Mi Band. @@ -104,6 +107,7 @@ Blacklist Apps + Blacklist Calendars Canned Messages Replies diff --git a/app/src/main/res/xml/changelog_master.xml b/app/src/main/res/xml/changelog_master.xml index a8e90a3e..db648cc8 100644 --- a/app/src/main/res/xml/changelog_master.xml +++ b/app/src/main/res/xml/changelog_master.xml @@ -8,8 +8,8 @@ Add workaround for blacklist not properly persisting Handle resetting language to default properly Pebble: Pass booleans from Javascript Appmessage correctly - Pebble: Make local configuration pages work on most recent webview implementation - + Pebble: Make local configuration pages work on most recent webview implementation + Pebble: Allow to blacklist calendars Add greek transliteration support Various visual improvements to charts diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index df21d596..e4cc5581 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -208,6 +208,9 @@ android:key="enable_calendar_sync" android:summary="@string/pref_summary_enable_calendar_sync" android:title="@string/pref_title_enable_calendar_sync" /> +