Root permission for android application

Техника

Время на прочтение

Apps request root access will be listed as shown above. By default they will be set to Prompt. So every time the app requests root priviledge, you will get prompt to allow or deny root priviledge for the app. If you want to add root access to certain app, click on the down arrow after the Prompt to reveal more options, including Allow, Deny and Prompt.

You are here: Home / Android / How To Give Root Access To Your Apps In Your Android Device

In our previous articles we have written the benefits of rooting your device and also more specifically on how to root your android device. We also mentioned one of the benefits of rooting yourd device is that you are able to install root only apps from the play store which allows you to have greater control over your phone. This control comes from the apps accessing your core system files. To allow the apps to access and modify your system files you need to give the apps special root access without which they won’t be able to function properly.

So we have prepared a simple guide that will allow you to give the apps root access to your phone. Don’t worry every time an app requests root access to your phone you will be prompted and this will protect you from running any malicious apps that might damage your phone.

If your app needs root permissions to execute any command, you can do this using something like:

What I’ve done is to create an initial activiy to ask for permissions:

This layout only defines an info message and a button to ask for root permissions.

Введение

Разрешения, или Permissions, в официальной документации – это механизмы разграничения доступа к различным функциям на устройстве. Они, по сути, служат для обеспечения конфиденциальности пользователей, чтобы последние понимали, к каким данным и действиям имеет доступ приложение и что оно может делать.

Разрешения защищают доступ к:

А чтобы узнать, что из себя представляют разрешения на более низком уровне, в самом Android, достаточно покопаться в исходниках.

Многие механизмы безопасности Android основаны на принципах классических Linux-систем, и способы работы с разрешениями — не исключение. Как известно, каждое приложение, установленное на устройстве, имеет своего собственного пользователя и группу в Linux. На этой особенности создан механизм песочницы. То есть никто, кроме этого пользователя, не имеет права доступа к директории приложения.

На этой же основе построены и разрешения. В файле  frameworks/base/data/etc/platform.xml имена разрешений, которые есть в Android, сопоставлены с наименованиями групп в Linux.

Если пойти чуть глубже и посмотреть, что представляют из себя группы и как они работают внутри системы, то в файле system/core/include/private/android_filesystem_config.h можно увидеть сопоставление групп с их числовыми идентификаторами:

И на самом деле, когда приложение запрашивает какие-то привилегии в системе, используя механизм разрешений, всё, что происходит под капотом – это добавление пользователя в определенную группу. Соответственно, когда приложение пробует воспользоваться, например камерой, на уровне системы происходит проверка присутствия клиента в нужной группе. Всё гениальное просто и отлично работает!

Общие положения Android-разрешений

Вернемся на уровень выше и рассмотрим типы разрешений:

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

Запрос разрешения во время выполнения.

Специальные разрешения для прилоеджни

Группы разрешений

Разрешения могут принадлежать группам, которые состоят из набора логически связанных permissions. Например, разрешения на отправку и получение SMS могут входить в одну и ту же группу, поскольку они оба относятся к взаимодействию приложения с сообщениями.

Группы разрешений помогают системе свести к минимуму количество диалогов, которые отображаются пользователю, когда приложение запрашивает тесно связанные permissions. Когда пользователю предлагается предоставить разрешения для приложения, в том же интерфейсе размещаются остальные permissions, входящие в группу.

Разрешения используются для того, чтобы понять, имеет ли приложение права доступа к чувствительным данным или право на выполнение определенных операций (действий). Например, если программный продукт хочет получить доступ к контактам, то разработчику необходимо объявить разрешение в файле AndroidManifest.xml:

Это встроенное разрешение, которое имеет уровень защиты (protectionLevel) – dangerous. При установке приложения с данным разрешением Android ОС спросит пользователя о том, хочет ли он предоставить доступ к данным своих контактов.

Разработчики могут создать свои разрешения. Для этого их нужно прописать в файле AndroidManifest.xml:

Если какое-то стороннее приложение захочет использовать данные Activity, то разрешения необходимо также прописать в файле AndroidManifest.xml этого продукта:

И тогда при установке приложения ОС Android спросит пользователя, давать ли доступ приложению к камере или нет.

Уровни разрешений

Часто при установке приложения на Android нам приходилось видеть, что оно запрашивает какое-то немыслимое количество разрешений. Например:

Дополнительно:  Fix Audio Interface Causing BSOD. Error 0x000000b8/100000b8

