Intereting Posts
Android: определить, отключены ли уведомления пользователем Тестирование JVM-модуля с помощью Mockito для тестирования Retrofit2 и RxJava для сетевых запросов Как свести к минимуму утечку батареи при тяжелых условиях эксплуатации Android Media Player перезагружает аудиозапись после выключения Как передать полезную нагрузку в RecyclerView.Adapter.notifyItemChanged? Предупреждения после обновления Xamarin Studio Имя файла отсутствует для openFileChooser Android 4.4.4 Facebook Connect Android – с помощью stream.publish @ http://api.facebook.com/restserver.php Android: разница между LocationManager.addProximityAlert () и LocationClient.addGeofences () Android ViewPager с масштабируемым ImageView Не удается выполнить синхронизацию (onPerformSync не вызывается) Robotium – выберите учетную запись в AccoutPicker с соло Android, как получить доступ к исходным ресурсам, которые я установил в папку res? Создание нового набора значков в Android Studio? Android-устройства, связанные с NSD, как отправлять сообщения с помощью сокетов (Client-Client)?

Android CheckCallingOrSelfPermission не возвращается должным образом

Я пишу службу, которая должна видеть, имеет ли ее вызывающий абонент определенное частное разрешение. Я не хочу запрещать звонящим, которым не хватает этого разрешения, я только хочу знать статус, чтобы я мог реагировать соответствующим образом. Казалось бы, метод Context checkCallingPermission() идеален для того, что мне нужно, возвращая 0, если вызывающий имеет указанное разрешение и -1 в противном случае. Тем не менее, я обнаружил, что -1 возвращается во всех случаях.

Я написал тестовый пример (используя аналогичный метод checkCallingOrSelfPermission() где я вытащил пакет PackageInfo из системы, перечислил каждый из моих разрешений (только один, запрошенный для пакета), и отобразил результат checkCallingOrSelfPermission() . Поскольку разрешения I Проверка m в этом случае – это именно те разрешения, которые я выполняю, я бы ожидал, что checkCallingOrSelfPermission() вернет 0 (PackageManager.PERMISSION_GRANTED) только … купите, он возвращает -1 (PackageManager.PERMISSION_DENIED).

Я проверил это и получил те же результаты как на эмуляторе 4.0, так и на устройстве 2.3.

Любая идея, что я делаю неправильно, чтобы вызвать эти вызовы?

Мой тестовый манифест включает:

 <permission android:protectionLevel="signatureOrSystem" android:name="abcd" /> <uses-permission android:name="abcd" /> 

Код моей тестовой активности:

 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); PackageManager pm = getPackageManager(); try { PackageInfo pi = pm.getPackageInfo("com.test.check", PackageManager.GET_PERMISSIONS); if ((null == pi.requestedPermissions) || (pi.requestedPermissions.length == 0)) { Log.d("CHECK", "Package has NO permissions!"); finish(); return; } for (int i = 0; i < pi.requestedPermissions.length; ++i) { Log.d("CHECK", pi.requestedPermissions[i] + " " + checkCallingOrSelfPermission(pi.requestedPermissions[i])); } } catch (NameNotFoundException e) { Log.d("CHECK", "Package name is wrong!"); } finish(); } 

И мои результаты теста:

 D/CHECK ( 3600): abcd -1 

Я не смог разрешить это в рамках моей службы, требующей проверки разрешений, но я нашел обход для службы (и проблему в моем тестовом случае).

Мой тестовый пример завершился неудачно, потому что разрешение, которое я создал и проверил с помощью «abcd», было переименовано в Android в записи <permission>, однако Android не смог равнозначно переименовать его в записи <uses-permission>. Он был переименован в то, что к нему добавлено имя моего пакета (и это переименование не происходит, если я предоставляю имя, включая период в нем, например «test.abcd»).

Хотя изменение имени разрешения фиксировало мой тестовый пример, в моем фактическом случае в службе уже использовалось полное имя разрешения, а checkCallingPermission() продолжает сбой. Однако я обнаружил, что метод checkPermission() работает, как ожидалось (за счет того, что мне нужно получить имя пакета вызывающего абонента).

Итак, чтобы подвести итог, следующее работает некорректно (хотя я не знаю почему):

 boolean permission = (PackageManager.PERMISSION_GRANTED == checkCallingPermission(PERMISSION_NAME)); 

В то время как это, кажется, работает правильно:

 PackageManager pm = getPackageManager(); boolean permission = (PackageManager.PERMISSION_GRANTED == pm.checkPermission(PERMISSION_NAME, pm.getNameForUid(getCallingUid())));