В Android 7 (API-уровень 24) моему приложению запрещается отключать телефон (установить режим звонка на тихий)

У меня есть приложение, которое отключает телефон с помощью AudioManager и настраивает режим звонка, чтобы отключить этот код:

AudioManager audioManager = 
    (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
try {
    audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT)
} catch (Exception e) {
    e.printStackTrace();
}

Это работает с Android 6, но теперь с Android 7, я получаю следующую ошибку:

System.err: java.lang.SecurityException: Not allowed to change Do Not Disturb state
System.err: at android.os.Parcel.readException(Parcel.java:1683)
System.err: at android.os.Parcel.readException(Parcel.java:1636)
System.err: at android.media.IAudioService$Stub$Proxy.setRingerModeExternal(IAudioService.java:962)
System.err: at android.media.AudioManager.setRingerMode(AudioManager.java:1022)
System.err: at controllers.SearchResultController.mutePhone(SearchResultController.java:185)

Есть ли какие-либо новые разрешения, которые я должен попросить сделать эту работу?

Я просмотрел список разрешений для Android, но не нашел подходящего.

Ответы

Ответ 1

Спасибо за ваши ответы, здесь немного подробнее.

Чтобы установить режим звонка в беззвучный режим, вы должны запросить разрешение на доступ к политике уведомлений (как сказал @ucsunil).

<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />

Затем проверьте, есть ли у вас это разрешение. Если вы этого не сделаете, откройте настройки "Не беспокоить доступ" для вашего приложения:

NotificationManager notificationManager = 
    (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
    && !notificationManager.isNotificationPolicyAccessGranted()) {

    Intent intent = new Intent(
                        android.provider.Settings
                        .ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);

    startActivity(intent);
}

При запуске startActivity() Android открывает настройки доступа "Не беспокоить" для вашего приложения.

Что меня смутило, так это то, что способ получения этого разрешения полностью отличается от других разрешений.

Просто для справки, вот способ запросить разрешение READ_CONTACTS:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
    && ActivityCompat.checkSelfPermission(activity,
        Manifest.permission.READ_CONTACTS)
        == PackageManager.PERMISSION_DENIED) {

    ActivityCompat.requestPermissions(activity,
        new String[]{ Manifest.permission.READ_CONTACTS },
            REQUEST_CODE_READ_CONTACTS);
}

Ответ 2

Доступ, который вы ищете, это:

<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />

Вам нужно попросить пользователя предоставить вам это конкретное разрешение.

Ответ 3

ACCESS_NOTIFICATION_POLICY считается "нормальным" разрешением, что означает, что вам не нужно запрашивать разрешения во время выполнения. Вам нужно только добавить разрешение на AndroidManifest.xml

    <uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />

Затем, чтобы отключить все уведомления, вы можете установить фильтр прерывания на INTERRUPTION_FILTER_NONE

NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            previous_notification_interrupt_setting = notificationManager.getCurrentInterruptionFilter();
            notificationManager.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_NONE);
        }

INTERRUPTION_FILTER_ALARMS - Только сигналы тревоги
INTERRUPTION_FILTER_ALL - Обычный фильтр
INTERRUPTION_FILTER_NONE - Без прерываний (MUTE)
INTERRUPTION_FILTER_PRIORITY - приоритетные перерывы

Я использую

 int previous_notification_interrupt_setting = notificationManager.getCurrentInterruptionFilter();

до reset фильтр позже, когда onPause() или onStop()

Ответ 4

На основе документации на Android вы должны предоставить доступ к Do Not Disturb.

Начиная с N, настройки режима звонка, которые будут переключаться на "Не беспокоить", не разрешены, если приложение не было предоставлено. "Не беспокоить доступ". См. IsNotificationPolicyAccessGranted().

Пожалуйста, проверьте ссылку

Надеюсь, что это поможет!

Ответ 5

Я решил эту проблему, открыв меню настроек и попросив пользователя предоставить разрешение на него, если api> 23.

Просто вызовите requestMutePermissions() из любого места, и оно будет работать!

private void requestMutePermissions() {
    try {
        if (Build.VERSION.SDK_INT < 23) {
            AudioManager audioManager = (AudioManager)getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
            audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
        } else if( Build.VERSION.SDK_INT >= 23 ) {
            this.requestForDoNotDisturbPermissionOrSetDoNotDisturbForApi23AndUp();
        }
    } catch ( SecurityException e ) {

    }
}

private void requestForDoNotDisturbPermissionOrSetDoNotDisturbForApi23AndUp() {

    NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
    // if user granted access else ask for permission
    if ( notificationManager.isNotificationPolicyAccessGranted()) {
        AudioManager audioManager = (AudioManager) getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
        audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
    } else{
        // Open Setting screen to ask for permisssion
        Intent intent = new Intent(android.provider.Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
        startActivityForResult( intent, ON_DO_NOT_DISTURB_CALLBACK_CODE );
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Check which request we're responding to
    if (requestCode == ON_DO_NOT_DISTURB_CALLBACK_CODE ) {
        this.requestForDoNotDisturbPermissionOrSetDoNotDisturbForApi23AndUp();
    }
}

Ответ 6

@Bjarte, что происходит, потому что с API-уровня 23 у вас есть разрешения во время выполнения. После того, как эта NotifyPolicy была добавлена ​​в уровне 23 api, почему вы должны реализовать по-другому.

ps: Извините, я не могу добавить это как комментарий:/

Привет