Хорошо, если вы устанавливаете приложение от какого-то известного разработчика, которому можете доверять. Но весьма подозрительно, если вы устанавливаете новый музыкальный плеер, а ему для работы требуется, например, получать ваше местоположение. Или, тем более, фонарик, требующий доступ к смс и звонкам.

Некоторые разработчики, чтобы уменьшить недоверие, добавляют в описание приложения на Google Play информацию о том, зачем нужно то или иное разрешение.

К шестой версии Android ситуация поменялась. Теперь разрешения нужно запрашивать в процессе работы. О том, как этой новой возможностью пользоваться и ее некоторых подводных камнях будет рассказано далее.

Общая информация

Подобно тому, как это происходит в iOS, при запросе появится системный диалог с запросом разрешения.

Отличие в том, что после нажатия на кнопку “Deny” разрешение не будет полностью запрещено для приложения, как это происходит у Apple. Его можно будет запросить повторно, но в этом случае появится опция “Never ask again”, после выбора которой “Deny” работает как “Don’t allow” в iOS.

Разрешения делятся на два типа (есть и другие, но они нас не интересуют):

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

Можно увидеть, что доступ к интернету не считается опасным. Все, кто использует рекламу в своих программах, могут вздохнуть с облегчением: отключить её, просто отобрав разрешение, не получится (все еще можно просто отключить интернет, но факт остается фактом).

Взаимодействие с пользователем

Посмотрим, как нужно производить взаимодействие с пользователем. Начнем непосредственно с запроса разрешения. С обычными разрешениями все понятно, это дело установщика приложений, нас это не интересует, а то, как мы будем запрашивать опасные разрешения, зависит от двух вещей.

Первая из них — это важность данного разрешения для вашего приложения, от этого зависит, когда нужно производить запрос. Если функция критична и без нее программа не будет иметь смысла, то смело просите разрешения прямо при запуске приложения. Например, если вы разрабатываете приложение для обмена sms, то без соответствующих разрешений с ним ничего не получится сделать, оно теряет всякий смысл. А если пользователь отказал, то не пропускаем его дальше, но даем возможность снова вызвать диалог запроса и даем инструкции что нужно делать.

Если же разрешения требует некая вторичная функция, то не нужно просить о нем сразу. Делайте это только тогда, когда пользователь захочет воспользоваться этой возможностью.

Второй момент заключается в том, насколько ясно будет человеку, для чего нужно это разрешение. Зачем приложению для смс доступ к календарю? Наверное, для какой-то классной функции, которая облегчит перенос дат из сообщений в календарь и тому подобное. Но знаете об этом только вы, поэтому сначала нужно объяснить причину запроса и показать какие возможности даст доступ к этому разрешению. Это относится и к первичным и к вторичным разрешениям.

Еще раз кратко:

В случае, когда вам все-таки отказали, пояснение причины в следующий раз является обязательным. А если помимо отказа, пользователь попросил вас никогда не запрашивать данное разрешение, используя опцию “Never ask again”, но пытается использовать соответствующую функцию приложения, предложите ему перейти в настройки вашей программы и вручную включить необходимые разрешения. Это особенно важно, если разрешение критично для работы программы.

Код

Логичным вопросом будет: а что же произойдет, если запустить ваше неадаптированное под runtime разрешения приложение на Android Marshmallow? Ответ зависит от того осмелились ли вы изменить targetSdk на 23 версию (compileSdk и buildTools нас в данном случае не интересуют). Если да, то у меня не лучшие новости для вас: очень вероятно, что вы получите SecurityException. Это не обязательно будет так, возможно где-то вы получите null вместо запрошенной информации, но вероятность далеко не нулевая. Если же вы используете targetSdk версии 22 и ниже, то все разрешения будут, как и прежде выданы приложению при установке, включая опасные. Это не отменяет того, что пользователь может отозвать любое из них после установки. При этом он получит предупреждение, что приложение не адаптировано под runtime разрешения и может работать некорректно. Насколько некорректно оно будет работать, полностью зависит от вас, то есть если вы проверяли возвращаемые значения на null или были готовы к нулю вместо вменяемого значения, то ничего страшного не произойдет: приложение просто не будет полноценно функционировать (что выглядит все же лучше чем падение из-за NullPointerException).

Но даже если у вас все хорошо с проверками и нет возможности заниматься внедрением новых возможностей, стоит перепроверить, все ли правильно работает, потому что иногда можно получить null не там, где его ожидаешь. Так, например, при использовании Environment.getExternalStorageDirectory() без наличия разрешения из группы Storage, мы получим File, но list() вернет нам заветный null. В документации такой исход описан, но для ситуации, когда File не является директорией. Так что проверка в любом случае лишней не будет.

