diff --git a/app/build.gradle b/app/build.gradle index b6b643b..58245e5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -42,6 +42,7 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.recyclerview:recyclerview:1.1.0' implementation 'com.google.android.material:material:1.1.0' + implementation 'androidx.preference:preference:1.1.1' implementation 'androidx.work:work-runtime:2.3.4' implementation "org.greenrobot:eventbus:$eventbus_version" annotationProcessor "org.greenrobot:eventbus-annotation-processor:$eventbus_version" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 82ecf92..a5b8f75 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -29,6 +29,13 @@ + + + diff --git a/app/src/main/java/dummydomain/yetanothercallblocker/App.java b/app/src/main/java/dummydomain/yetanothercallblocker/App.java index 975b3d8..8573287 100644 --- a/app/src/main/java/dummydomain/yetanothercallblocker/App.java +++ b/app/src/main/java/dummydomain/yetanothercallblocker/App.java @@ -1,5 +1,6 @@ package dummydomain.yetanothercallblocker; +import android.annotation.SuppressLint; import android.app.Application; import org.greenrobot.eventbus.EventBus; @@ -10,6 +11,7 @@ public class App extends Application { private static App instance; + @SuppressLint("StaticFieldLeak") private static Settings settings; @Override @@ -19,6 +21,7 @@ public class App extends Application { instance = this; settings = new Settings(this); + settings.init(); EventBus.builder() .throwSubscriberException(BuildConfig.DEBUG) diff --git a/app/src/main/java/dummydomain/yetanothercallblocker/GenericSettings.java b/app/src/main/java/dummydomain/yetanothercallblocker/GenericSettings.java index c79a0b9..f2824ab 100644 --- a/app/src/main/java/dummydomain/yetanothercallblocker/GenericSettings.java +++ b/app/src/main/java/dummydomain/yetanothercallblocker/GenericSettings.java @@ -5,13 +5,15 @@ import android.content.SharedPreferences; public class GenericSettings { + protected final Context context; protected final SharedPreferences pref; public GenericSettings(Context context, String name) { - this(context.getSharedPreferences(name, Context.MODE_PRIVATE)); + this(context, context.getSharedPreferences(name, Context.MODE_PRIVATE)); } - public GenericSettings(SharedPreferences pref) { + public GenericSettings(Context context, SharedPreferences pref) { + this.context = context; this.pref = pref; } @@ -43,4 +45,8 @@ public class GenericSettings { pref.edit().putLong(key, value).apply(); } + public boolean isSet(String key) { + return pref.contains(key); + } + } diff --git a/app/src/main/java/dummydomain/yetanothercallblocker/MainActivity.java b/app/src/main/java/dummydomain/yetanothercallblocker/MainActivity.java index ebadb7c..0038abd 100644 --- a/app/src/main/java/dummydomain/yetanothercallblocker/MainActivity.java +++ b/app/src/main/java/dummydomain/yetanothercallblocker/MainActivity.java @@ -196,6 +196,10 @@ public class MainActivity extends AppCompatActivity { loadCallLog(); } + public void onOpenSettings(MenuItem item) { + startActivity(new Intent(this, SettingsActivity.class)); + } + public void onOpenDebugActivity(MenuItem item) { startActivity(new Intent(this, DebugActivity.class)); } diff --git a/app/src/main/java/dummydomain/yetanothercallblocker/Settings.java b/app/src/main/java/dummydomain/yetanothercallblocker/Settings.java index c7e32fd..59232e0 100644 --- a/app/src/main/java/dummydomain/yetanothercallblocker/Settings.java +++ b/app/src/main/java/dummydomain/yetanothercallblocker/Settings.java @@ -2,16 +2,52 @@ package dummydomain.yetanothercallblocker; import android.content.Context; +import androidx.preference.PreferenceManager; + public class Settings extends GenericSettings { - private static final String PREF_INCOMING_CALL_NOTIFICATIONS = "incomingCallNotifications"; - private static final String PREF_BLOCK_CALLS = "blockCalls"; - private static final String PREF_USE_CONTACTS = "useContacts"; - private static final String PREF_LAST_UPDATE_TIME = "lastUpdateTime"; - private static final String PREF_LAST_UPDATE_CHECK_TIME = "lastUpdateCheckTime"; + public static final String PREF_INCOMING_CALL_NOTIFICATIONS = "incomingCallNotifications"; + public static final String PREF_BLOCK_CALLS = "blockCalls"; + public static final String PREF_USE_CONTACTS = "useContacts"; + public static final String PREF_LAST_UPDATE_TIME = "lastUpdateTime"; + public static final String PREF_LAST_UPDATE_CHECK_TIME = "lastUpdateCheckTime"; + + private static final String SYS_PREFERENCES_VERSION = "__preferencesVersion"; + + private static final int PREFERENCES_VERSION = 1; Settings(Context context) { - super(context, "yacb_preferences"); + super(context, PreferenceManager.getDefaultSharedPreferences(context)); + } + + private Settings(Context context, String name) { + super(context, name); + } + + public void init() { + int preferencesVersion = getInt(SYS_PREFERENCES_VERSION, -1); + + if (preferencesVersion == PREFERENCES_VERSION) return; + + if (preferencesVersion < 1) { + PreferenceManager.setDefaultValues(context, R.xml.root_preferences, false); + + Settings oldSettings = new Settings(context, "yacb_preferences"); + + if (oldSettings.isSet(PREF_INCOMING_CALL_NOTIFICATIONS)) { + setIncomingCallNotifications(oldSettings.getIncomingCallNotifications()); + } + if (oldSettings.isSet(PREF_BLOCK_CALLS)) { + setBlockCalls(oldSettings.getBlockCalls()); + } + if (oldSettings.isSet(PREF_USE_CONTACTS)) { + setUseContacts(oldSettings.getUseContacts()); + } + setLastUpdateTime(oldSettings.getLastUpdateTime()); + setLastUpdateCheckTime(oldSettings.getLastUpdateCheckTime()); + } + + setInt(SYS_PREFERENCES_VERSION, PREFERENCES_VERSION); } public boolean getIncomingCallNotifications() { diff --git a/app/src/main/java/dummydomain/yetanothercallblocker/SettingsActivity.java b/app/src/main/java/dummydomain/yetanothercallblocker/SettingsActivity.java new file mode 100644 index 0000000..39d0f24 --- /dev/null +++ b/app/src/main/java/dummydomain/yetanothercallblocker/SettingsActivity.java @@ -0,0 +1,100 @@ +package dummydomain.yetanothercallblocker; + +import android.os.Bundle; + +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.preference.Preference; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.PreferenceGroup; +import androidx.preference.PreferenceScreen; +import androidx.preference.SwitchPreferenceCompat; + +import dummydomain.yetanothercallblocker.work.UpdateScheduler; + +import static java.util.Objects.requireNonNull; + +public class SettingsActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.settings_activity); + + getSupportFragmentManager() + .beginTransaction() + .replace(R.id.settings, new SettingsFragment()) + .commit(); + + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.setDisplayHomeAsUpEnabled(true); + } + } + + public static class SettingsFragment extends PreferenceFragmentCompat { + + private static final String PREF_AUTO_UPDATE_ENABLED = "autoUpdateEnabled"; + + private final UpdateScheduler updateScheduler = UpdateScheduler.get(App.getInstance()); + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.root_preferences, rootKey); + + SwitchPreferenceCompat incomingCallNotificationPref = + requireNonNull(findPreference(Settings.PREF_INCOMING_CALL_NOTIFICATIONS)); + incomingCallNotificationPref.setOnPreferenceChangeListener((preference, newValue) -> { + if (Boolean.TRUE.equals(newValue)) { + PermissionHelper.checkPermissions((AppCompatActivity) getActivity(), true, false, false); + } + return true; + }); + + SwitchPreferenceCompat blockCallsPref = + requireNonNull(findPreference(Settings.PREF_BLOCK_CALLS)); + blockCallsPref.setOnPreferenceChangeListener((preference, newValue) -> { + if (Boolean.TRUE.equals(newValue)) { + PermissionHelper.checkPermissions((AppCompatActivity) getActivity(), false, true, false); + } + return true; + }); + + SwitchPreferenceCompat nonPersistentAutoUpdatePref = + requireNonNull(findPreference(PREF_AUTO_UPDATE_ENABLED)); + nonPersistentAutoUpdatePref.setChecked(updateScheduler.isAutoUpdateScheduled()); + nonPersistentAutoUpdatePref.setOnPreferenceChangeListener((preference, newValue) -> { + if (Boolean.TRUE.equals(newValue)) { + updateScheduler.scheduleAutoUpdates(); + } else { + updateScheduler.cancelAutoUpdateWorker(); + } + return true; + }); + + SwitchPreferenceCompat useContactsPref = + requireNonNull(findPreference(Settings.PREF_USE_CONTACTS)); + useContactsPref.setOnPreferenceChangeListener((preference, newValue) -> { + if (Boolean.TRUE.equals(newValue)) { + PermissionHelper.checkPermissions((AppCompatActivity) getActivity(), false, false, true); + } + return true; + }); + + PreferenceScreen preferenceScreen = getPreferenceScreen(); + int count = preferenceScreen.getPreferenceCount(); + for (int i = 0; i < count; i++) { + Preference preference = preferenceScreen.getPreference(i); + preference.setIconSpaceReserved(false); + if (preference instanceof PreferenceGroup) { + PreferenceGroup group = (PreferenceGroup) preference; + int nestedCount = group.getPreferenceCount(); + for (int k = 0; k < nestedCount; k++) { + Preference nested = group.getPreference(k); + nested.setIconSpaceReserved(false); + } + } + } + } + } +} diff --git a/app/src/main/res/layout/settings_activity.xml b/app/src/main/res/layout/settings_activity.xml new file mode 100644 index 0000000..de6591a --- /dev/null +++ b/app/src/main/res/layout/settings_activity.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/activity_main.xml b/app/src/main/res/menu/activity_main.xml index 43a3dec..0ad99c9 100644 --- a/app/src/main/res/menu/activity_main.xml +++ b/app/src/main/res/menu/activity_main.xml @@ -25,6 +25,10 @@ android:onClick="onUseContactsChanged" android:title="@string/use_contacts" /> + + diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 89f2aec..c2f9871 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -21,7 +21,9 @@ Робот/автомат Некоммерческая орг-я Блокир-ть нежелат. вызовы + Автоматически сбрасывать звонки c номеров с отрицательным рейтингом Авто-обновл. базы номеров + Получать ежедневные обновления базы (загружаются только изменения, поэтому расход трафика небольшой) Работа с базой номеров Работа с базой номеров Искать в установленной базе @@ -30,6 +32,7 @@ Не найдено Обновление завершено. Версия: %d Отображ. уведомл. при входящих + Отображает уведомление с краткой информацией о номере (рейтинги, кол-во отзывов, категория) при входящих вызовах Отзывы Загружаем отзывы… Факс @@ -64,5 +67,9 @@ Разрешите доступ к журналу вызовов, чтобы здесь отображались недавние вызовы Выполняется процесс в фоне… Отображать имена контактов + Номера из телефонной книги никогда не блокируются, и имя контакта отображается рядом/вместо номера Контакт + Настройки + Настройки + Основные \ 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 b30d7b9..0e3aeb6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -73,10 +73,18 @@ Are you sure? Loading online reviews will leak the number to a 3rd party service. Are you sure you want to do it with a number present in your Contacts? + Settings + Settings + Main + Incoming call notifications + Displays a notification with phone number summary (rating, reviews count, category) during incoming calls Block unwanted calls + Automatically blocks calls with negative rating Auto-update database + Automatically receive daily DB updates (these are incremental/delta updates, so they consume very little traffic) Use contacts + Numbers present in the phone book are never blocked and the contact name is displayed next to/instead of a number throughout the app Open debug screen Debug diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml new file mode 100644 index 0000000..3e4c696 --- /dev/null +++ b/app/src/main/res/xml/root_preferences.xml @@ -0,0 +1,25 @@ + + + + + + + + + +