Как получить разрешение на чтение SMS в Android
Что проверяют
Формально это вопрос про runtime-разрешения, но сильный ответ начинается с того, что READ_SMS почти никому нельзя. Интервьюер хочет услышать про ограничения Google Play и альтернативы. Следом спрашивают, как получить код из SMS для входа без этого разрешения.
Как отвечать
Техническая часть. READ_SMS относится к опасным (dangerous) разрешениям, поэтому с Android 6.0 его мало объявить в манифесте через <uses-permission>, нужно запросить во время работы:
- проверка:
ContextCompat.checkSelfPermission(context, Manifest.permission.READ_SMS); - запрос: современный способ через
registerForActivityResult(ActivityResultContracts.RequestPermission()). СвязкаrequestPermissionsиonRequestPermissionsResultв androidx помечена устаревшей; - объяснение: если
shouldShowRequestPermissionRationaleвернулtrue, пользователь уже отказывал, и перед повторным запросом стоит показать, зачем разрешение нужно; - чтение:
ContentResolver.queryпоTelephony.Sms.Inbox.CONTENT_URI, в фоне, не на главном потоке.
Теперь главное. Google Play пускает приложения с разрешениями групп SMS и журнала звонков, только если приложение стало обработчиком SMS по умолчанию или попадает в узкий список исключений, и это оформляется декларацией в Play Console. Для кода подтверждения разрешение не нужно вовсе:
- SMS Retriever API: без участия пользователя, но сообщение должно содержать хеш вашего приложения;
- SMS User Consent API: система показывает диалог с одним конкретным сообщением, пользователь подтверждает, и вы получаете его текст.
Где спотыкаются
Рассказывают только про манифест и запрос, не упомянув политику магазина. На практике такое приложение не пройдёт ревью.
Не обрабатывают постоянный отказ. С Android 11 после двух отказов система перестаёт показывать диалог, и остаётся только отправить пользователя в настройки через Settings.ACTION_APPLICATION_DETAILS_SETTINGS.
Запрашивают разрешение при старте приложения, а не в момент, когда пользователь открыл функцию. Без контекста отказов заметно больше.