Дополнительно:  Как на bluestacks установить root права на

В процессе отладки часто приходится включать/отключать разрешения. Заходить для этого каждый раз в настройки приложения не очень удобно. К счастью, это можно сделать с помощью adb:

И еще несколько полезных команд, смысл которых ясен из названия:

adb shell pm reset-permissions
adb shell pm list permission-groups
adb shell pm list permissions

Перейдем к непосредственной реализации (предварительно не забудем обновить compileSdkVersion и targetSdkVersion до версии 23).

До момента, когда Marshmallow станет минимальной версией андроида для ваших приложений, еще далеко, поэтому нужно позаботиться об обратной совместимости. Конечно, можно делать проверки версии sdk, но зачем, если все реализовано за нас в support library v4 (ActivityCompat) и v13 (FragmentCompat). Если все же вам понадобятся оригинальные методы, то найти их не составит труда.

Во всех примерах используется ActivityCompat, так как они были сделаны для activity. Для fragment нужно использовать FragmentCompat. Если вы по какой-то причине не используете activity и fragment из support библиотек, то вам нужно реализовать интерфейс ActivityCompat.OnRequestPermissionsResultCallback или FragmentCompat.OnRequestPermissionsResultCallback соответственно.

Каждый раз, когда мы хотим использовать метод, требующий опасного разрешения, необходимо проверить есть ли оно у нас. Для этого используем метод ContextCompat.checkSelfPermission(Context context, String permission), который возвращает нам одно из int значений: PackageManager.PERMISSION_GRANTED в случае если разрешение есть или PackageManager.PERMISSION_DENIED если его нет. Именем разрешения является одна из констант класса Manifest.permission.

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

Стоит упомянуть, что если разрешения находятся в одной permission group, то запросить достаточно одно из них, так как все остальные элементы этой группы станут также доступны. Но так делать не нужно. Потому что в будущем состав групп может поменяться, поэтому при запросе разрешений не нужно делать предположений относительно того находятся ли они в одной группе или нет.

UPD будто в подтверждение предыдущего параграфа, начиная с Android 8.0 разрешения из одной permission group не выдаются сразу — каждое разрешение нужно запрашивать отдельно, но все разрешения из одной группы будут выданы автоматически, без участия пользователя при первом же их запросе.

UPD2 это же поведение было замечено на Android 7.0 — если часть разрешений из группы выдана (не могу сказать с уверенностью, имеет ли значение какие именно), то остальные будут выдаваться по запросу сразу же без показа диалога. Это может вызвать проблемы, если ваше приложение объясняет пользователю зачем ей нужно то или иное разрешение еще до его запроса. В реальной жизни такое редко когда может возникнуть (только при использовании adb комманд), но стоит учитывать это при отладке приложения.

Как видите, напрямую запрашивать разрешения можно только из Activity или Fragment. Если разрешение требуется сервису, то придется запускать Activity, из которой уже можно будет сделать запрос. Лучше всего перед этим будет показать уведомление, содержащее информацию о недостающем разрешении с кнопкой для запуска этой самой Activity.

Размер массива grantResults проверяется для того, чтобы удостовериться, что запрос разрешения не был прерван (в этом случае permissions и grantResults не будут содержать элементов). Такую ситуацию следует рассматривать не как запрет разрешения, а как отмену запроса на него.

Never ask again

Одной из проблем может стать опция “Never ask again”, которая появляется при повторном запросе разрешения, после того как пользователь уже отказал ранее. Как видно из названия, при её выборе диалог запроса не будет больше появляться. shouldShowRequestPermissionRationale будет выдавать false, а в onRequestPermissionsResult будет получен результат PackageManager.PERMISSION_DENIED. И получим разрешение мы, только если включить его непосредственно через настройки приложения в разделе Permissions.

Что с этим можно сделать? В первую очередь, конечно, сообщить пользователю, что для выполнения действия нет нужных прав. Далее возможным действием может быть предложение перейти в настройки и предоставить это разрешение вручную. Не лучший вариант, но лучше чем ничего. Реализовать это можно вновь с использованием Snackbar с кнопкой действия.

Перейти непосредственно на страницу с разрешениями не получится, поэтому лучшее, что вы можете сделать, это открыть настройки своего приложения. После этого можно, например, показать Toast с информацией, что нужно сделать.

