En Android 7 (API nivel 24) mi aplicación no se permite silenciar el teléfono (establecer el modo de timbre en silencio)

Tengo una aplicación que silencia el teléfono usando AudioManager y el modo de timbre de ajuste en silencio con este código:

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

Esto funciona con Android 6, pero ahora con Android 7, me sale el siguiente error:

 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) 

¿Hay nuevos permisos que necesito pedir para que esto funcione?

Miré a través de la lista de permisos de Android, pero no pude encontrar ninguna que parecía relevante.

Gracias por sus respuestas, aquí hay un poco más de detalle.

Para poder establecer el modo de timbre en silencio, debe tener permiso para acceder a la política de notificación (como @ucsunil dijo).

Primero compruebe si tiene este permiso. Si no lo hace, abra la configuración del acceso No molestar para su aplicación:

 NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && !notificationManager.isNotificationPolicyAccessGranted()) { Intent intent = new Intent( android.provider.Settings .ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS); startActivity(intent); } 

Cuando ejecuta startActivity (), Android abre la configuración de acceso de No molestar para su aplicación.

Lo que me confundió, fue que la forma de pedir este permiso es completamente diferente de otros permisos.

Sólo para referencia, aquí está la manera de pedir permiso 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); } 

Basado en la documentación de Android, tiene que conceder acceso a No molestar.

Desde N en adelante, los ajustes del modo de timbre que cambiarían de No molestar no se permiten a menos que se haya concedido a la aplicación Acceso a No molestar. Consulte isNotificationPolicyAccessGranted ().

Por favor revise el enlace

¡Espero eso ayude!

El acceso que buscas es:

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

Debe solicitar al usuario que le proporcione este permiso específico.

ACCESS_NOTIFICATION_POLICY se considera un permiso "normal", lo que significa que NO tiene que solicitar permiso en tiempo de ejecución. Solo tienes que agregar el permiso a AndroidManifest.xml

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

A continuación, para silenciar todas las notificaciones, puede establecer el filtro Interrupción en 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 – Sólo alarmas
INTERRUPTION_FILTER_ALL – Filtro normal
INTERRUPTION_FILTER_NONE – Sin interrupciones (MUTE)
INTERRUPTION_FILTER_PRIORITY – Interrupciones prioritarias

yo suelo

  int previous_notification_interrupt_setting = notificationManager.getCurrentInterruptionFilter(); 

Para restablecer el filtro más tarde cuando onPause () o onStop ()

@Bjarte que sucede porque desde el nivel 23 de API tiene permisos en tiempo de ejecución. Una vez que esta NotifyPolicy se agregó en api nivel 23 también, es por eso que tienes que implementar de una manera diferente.

Ps: Lo siento, no puedo agregar esto como un comentario: /

Saludos

  • ¿Cómo puedo enviar un archivo pregrabado (wav) durante una llamada de voz?
  • Cómo silenciar el "pitido" por MediaRecorder.start ()?
  • Reproducir / grabar archivos .DSS o .DS2
  • Cambio de volumen Listener: ¿Es preferible registerMediaButtonEventReceiver a onKeyDown?
  • Android MediaPlayer - cómo jugar en el STREAM_ALARM?
  • Android: forzar el micrófono externo (entrada jack 3,5 mm) para permanecer en
  • Cómo detectar capacidades de auriculares
  • Android: Actividad de llamada del fragmento
  • Volumen de secuencia en SoundPool vs volumen en AudioManager
  • Utilizar AudioManager interfiere con el audio de la llamada
  • Android es la forma más rápida de cargar y reproducir sonido en la aplicación
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.