在Android 7(API级别24)中,我的应用程序不允许静音手机(将铃声模式设置为静音)

时间:2016-08-25 17:32:48

标签: android android-audiomanager android-7.0-nougat

我有一个应用程序通过使用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权限列表,但无法找到任何相似的内容。

7 个答案:

答案 0 :(得分:49)

感谢您的回答,这里有一些细节。

为了能够将铃声模式设置为静音,您必须获得访问通知政策的许可(如@ucsunil所说)。

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

然后,检查您是否拥有此权限。如果不这样做,请打开&#34;请勿打扰访问&#34;为您的应用程序:

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

答案 1 :(得分:9)

您正在寻找的访问权限是:

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

您需要请求用户向您提供此特定权限。

答案 2 :(得分:4)

ACCESS_NOTIFICATION_POLICY被视为&#34;正常&#34;权限,这意味着您不必在运行时请求权限。您只需要将权限添加到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();

稍后在onPause()或onStop()

时重置过滤器

答案 3 :(得分:1)

根据Android文档,您必须授予对“请勿打扰”的访问权限。

  

从N开始,除非应用程序被授予免打扰访问权限,否则不允许切换“请勿打扰”的振铃模式调整。请参阅isNotificationPolicyAccessGranted()。

请查看link

希望它有所帮助!

答案 4 :(得分:1)

我已经解决了这个问题,打开设置菜单并要求用户在api&gt;时为其授予权限。 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();
    }
}

答案 5 :(得分:1)

嘿, 如果有人在 Kotlin 中需要此权限,请在这里

var notificationManager = this.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
        && !notificationManager.isNotificationPolicyAccessGranted
    ) {
        val intent = Intent(
            Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS
        )
        startActivity(intent)
    }

我真的很感谢你的救命建议! :D

答案 6 :(得分:0)

我仅在模拟器中遇到过此问题。当我在手机上运行该应用程序时,它永远不会出现,并且可以按预期运行。