В примере используются startActivityForResult и onActivityResult чтобы определить, что пользователь вернулся из activity настроек обратно в приложение и попробовать выполнить действие, которое нельзя было сделать без нужного разрешения. В методе showExtDirFilesCount нужно снова проверить есть ли разрешение для уверенности, что пользователь его все-таки выдал.

Здесь может возникнуть ситуация, которая не особенно мешает, если вы используете Snackbar для показа rationale, но портит UX, если вы решили использовать диалоги (причины этого решения мы не затрагиваем). А именно двойное появление rationale, до запроса разрешения и после него. Как это может произойти? У нас всего два метода, по которым мы можем судить о состоянии разрешения. Проблема в том, что до запроса разрешения ситуация, когда мы еще никогда не запрашивали это разрешение, и ситуация, когда пользователь ранее выбрал “Never ask again”, абсолютно одинаковы по значениям. А именно checkSeflPermission возвращает нам PERMISSION_DENIED, a shouldShowRequestPermissionRationale — false. Значит, показывать диалог для открытия настроек мы будем в onRequestPermissionsResult, где значение shouldShowRequestPermissionRationale точно будет разным для этих двух ситуаций. Все отлично? Не совсем. В этом callback’e никак нельзя определить была ли показана rationale или нет. Поэтому если вы показываете причину запроса, а далее пользователь просит больше его не спрашивать об этом разрешении, после нажатия на кнопку DENY он получит очередной rationale диалог, приглашающий его в настройки программы. Хорошие программы так себя не ведут.

Дополнительно:  Не работает микрофон Windows 10: на ноутбуке и компьютере

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

Intent

Есть еще одна важная рекомендация при использовании runtime разрешений. Не используйте их. Точнее, используйте, но только тогда, когда функционал, который вы собираетесь реализовать с их помощью, не сделал уже кто-то до вас.

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

Таким образом, вы сможете избавиться от некоторых опасных разрешений и упростите работу с приложением.

Заключение

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

(Visited 20,352 times, 2,440 visits today)

Solution 1

First: note that you can only execute shell commands using su (= you can only use shell commands as root, not java code).

Second: Not sure if this applies to all su apps out there, but this is the help message of su on my phone:

This means: you have to run su -c something (or su -c something — root, but rootis the default anyway). essentially this is equal to su on most Linux systems, except the daemon-thing, as there is no daemon ahndling su calls on regular linux systems.

If other su commands behave differently (which is possible), it’s more secure to open a stream to a shell, execute su, evaluate it’s return code, then proceed to execute other commands, finally execute exit.

Solution 2

Theres a good answer here — ANDROID: How to gain root access in an Android application?

«As far as I know, you can only run command-line commands using root privileges. You can use this generic class I made that wraps the root access in your code: http://muzikant-android.blogspot.com/2011/02/how-to-get-root-access-and-execute.html»

Comments

1. Permissions on Android

2. Распространенные ошибки при использовании разрешений в Android

3. Content Provider шарит все свои данные

4. Детекты линтера проблем в разрешениях

5. Описание флагов для открытия доступа к определенному Uri (например, в Content Provider)

Рекомендации при работе с разрешениями

Манифест приложения камеры:

Манифест приложения для чтения:

Чтобы предотвратить это, убедитесь, что каждое разрешение из экосистемы нескольких приложений объявляется индивидуально во всех продуктах.

В приведенном выше примере вместо атрибута android:permission (который устанавливает уровень доступа к компоненту), указано android:uses-permission. Это значит, что компонент не имеет уровня защиты, поэтому любое стороннее приложение сможет получить к нему доступ.

В этом случае для доступа к uri ContactsContract.CommonDataKinds.Phone требуется разрешение android.permission.READ_CONTACTS. Однако для доступа к content: //com.exampleapp.contacts не запрашиваются никакие права.

В случае с «bad» ContentProvider разрешит доступ ко всем своим данным.

Наша статья вдохновлена материалом одной известной компании и призвана лишний раз подчеркнуть, что даже в таком привычном и обыденном функционале, как механизм разрешений в Android, могут быть свои особенности и нюансы. И знание всех этих тонкостей поможет избежать ошибок. Надеемся, статья пригодится как начинающим Android-разработчикам, так и их старшим коллегам – для повторения материала.

И напоследок еще одна рекомендация – старайтесь регулярно проверять защищенность своих приложений. Все вместе мы сделаем нашу цифровую среду более безопасной!

Спасибо за внимание, с вами были Юрий Шабалин и Веселина Зацепина!

До новых встреч!

Оцените статью
Master Hi-technology
Добавить комментарий