Improve enabling/disabling call screening

Thanks to an anonymous contributor for Huawei-related code and testing.
This commit is contained in:
xynngh 2020-10-17 23:45:11 +04:00
parent 683c69d7ab
commit 1e78c0a5e6
13 changed files with 253 additions and 34 deletions

View File

@ -0,0 +1,17 @@
package com.android.settings.applications;
public class PreferredSettingsUtils {
@SuppressWarnings({"unused", "RedundantSuppression"})
public enum PreferredApplication {
PREFERRED_HOME,
@SuppressWarnings("SpellCheckingInspection") PREFERRED_DAILER,
PREFERRED_MMS,
PREFERRED_CAMERA,
PREFERRED_GALLERY,
PREFERRED_MUSIC,
PREFERRED_MAIL,
PREFERRED_BROWSER
}
}

View File

@ -25,12 +25,14 @@ public class IntentHelper {
return intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
}
public static void startActivity(Context context, Intent intent) {
public static boolean startActivity(Context context, Intent intent) {
try {
context.startActivity(intent);
return true;
} catch (Exception e) {
LOG.warn("startActivity() error starting activity", e);
}
return false;
}
}

View File

@ -2,26 +2,40 @@ package dummydomain.yetanothercallblocker;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.telecom.PhoneAccount;
import android.telecom.TelecomManager;
import android.text.TextUtils;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.android.settings.applications.PreferredSettingsUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import static dummydomain.yetanothercallblocker.IntentHelper.startActivity;
import static java.util.Objects.requireNonNull;
public class PermissionHelper {
@ -127,6 +141,7 @@ public class PermissionHelper {
}
}
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
public static boolean hasNumberInfoPermissions(Context context) {
for (String permission : INFO_PERMISSIONS) {
if (!hasPermission(context, permission)) return false;
@ -151,12 +166,14 @@ public class PermissionHelper {
== PackageManager.PERMISSION_GRANTED;
}
public static void requestCallScreening(Activity activity) {
public static RequestToken requestCallScreening(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
RoleManagerHelper.requestCallScreeningRole(activity);
} else {
setAsDefaultDialer(activity);
return null;
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return setAsDefaultDialer(activity);
}
return null;
}
public static boolean isCallScreeningHeld(Context context) {
@ -167,15 +184,36 @@ public class PermissionHelper {
return isDefaultDialer(context);
}
public static void disableCallScreening(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (RoleManagerHelper.hasCallScreeningRole(context)) {
new AlertDialog.Builder(context)
.setTitle(R.string.default_caller_id_app)
.setMessage(R.string.default_caller_id_app_unset)
.setPositiveButton(R.string.open_system_settings,
(d, w) -> openDefaultAppsSettings(context))
.show();
return;
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
if (isDefaultDialer(context)) {
showDefaultDialerDialog(context, false);
}
}
}
public static boolean handleCallScreeningResult(Context context,
int requestCode, int resultCode) {
int requestCode, int resultCode,
RequestToken requestToken) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (RoleManagerHelper.handleCallScreeningResult(context, requestCode, resultCode)) {
return true;
}
}
return handleDefaultDialerResult(context, requestCode, resultCode);
return handleDefaultDialerResult(context, requestCode, resultCode, requestToken);
}
public static boolean isDefaultDialer(Context context) {
@ -187,22 +225,127 @@ public class PermissionHelper {
return BuildConfig.APPLICATION_ID.equals(telecomManager.getDefaultDialerPackage());
}
public static void setAsDefaultDialer(Activity activity) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) return;
if (isDefaultDialer(activity)) return;
@RequiresApi(Build.VERSION_CODES.N)
public static RequestToken setAsDefaultDialer(Activity activity) {
if (isDefaultDialer(activity)) return null;
Intent intent = new Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER);
intent.putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME,
BuildConfig.APPLICATION_ID);
activity.startActivityForResult(intent, REQUEST_CODE_DEFAULT_DIALER);
try {
activity.startActivityForResult(intent, REQUEST_CODE_DEFAULT_DIALER);
return new RequestToken(System.nanoTime());
} catch (Exception e) {
LOG.warn("setAsDefaultDialer()", e);
setAsDefaultDialerFallback(activity);
}
return null;
}
@RequiresApi(Build.VERSION_CODES.N)
private static void setAsDefaultDialerFallback(Context context) {
showDefaultDialerDialog(context, true);
}
@RequiresApi(Build.VERSION_CODES.N)
private static void showDefaultDialerDialog(Context context, boolean set) {
new AlertDialog.Builder(context)
.setTitle(R.string.default_phone_app)
.setMessage(set ? R.string.default_phone_app_set : R.string.default_phone_app_unset)
.setPositiveButton(R.string.open_system_settings,
(d, w) -> openDefaultDialerSettings(context))
.show();
}
@RequiresApi(Build.VERSION_CODES.N)
private static void openDefaultAppsSettings(Context context) {
if (startActivity(context, new Intent(Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS))) return;
startActivity(context, new Intent(Settings.ACTION_SETTINGS));
}
@RequiresApi(Build.VERSION_CODES.N)
private static void openDefaultDialerSettings(Context context) {
if (openDefaultDialerSettingsEmui(context)) return;
openDefaultAppsSettings(context);
}
@RequiresApi(Build.VERSION_CODES.M)
private static boolean openDefaultDialerSettingsEmui(Context context) {
if (!isEmui()) return false;
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_DIAL);
intentFilter.addDataScheme(PhoneAccount.SCHEME_TEL);
Intent preferredAppIntent = getEmuiPreferredAppIntent(intentFilter);
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.settings",
"com.android.settings.Settings$PreferredSettingsActivity"));
intent.putExtra("preferred_app_intent", preferredAppIntent);
intent.putExtra("preferred_app_intent_filter", intentFilter);
intent.putExtra("preferred_app_type",
PreferredSettingsUtils.PreferredApplication.PREFERRED_DAILER);
intent.putExtra("preferred_app_label", "");
intent.putExtra("preferred_app_package_name", "");
if (startActivity(context, intent)) {
return true;
}
return startActivity(context, new Intent("com.android.settings.PREFERRED_SETTINGS"));
}
private static boolean isEmui() {
// not sure about min and max SDK versions
if ("huawei".equalsIgnoreCase(Build.BRAND) || "honor".equalsIgnoreCase(Build.BRAND)) {
try {
@SuppressWarnings("JavaReflectionMemberAccess")
Field field = Intent.class.getField("FLAG_HW_HOME_INTENT_FROM_SYSTEM");
field.setAccessible(true);
return field.getInt(Intent.class) != 0;
} catch (Exception e) {
LOG.debug("isEmui()", e);
}
}
return false;
}
private static Intent getEmuiPreferredAppIntent(IntentFilter filter) {
Intent intent = new Intent(filter.getAction(0));
if (filter.countCategories() > 0 && !TextUtils.isEmpty(filter.getCategory(0))) {
intent.addCategory(filter.getCategory(0));
}
if (filter.countDataSchemes() > 0 && !TextUtils.isEmpty(filter.getDataScheme(0))) {
Uri localUri = Uri.parse(filter.getDataScheme(0) + ":");
String str = null;
if (filter.countDataTypes() > 0 && !TextUtils.isEmpty(filter.getDataType(0))) {
str = filter.getDataType(0);
if (!str.contains("\\") && !str.contains("/")) {
str = str + "/*";
}
}
intent.setDataAndType(localUri, str);
}
return intent;
}
public static boolean handleDefaultDialerResult(Context context,
int requestCode, int resultCode) {
int requestCode, int resultCode,
RequestToken requestToken) {
if (requestCode != REQUEST_CODE_DEFAULT_DIALER) return false;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) return true;
if (resultCode == Activity.RESULT_OK) return true;
if (resultCode != Activity.RESULT_OK) {
if (requestToken != null && System.nanoTime() - requestToken.timestamp
< TimeUnit.MILLISECONDS.toNanos(500)) {
// probably the request is not supported, try workarounds
setAsDefaultDialerFallback(context);
} else {
Toast.makeText(context, R.string.denied_default_dialer_message, Toast.LENGTH_LONG)
.show();
}
@ -210,4 +353,22 @@ public class PermissionHelper {
return true;
}
public static class RequestToken {
private final long timestamp;
private RequestToken(long timestamp) {
this.timestamp = timestamp;
}
public void onSaveInstanceState(@NonNull Bundle outState, String key) {
outState.putLong(key, timestamp);
}
public static RequestToken fromSavedInstanceState(@Nullable Bundle savedInstanceState,
String key) {
return savedInstanceState != null && savedInstanceState.containsKey(key)
? new RequestToken(savedInstanceState.getLong(key)) : null;
}
}
}

