ContextCompat.checkSelfPermission() возвращает PERMISSION_DENIED, хотя разрешение предоставлено

Я пытаюсь получить разрешение BIND_NOTIFICATION_LISTENER_SERVICE, предоставленное пользователем. Для этого я открываю приложение настроек в правильном месте, используя:

Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
startActivity(intent);

Что уже странно, так это то, что Настройки открываются дважды (если вы нажмете кнопку «Назад» один раз, снова откроется тот же экран настроек)

Однако в onResume() я затем проверяю, было ли предоставлено разрешение, используя:

if(ContextCompat.checkSelfPermission(context,Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE)== PackageManager.PERMISSION_GRANTED){
   //open next activity
}

И вот проблема: не имеет значения, предоставил ли пользователь разрешение в настройках, потому что checkSelfPermission() всегда возвращает PERMISSION_DENIED.

И теперь становится действительно странно: мой NotificationListenerService создан, связан и полностью работает, хотя разрешение не было предоставлено в соответствии с checkSelfPermission().

Как я должен узнать, предоставил ли пользователь разрешение?

Декларация разрешений и услуг в моем манифесте:

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

    <application>      
        <service
            android:name=".service.NotificationListener"
            android:directBootAware="true"
            android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
            <intent-filter>
                <action android:name="android.service.notification.NotificationListenerService" />
            </intent-filter>
        </service>
    </application>

My NotificationListenerService:

public class NotificationListener extends NotificationListenerService {

    private static final String TAG = NotificationListener.class.getSimpleName();

    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {
        super.onNotificationPosted(sbn);
        Log.d(TAG, "onNotificationPosted: "+sbn.getNotification().tickerText + " ;" + sbn.getPackageName());
    }
}

Что я уже пробовал:

  • Разные устройства и уровни API (включая эмуляторы) -> Везде одна и та же проблема
  • PermissionChecker.checkSelfPermission (не знаю, в чем разница по сравнению с ContextCompat.checkSelfPermission(), но возвращает тот же результат)
  • Android Bug Tracker -> нет известных проблем



Ответы (1)


Согласно документации разрешение BIND_NOTIFICATION_LISTENER_SERVICE имеет:

Уровень защиты: подпись

Это означает, что его могут иметь и использовать только системные приложения. Запрос разрешений указанным вами способом возможен только в том случае, если разрешение имеет:

Уровень защиты: опасный

Если ваше приложение не является системным приложением, и вы не рутировали устройство, чтобы иметь возможность установить на него пользовательское ПЗУ с вашим собственным сертификатом (ваше приложение также должно быть подписано с ним), то вы просто не можете получить это разрешение .

person R. Zagórski    schedule 09.04.2017