W Androidzie 7 (poziom API 24) moja aplikacja nie może wyciszyć telefonu (ustaw tryb dzwonka na cichy)

Mam aplikację, która wycisza telefon za pomocą Audiomanagera i ustawia tryb dzwonka na cichy za pomocą tego kodu:

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

To działa z Androidem 6, ale teraz z Androidem 7, dostaję następujący błąd:

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)

Czy są jakieś nowe uprawnienia, o które muszę poprosić, aby to działało?

Przejrzałem listę uprawnień Androida, ale nie mogłem znaleźć żadnych, które wydawały się istotne.

Author: hichris123, 2016-08-25

5 answers

Dzięki za odpowiedzi, tutaj jest trochę więcej szczegółów.

Aby móc ustawić tryb dzwonka na cichy, musisz mieć uprawnienia dostępu do polityki powiadomień(jak powiedział @ucsunil).

Najpierw sprawdź, czy masz to pozwolenie. Jeśli tego nie zrobisz, otwórz Ustawienia dostępu nie przeszkadzać w aplikacji:

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);
}

Po uruchomieniu funkcji startActivity (), Android otwiera ustawienia dostępu nie przeszkadzać dla Twojej aplikacji.

To, co mnie zdezorientowało, to sposób, w jaki prosiłem o to uprawnienia są zupełnie inne od innych uprawnień.

Dla odniesienia, oto sposób, aby poprosić o pozwolenie 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);
}
 40
Author: Bjarte Aune Olsen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-29 22:39:05

Dostęp, którego szukasz to:

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

Musisz poprosić Użytkownika o udzielenie ci tego konkretnego uprawnienia.

 8
Author: ucsunil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-25 17:47:08

Access_notification_policy jest uważane za "normalne" uprawnienia, co oznacza, że nie musisz żądać uprawnień w czasie wykonywania. Musisz tylko dodać uprawnienia do AndroidManifest.xml

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

Następnie, aby wyciszyć wszystkie powiadomienia, możesz ustawić filtr przerwań na 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-tylko alarmy
INTERRUPTION_FILTER_ALL-zwykły filtr
INTERRUPTION_FILTER_NONE - bez przerw (MUTE)
INTERRUPTION_FILTER_PRIORITY-priorytetowe przerwania

Używam

 int previous_notification_interrupt_setting = notificationManager.getCurrentInterruptionFilter();

Aby zresetować filtr później, gdy onpause () lub onStop ()

 2
Author: Winston Brown,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-08 07:39:55

Na podstawie dokumentacji Androida, musisz przyznać dostęp Do nie przeszkadzać.

Od N dalej, Ustawienia trybu dzwonka, które przełączają Tryb nie przeszkadzać, nie są dozwolone, chyba że aplikacja otrzymała dostęp Do nie przeszkadzać. Patrz isNotificationPolicyAccessGranted ().

Proszę sprawdzić link

Mam nadzieję, że to pomoże!

 1
Author: Lucas Santos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-25 17:44:09

Rozwiązałem ten problem, otwierając menu ustawień i prosząc użytkownika o przyznanie mu uprawnień, jeśli api > 23.

Po prostu wywołaj requestMutePermissions () z dowolnego miejsca i będzie działać!

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();
    }
}
 0
Author: Waqar UlHaq,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-20 07:08:18