AndroidManifest Permissions sunt declarații de permisiuni în fișierul AndroidManifest.xml care determină la ce resurse și date de sistem are acces aplicația. Android cere ca fiecare permisiune să fie specificată în manifest înainte de utilizarea API-ului corespunzător: de la cameră și geolocație până la trimiterea SMS și accesul la contacte. Conform Android Developer Documentation, fiecare permisiune se împarte într-unul din patru niveluri de protecție: normal, dangerous, signature și special.
Principalele puncte
AndroidManifest Permissions este mecanismul de securitate Android care controlează accesul aplicațiilor la datele protejate și funcțiile de sistem. Fiecare aplicație trebuie să declare permisiunile necesare în fișierul AndroidManifest.xml folosind elementul <uses-permission>. Fără declarare, apelarea API-ului corespunzător se va încheia cu eroarea de securitate SecurityException.
Modelul de permisiuni Android a trecut prin mai multe etape de evoluție. Înainte de Android 6.0 (API 23), toate permisiunile erau acordate la instalare — utilizatorul vedea lista completă și accepta sau refuza instalarea aplicației. Începând cu Android 6.0, permisiunile de nivel dangerous sunt solicitate în timpul execuției (Runtime Permissions), oferind utilizatorului un control mai flexibil.
Permisiunile sunt împărțite în patru niveluri de protecție: normal (acordate automat la instalare), dangerous (necesită solicitare în timpul execuției), signature (disponibile doar aplicațiilor semnate cu același certificat) și special (necesită activare separată în setări). Fiecare nivel are propriul mecanism de acordare și retragere.
Conform Google I/O 2024, în Android 15 este planificată introducerea permisiunilor mai granulare — utilizatorul va putea acorda acces doar la anumite fișiere din biblioteca media, nu la întreaga bibliotecă. Aceasta continuă tendința Android de a minimiza volumul datelor furnizate implicit.
Spre deosebire de iOS, unde toate permisiunile sunt solicitate în timpul execuției (runtime), Android împarte permisiunile în cele de instalare (install-time) și cele de execuție (runtime). Nivelul normal este acordat automat la instalare fără notificarea utilizatorului. Nivelul dangerous necesită un dialog explicit, ca în iOS.
O altă diferență: în Android, permisiunile sunt grupate în grupuri (permission groups). Dacă utilizatorul a acceptat accesul la cameră, aplicația primește automat acces la microfon — sunt în același grup MICROPHONE. În iOS, fiecare permisiune este solicitată separat, independent de grup.
| Versiunea Android | Schimbarea în modelul permisiunilor |
|---|---|
| Android 1.0–5.x | Toate permisiunile sunt acordate la instalare (install-time) |
| Android 6.0 (API 23) | Introducerea Runtime Permissions pentru nivelul dangerous |
| Android 10 (API 29) | Scoped Storage — acces restricționat la sistemul de fișiere |
| Android 11 (API 30) | Resetarea automată a permisiunilor — permisiunile neutilizate se resetează |
| Android 14 (API 34) | Permisiuni Runtime pentru accesul media (foto, video, audio) |
Android definește patru niveluri de protecție (protection levels) pentru permisiuni, fiecare cu propriile reguli de acordare. Să examinăm fiecare nivel în detaliu.
Permisiunile normal sunt acordate automat la instalarea aplicației fără notificare sau solicitare din partea utilizatorului. Acestea acoperă accesul la funcții cu risc scăzut care nu amenință confidențialitatea utilizatorului: INTERNET, ACCESS_NETWORK_STATE, VIBRATE, BLUETOOTH. Utilizatorul nu vede un dialog de acord — permisiunea este considerată acordată prin simpla instalare.
Dezvoltatorul nu trebuie să gestioneze solicitarea în cod pentru permisiunile normal — este suficient să le declare în manifest. Cu toate acestea, în Android 12+ la instalarea din Google Play, utilizatorul vede fila „Permisiuni” cu listarea tuturor permisiunilor normal, ceea ce sporește transparența. Conform Statista (2024), peste 90% din aplicațiile din Google Play folosesc INTERNET ca cea mai comună permisiune normal.
Permisiunile dangerous acoperă accesul la date și funcții care pot încălca confidențialitatea: cameră, microfon, geolocație, contacte, SMS, telefon, calendar, senzori corporali. Aceste permisiuni necesită un mecanism în două etape: declarare în manifest + solicitare în timpul execuției prin ActivityCompat.requestPermissions().
Utilizatorul poate refuza acordarea permisiunii dangerous, iar aplicația trebuie să gestioneze corect acest scenariu. În Android 11+, dacă utilizatorul a refuzat de două ori, solicitările ulterioare nu afișează dialogul de sistem — sistemul returnează automat DENIED. În acest caz, trebuie să direcționați utilizatorul către setări.
Nivelul signature — permisiunea este acordată automat dacă aplicația este semnată cu același certificat ca sistemul sau o altă aplicație care a definit permisiunea. Folosit pentru aplicații de sistem și corporative. Exemplu: BIND_ACCESSIBILITY_SERVICE — disponibil doar aplicațiilor de sistem.
Nivelul special (SYSTEM_ALERT_WINDOW, WRITE_SETTINGS, REQUEST_INSTALL_PACKAGES, MANAGE_EXTERNAL_STORAGE) — necesită o acțiune separată a utilizatorului prin setările sistemului. Aplicația poate deschide pagina de setări cu Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION). Google Play limitează utilizarea permisiunilor special și necesită justificare în formular la publicare.
Începând cu Android 6.0, toate permisiunile dangerous necesită solicitare în timpul execuției. Să analizăm ciclul complet de lucru cu runtime permissions în Kotlin.
Înainte de a apela API-ul care necesită o permisiune dangerous, verificați întotdeauna starea curentă prin ContextCompat.checkSelfPermission(). Dacă starea este PERMISSION_GRANTED — puteți apela API-ul. Dacă este PERMISSION_DENIED — trebuie să solicitați permisiunea prin ActivityResultContract RequestPermission (AndroidX) sau prin requestPermissions() învechit.
Se recomandă utilizarea ActivityResultContracts.RequestMultiplePermissions pentru solicitarea mai multor permisiuni simultan. Google recomandă gruparea permisiunilor conexe (de exemplu, cameră + microfon pentru înregistrare video) într-un singur dialog, astfel încât utilizatorul să vadă contextul complet al solicitării.
import android.Manifest
import android.content.pm.PackageManager
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
class CameraActivity : AppCompatActivity() {
private val requestPermissionLauncher =
registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted: Boolean ->
if (isGranted) {
openCamera()
} else {
explainWhyPermissionNeeded()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
checkCameraPermission()
}
private fun checkCameraPermission() {
when {
ContextCompat.checkSelfPermission(this,
Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED -> {
openCamera()
}
shouldShowRequestPermissionRationale(
Manifest.permission.CAMERA
) -> {
showRationale()
}
else -> {
requestPermissionLauncher.launch(
Manifest.permission.CAMERA
)
}
}
}
}
Dacă utilizatorul a refuzat permisiunea de două ori, Android trece solicitarea în starea „Never ask again”. În acest caz, shouldShowRequestPermissionRationale() returnează false, iar dialogul de sistem nu va fi afișat. Aplicația trebuie să direcționeze utilizatorul către setările de sistem prin Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).
Important: nu afișați dialogul cu propunerea de a deschide setările imediat după primul refuz — acesta este perceput ca un comportament agresiv. Utilizați shouldShowRequestPermissionRationale() pentru a determina dacă trebuie afișată o explicație. Material Design Guidelines recomandă afișarea unui ecran cu explicația valorii accesului, nu doar un buton „Deschide setări”.
private fun openAppSettings() {
Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", packageName, null)
).also { intent ->
startActivity(intent)
}
}
private fun showPermissionSettings() {
AlertDialog.Builder(this)
.setTitle("Acces la cameră")
.setMessage("Permiteți accesul la cameră în Setări, "
+ "pentru a face poze de profil")
.setPositiveButton("Deschide setări") { _, _ ->
openAppSettings()
}
.setNegativeButton("Anulare", null)
.show()
}
Fișierul AndroidManifest.xml conține elementul <uses-permission> pentru fiecare permisiune pe care o folosește aplicația. Permisiunile sunt declarate la nivelul <manifest> înaintea elementului <application>.
Fiecare permisiune este declarată printr-un element separat <uses-permission> cu atributul android:name care indică numele complet al permisiunii. Pentru permisiunile care au apărut în anumite versiuni Android, utilizați atributul maxSdkVersion pentru a limita declararea doar la versiunile necesare — aceasta îmbunătățește compatibilitatea.
De exemplu, permisiunea WRITE_EXTERNAL_STORAGE nu este necesară pe Android 10+ (Scoped Storage), deci specificați maxSdkVersion=„28” (Android 9). Aceasta previne întrebările inutile din partea utilizatorilor pe versiunile noi. Android Studio avertizează despre maxSdkVersion recomandate prin Lint.
<!-- AndroidManifest.xml -->
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Normal permissions (install-time) -->
<uses-permission
android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Dangerous permissions (runtime) -->
<uses-permission
android:name="android.permission.CAMERA" />
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- Legacy storage permission limited to API 28 and below -->
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<application>
<!-- ... -->
</application>
</manifest>
Elementul <uses-feature> specifică că aplicația necesită un anumit hardware (cameră, GPS, NFC). Atributul android:required=„false” permite instalarea aplicației pe dispozitive fără acest hardware — verificarea disponibilității se face în cod. Dacă required=„true”, Google Play filtrează aplicația și aceasta devine indisponibilă pentru dispozitivele nepotrivite.
Se recomandă ca pentru toate funcțiile hardware să specificați required=„false” și să verificați disponibilitatea programatic prin PackageManager.hasSystemFeature(). Aceasta extinde audiența aplicației dvs. Singura excepție este atunci când funcția este critică pentru funcționarea aplicației (o aplicație de comandat taxi fără GPS nu are sens).
Lucrul corect cu permisiunile este un aspect cheie al calității aplicației Android. Să analizăm recomandările principale și greșelile tipice.
Solicitați doar permisiunile care sunt cu adevărat necesare pentru funcționarea aplicației. Fiecare permisiune suplimentară reduce conversia instalărilor și crește numărul de refuzuri. Google Play Console arată câți utilizatori au renunțat la instalare din cauza setului de permisiuni. Conform AppBrain (2024), aplicațiile cu 10+ permisiuni dangerous au cu 35% mai puține instalări.
Revizuiți periodic lista permisiunilor. Ștergeți-le pe cele neutilizate, în special la tranziția către versiuni noi Android unde unele permisiuni au devenit opționale. De exemplu, odată cu apariția selectorului foto (ActivityResultContracts.PickVisualMedia) în Android 13+, accesul la biblioteca media poate fi obținut fără permisiunea dangerous READ_MEDIA_IMAGES.
Înainte de a solicita o permisiune dangerous, afișați utilizatorului un ecran cu explicația de ce este necesară această permisiune și ce valoare oferă. Material Design recomandă utilizarea unui bottom sheet sau a unui dialog cu pictogramă, text scurt și butonul „Continuă”. Rationale crește acordul cu 20–30% comparativ cu solicitarea directă.
Verificați shouldShowRequestPermissionRationale() înainte de a apela launch(). Dacă este true — afișați rationale. Dacă este false — fie permisiunea a fost deja acordată, fie utilizatorul a refuzat definitiv (never ask again). În ultimul caz, afișați butonul „Deschide setări”, nu repetați solicitarea.
Testați toate scenariile posibile: acordarea permisiunii, refuzul, refuzul definitiv, retragerea permisiunii în setări, resetarea permisiunilor (Android 11+ auto-reset). Fiecare scenariu trebuie gestionat fără crash și fără pierdere de date. Android Testing Guide recomandă utilizarea bibliotecii TestPermission pentru automatizarea testării.
Acordați o atenție deosebită scenariului în care utilizatorul retrage permisiunea în timpul funcționării aplicației (aplicația minimizată → Setări → retragere). La revenirea în aplicație, verificați din nou toate permisiunile prin onResume(). Nu vă bazați pe stocarea în cache a stării permisiunilor — utilizatorul le poate modifica oricând.
Întrebări frecvente
Da, dacă SDK-ul include o permisiune în propriul manifest, aceasta se îmbină cu manifestul aplicației la compilare. Puteți dezactiva permisiunea inutilă a SDK-ului cu tools:node=„remove” în AndroidManifest.xml.
Apelarea API-ului fără permisiune va cauza o SecurityException, ceea ce duce la crash-ul aplicației. Verificați întotdeauna starea permisiunii înainte de a utiliza API-ul corespunzător și gestionați refuzul corect.
În setările dispozitivului: Setări → Aplicații → [aplicația dvs.] → Permisiuni. Pentru resetarea tuturor permisiunilor, utilizați comanda adb: adb shell pm reset-permissions.
Da, cu ajutorul ActivityResultLauncher în Fragment sau Service. Cu toate acestea, dialogul de solicitare necesită întotdeauna contextul UI al Activity. Pentru Service, puteți afișa o Notification cu Intent care deschide un Activity cu solicitarea.
De exemplu, WRITE_EXTERNAL_STORAGE nu este necesar pe Android 10+ (Scoped Storage). Specificând android:maxSdkVersion=„28”, excludeți declararea permisiunii pe versiunile noi, ceea ce îmbunătățește compatibilitatea și reduce lista permisiunilor solicitate.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.