View File

@ -14,6 +14,7 @@ import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentTransaction;
import androidx.preference.EditTextPreference;
import androidx.preference.Preference;
@ -40,12 +41,19 @@ import static java.util.Objects.requireNonNull;
public class SettingsActivity extends AppCompatActivity
implements PreferenceFragmentCompat.OnPreferenceStartScreenCallback {
private static final String STATE_REQUEST_TOKEN = "STATE_REQUEST_TOKEN";
private PermissionHelper.RequestToken requestToken;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings_activity);
if (savedInstanceState == null) {
if (savedInstanceState != null) {
requestToken = PermissionHelper.RequestToken
.fromSavedInstanceState(savedInstanceState, STATE_REQUEST_TOKEN);
} else {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.settings, new SettingsFragment())
@ -58,6 +66,22 @@ public class SettingsActivity extends AppCompatActivity
}
}
@Override
protected void onResume() {
super.onResume();
updateCallScreeningPreference();
}
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
if (requestToken != null) {
requestToken.onSaveInstanceState(outState, STATE_REQUEST_TOKEN);
}
}
@Override
public boolean onPreferenceStartScreen(PreferenceFragmentCompat preferenceFragmentCompat,
PreferenceScreen preferenceScreen) {
@ -91,11 +115,16 @@ public class SettingsActivity extends AppCompatActivity
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (PermissionHelper.handleCallScreeningResult(this, requestCode, resultCode)) {
for (Fragment fragment : getSupportFragmentManager().getFragments()) {
if (fragment instanceof SettingsFragment) {
((SettingsFragment) fragment).updateCallScreeningPreference();
}
if (PermissionHelper.handleCallScreeningResult(
this, requestCode, resultCode, requestToken)) {
updateCallScreeningPreference();
}
}
private void updateCallScreeningPreference() {
for (Fragment fragment : getSupportFragmentManager().getFragments()) {
if (fragment instanceof SettingsFragment) {
((SettingsFragment) fragment).updateCallScreeningPreference();
}
}
}
@ -170,11 +199,16 @@ public class SettingsActivity extends AppCompatActivity
callScreeningPref.setChecked(PermissionHelper.isCallScreeningHeld(requireContext()));
callScreeningPref.setOnPreferenceChangeListener((preference, newValue) -> {
if (Boolean.TRUE.equals(newValue)) {
PermissionHelper.requestCallScreening(requireActivity());
FragmentActivity activity = requireActivity();
PermissionHelper.RequestToken requestToken
= PermissionHelper.requestCallScreening(activity);
if (activity instanceof SettingsActivity) {
((SettingsActivity) activity).requestToken = requestToken;
}
} else {
Toast.makeText(requireActivity(),
R.string.use_call_screening_service_disable_message,
Toast.LENGTH_LONG).show();
PermissionHelper.disableCallScreening(requireContext());
return false;
}
return true;
@ -299,9 +333,11 @@ public class SettingsActivity extends AppCompatActivity
}
public void updateCallScreeningPreference() {
SwitchPreferenceCompat callScreeningPref =
requireNonNull(findPreference(PREF_USE_CALL_SCREENING_SERVICE));
callScreeningPref.setChecked(PermissionHelper.isCallScreeningHeld(requireContext()));
SwitchPreferenceCompat callScreeningPref
= findPreference(PREF_USE_CALL_SCREENING_SERVICE);
if (callScreeningPref != null) {
callScreeningPref.setChecked(PermissionHelper.isCallScreeningHeld(requireContext()));
}
}
private void exportLogcat() {

View File

@ -94,7 +94,6 @@
<string name="use_contacts">Χρήση επαφών</string>
<string name="auto_updates_summary">Αυτόματη λήψη ημερήσιων ενημερώσεων της βάσης δεδομένων (αυτές είναι προσθετικές/delta ενημερώσεις, επομένως καταναλώνουν πολύ λίγα δεδομένα)</string>
<string name="auto_updates">Αυτόματη ενημέρωση βάσης δεδομένων</string>
<string name="use_call_screening_service_disable_message">Επιλέξτε διαφορετική \"Εφαρμογή τηλεφώνου\" ή \"Εφαρμογή αναγνώρισης κλήσης\" στις Ρυθμίσεις - Εφαρμογές - Προεπιλεγμένες εφαρμογές</string>
<string name="use_call_screening_service_summary">Επιτρέπει τον αποκλεισμό κλήσεων πριν αρχίσει να κουδουνίζει το τηλέφωνο. Απαιτεί η εφαρμογή να οριστεί ως \"Εφαρμογή τηλεφώνου\" (Android 79) ή ως \"Εφαρμογή αναγνώρισης κλήσης\" (Android 10+)</string>
<string name="use_call_screening_service">Σύνθετη λειτουργία αποκλεισμού κλήσεων</string>
<string name="block_blacklisted_summary">Αποκλεισμός κλήσεων από αριθμούς που έχουν προστεθεί στη μαύρη λίστα</string>

View File

@ -79,7 +79,6 @@
<string name="block_hidden_number_summary">(Expérimental.) Bloquer les appels provenant de numéros masqués. Fonctionne probablement mieux en mode blocage d\'appel avancé. Merci de signaler votre retour d\'expérience sur GitLab</string>
<string name="use_call_screening_service">Mode de blocage d\'appel avancé</string>
<string name="use_call_screening_service_summary">Permet de bloquer les appels avant que le téléphone ne commence à sonner. Nécessite que l\'application soit définie comme appli "téléphone" (Android 79) ou comme appli \"reconnaissance d\'appel entrant\" (Android 10+)</string>
<string name="use_call_screening_service_disable_message">Sélectionner une autre \"application téléphonique\" ou \"application d\'identification de l\'appelant\" dans Paramètres - Apps - Apps par défaut</string>
<string name="auto_updates">Mettre à jour automatiquement la base de données</string>
<string name="auto_updates_summary">Recevoir automatiquement les mises à jour quotidiennes de la BD (il s\'agit de mises à jour incrémentielles/delta, donc elles consomment très peu de données)</string>
<string name="use_contacts">Utiliser les contacts</string>

View File

@ -71,7 +71,6 @@
<string name="sia_category_survey">Anketa</string>
<string name="save_crashes_to_external_storage_summary">Spremi izvještaje i log-zapise o rušenju aplikacije u javno spremište, u protivnom se izvještaji o rušenju spremaju u mapu privatne aplikacije. Izvještaji mogu sadržavati osjetljive podatke (telefonske brojeve, imena kontakata). Ostale aplikacije s dozvolom za spemanje podataka mogu imati pristup tim podacima u javnom spremištu</string>
<string name="blacklist_item_date_no_info">nema podataka</string>
<string name="use_call_screening_service_disable_message">Odaberi „Aplikacija telefona” ili „Aplikacija ID oznake pozivatelja” u Postavke Aplikacije Standardne aplikacije</string>
<string name="back">Natrag</string>
<string name="settings_category_main">Glavna</string>
<string name="lookup_res_featured_name">Predstavljeno ime: %s</string>

View File

@ -4,7 +4,6 @@
<string name="use_contacts_summary">Nummer i telefonboken blokkeres aldri, og kontaktnavnet vises ved siden av/istedenfor et nummer i hele programmet</string>
<string name="auto_updates_summary">Motta daglige databaseoppdateringer (disse legger kun til endringer, slik at de bruker lite data)</string>
<string name="auto_updates">Automatisk oppdatering av database</string>
<string name="use_call_screening_service_disable_message">Velg forskjellig \"telefonprogram\" eller \"samtale-ID-program\" i Innstillinger → Programmer → Forvalgte programmer</string>
<string name="use_call_screening_service_summary">Blokkerer anrop før telefonen runger. Krever at programmet er satt som \"Telefonprogram\" (Android 79) eller som \"Samtale-ID-program\" (Android 10+)</string>
<string name="incoming_call_notifications_summary">Viser en merknad med telefonnummersammendrag (vurdering, vurderingsantall, kategori) ved innkommende anrop</string>
<string name="load_reviews_confirmation_message">Innlasting av nettbaserte vurderinger lekker nummeret til en tredjepartstjeneste. Er du sikker på at du vil gjøre dette med et nummer som er å finne i kontaktlisten\?</string>

View File

@ -163,7 +163,6 @@
<string name="export_logcat_summary">Eksportuj i udostępnij zawartość logcata wybranej przez siebie aplikacji (np. klientowi poczty elektronicznej). Raporty mogą zawierać dane wrażliwe (numery telefonów, nazwy kontaktów). Tylko wybrana aplikacja będzie miała dostęp do tych danych</string>
<string name="save_crashes_to_external_storage">Zapisz raporty w pamięci publicznej</string>
<string name="country_codes_info_summary">Kody krajów używane są w zapytaniach do serwerów zewnętrznych. Kody te ustawione są tak, aby naśladować działanie oficjalnej aplikacji zewnętrznej firmy. Jeśli kod pasuje do kraju, w którym przebywasz (a to może zostać wykryte poprzez twój adres IP), twoje zapytania będą wyglądać najbardziej niepozornie. Domyślnie używane jest automatyczne wykrywanie (na podstawie informacji o sieci komórkowej lub ustawień regionalnych systemu), co powinno wystarczyć większości użytkownikom, ale możesz ustawić kod ręcznie. Jest to 2-literowy kod zgodny ze standardem ISO 3166 (np. PL)</string>
<string name="use_call_screening_service_disable_message">Wybierz inną „Aplikację do obsługi telefonu” lub „Aplikację do identyfikacji rozmówcy i spamu” w Ustawienia → Aplikacje i powiadomienia → Aplikacje domyślne</string>
<string name="lookup_res_featured_name">Wyróżniona nazwa: %s</string>
<string name="title_lookup_number">Wyszukaj numer</string>
<string name="country_code_incorrect_format">Nieprawidłowy format kodu kraju. Wartość nie zostanie zmieniona</string>

View File

@ -30,7 +30,6 @@
<string name="block_blacklisted_summary">Блокировать звонки с номеров добавленных в чёрный список</string>
<string name="use_call_screening_service">Продвинутый режим блокирования вызовов</string>
<string name="use_call_screening_service_summary">Позволяет блокировать вызовы до того, как телефон зазвонит. Это требует назначить приложение \"приложением для звонков\" (на Android 79) или \"приложением для АОН и защиты от спама\" (на Android 10+)</string>
<string name="use_call_screening_service_disable_message">Выберите другое приложение для звонков или защиты от спама в меню Настройки - Приложения - Приложения по умолчанию</string>
<string name="auto_updates">Авто-обновл. базы номеров</string>
<string name="auto_updates_summary">Получать ежедневные обновления базы (загружаются только изменения, поэтому расход трафика небольшой)</string>
<string name="open_db_management_activity">Управление базой</string>
@ -64,6 +63,12 @@
<string name="feature_contacts">имена контактов</string>
<string name="denied_default_dialer_message">Продвинутый режим блокирования не сможет работать, т.к. приложение не назначено \"приложением для звонков\"</string>
<string name="denied_call_screening_role_message">Продвинутый режим блокирования не сможет работать, т.к. приложение не назначено \"приложением для АОН и защиты от спама\"</string>
<string name="default_caller_id_app">\"Приложение для АОН\" по умолчанию</string>
<string name="default_caller_id_app_unset">Выберите другое \"приложение для АОН и защиты от спама\" в \"Приложениях по умолчанию\" в настройках системы</string>
<string name="default_phone_app">\"Приложение для звонков\" по умолчанию</string>
<string name="default_phone_app_set">Выберите \"Yet Another Call Blocker\" в качестве \"приложения для звонков\" в \"Приложениях по умолчанию\" в настройках системы</string>
<string name="default_phone_app_unset">Выберите другое \"приложение для звонков\" в \"Приложениях по умолчанию\" в настройках системы</string>
<string name="open_system_settings">Открыть Настройки</string>
<string name="no_main_db_title">Загрузить базу номеров</string>
<string name="no_main_db_text">База номеров отсутствует. Для полноценной работы приложения требуется загрузка базы номеров (около 25 МБ трафика).</string>
<string name="download_main_db">Загрузить базу номеров</string>

View File

@ -80,7 +80,6 @@
<string name="auto_updates_summary">Günlük veri tabanı güncellemelerini otomatik olarak al (bunlar artımlı/delta güncellemelerdir, bu nedenle çok az veri harcarlar)</string>
<string name="use_monitoring_service_summary">Bazı telefonlarda telefon olaylarının alınmasına yardımcı olan, sürekli çalışan bir izleme hizmetini etkinleştirir. Bu özelliği sadece arama engelleme ve bilgilendirme bildirimleri çalışmıyorsa etkinleştirin. Bu özelliğin pil ömrü üzerinde hiçbir etkisi yoktur</string>
<string name="use_monitoring_service">Bir izleme hizmeti kullan</string>
<string name="use_call_screening_service_disable_message">Ayarlar - Uygulamalar - Öntanımlı uygulamalar bölümünde farklı \"Telefon uygulaması\" veya \"Arayan kimliği uygulaması\" seçin</string>
<string name="use_call_screening_service_summary">Telefon çalmaya başlamadan önce aramaları engellemeye izin verir. Uygulamanın \"Telefon uygulaması\" (Android 79) veya \"Arayan kimliği uygulaması\" (Android 10+) olarak ayarlanması gerekir</string>
<string name="use_call_screening_service">Gelişmiş arama engelleme modu</string>
<string name="block_blacklisted_summary">Kara listeye eklenen numaralardan gelen aramaları engelle</string>

View File

@ -30,7 +30,6 @@
<string name="block_blacklisted_summary">Блокувати дзвінки з номерів доданих в чорний список</string>
<string name="use_call_screening_service">Просунутий режим блокування викликів</string>
<string name="use_call_screening_service_summary">Дозволяє блокувати виклики до того, як телефон задзвонить. Це вимагає призначити додаток \"додатком для дзвінків \" (на Android 79) або \"додатком для АВН і захисту від спаму\" (на Android 10 +)</string>
<string name="use_call_screening_service_disable_message">Виберіть інший додаток для дзвінків або захисту від спаму в меню Налаштування - Додатки - Додатки за замовчуванням</string>
<string name="auto_updates">Авто-оновл. бази номерів</string>
<string name="auto_updates_summary">Отримувати щоденні оновлення бази (завантажуються тільки зміни, тому витрата трафіку невеликий)</string>
<string name="db_management_db_info">Інфо про встановлену базу</string>

View File

@ -59,6 +59,12 @@
<string name="feature_contacts">using contacts</string>
<string name="denied_default_dialer_message">Advanced call blocking won\'t work due to the app not being set as the \"Phone app\"</string>
<string name="denied_call_screening_role_message">Advanced call blocking won\'t work due to the app not being set as the \"Caller ID app\"</string>
<string name="default_caller_id_app">Default \"Caller ID app\"</string>
<string name="default_caller_id_app_unset">Select a different app as the \"Caller ID app\" in \"Default apps\" in system settings</string>
<string name="default_phone_app">Default \"Phone app\"</string>
<string name="default_phone_app_set">Select \"Yet Another Call Blocker\" as the \"Phone app\" in \"Default apps\" in system settings</string>
<string name="default_phone_app_unset">Select a different app as the \"Phone app\" in \"Default apps\" in system settings</string>
<string name="open_system_settings">Open Settings</string>
<string name="call_log_permission_message">Grant \"Phone\" permission to see recent calls</string>
@ -103,7 +109,6 @@
<string name="block_blacklisted_summary">Block calls from numbers added to the blacklist</string>
<string name="use_call_screening_service">Advanced call blocking mode</string>
<string name="use_call_screening_service_summary">Allows to block calls before the phone starts to ring. Requires the app to be set as the \"Phone app\" (Android 79) or as the \"Caller ID app\" (Android 10+)</string>
<string name="use_call_screening_service_disable_message">Select different \"Phone app\" or \"Caller ID app\" in Settings - Apps - Default apps</string>
<string name="use_monitoring_service">Use a monitoring service</string>
<string name="use_monitoring_service_summary">Enables an always-running monitoring service that helps with receiving telephony events on some phones. Enable this feature only if call blocking and informational notifications don\'t work. This feature has no effect on battery life</string>
<string name="auto_updates">Auto-update database</string>