AndroidJezik

## **Osnove aplikacija**

Android aplikacije se mogu pisati koristeći Kotlin, Java i C++ jezike. Android SDK alati kompajliraju vaš kod zajedno sa svim podacima i fajlovima resursa u APK ili Android App Bundle.

Android paket, koji je arhivski fajl sa sufiksom .apk, sadrži sadržaj Android aplikacije koji je neophodan tokom izvršavanja i to je fajl koju uređaji na Android-u koriste za instaliranje aplikacije.

Android App Bundle., koji je arhivski fajl sa .aab sufiksom, sadrži sadržaj projekta Android aplikacije, uključujući neke dodatne metapodatke koji nisu potrebni tokom izvršavanja. AAB je format za objavljivanje i ne može se instalirati na Android uređaje, već odlaže generisanje APK-a i potpisivanje na kasniju fazu. Kada distribuirate vašu aplikaciju preko Google Play-a, na primer, Google Play serveri generišu optimizovane APK-ove koji sadrže samo resurse i kod koji su potrebni za određeni uređaj koji zahteva instalaciju aplikacije.

Svaka Android aplikacija živi u sopstvenom sigurnosnom sandbox-u, zaštićenom sledećim Android bezbednosnim funkcijama:

Android operativni sistem je višekorisnički Linux sistem u kojem je svaka aplikacija različit korisnik. Podrazumevano, sistem svakoj aplikaciji dodeljuje jedinstveni Linux korisnički ID (ID koristi samo sistem i nije poznat aplikaciji). Sistem postavlja dozvole za sve fajlove u aplikaciji tako da samo korisnički ID koji je dodeljen toj aplikaciji može da im pristupi. Svaki proces ima svoju virtuelnu mašinu (VM), tako da kod aplikacije radi izolovano od drugih aplikacija. Podrazumevano, svaka aplikacija radi u sopstvenom Linux procesu. Android sistem pokreće proces kada bilo koja od komponenti aplikacije treba da se izvrši, a zatim isključuje proces kada više nije potreban ili kada sistem mora da povrati memoriju za druge aplikacije.

Android sistem primenjuje princip najmanje privilegija. To jest, svaka aplikacija, podrazumevano, ima pristup samo komponentama koje su joj potrebne za obavljanje svog posla i ništa više. Ovo stvara veoma bezbedno okruženje u kojem aplikacija ne može da pristupi delovima sistema za koje joj nije data dozvola. Međutim, postoje načini da aplikacija deli podatke sa drugim aplikacijama i da aplikacija pristupi sistemskim uslugama:

* Moguće je organizovati da dve aplikacije dele isti Linuk korisnički ID, u kom slučaju mogu da pristupaju datotekama jedne druge. Da bi sačuvale sistemske resurse, aplikacije sa istim korisničkim ID-om takođe mogu da organizuju rad u istom Linuk procesu i dele isti VM. Aplikacije takođe moraju biti potpisane istim sertifikatom.

* Aplikacija može da zatraži dozvolu za pristup podacima uređaja kao što su lokacija uređaja, kamera i Bluetooth veza. Korisnik mora eksplicitno da odobri ove dozvole. Za više informacija pogledajte Rad sa sistemskim dozvolama.

Ostatak ovog dokumenta uvodi sledeće koncepte:

* Osnovne komponente okvira koje definišu vašu aplikaciju.

* Datoteka manifesta u kojoj deklarišete komponente i potrebne funkcije uređaja za svoju aplikaciju.

* Resursi koji su odvojeni od koda aplikacije i koji omogućavaju vašoj aplikaciji da elegantno optimizuje svoje ponašanje za različite konfiguracije uređaja.

## Komponente aplikacija(App components)

Komponente aplikacije su osnovni gradivni blokovi Android aplikacije. Svaka komponenta je ulazna tačka preko koje sistem ili korisnik može da uđe u vašu aplikaciju. Neke komponente zavise od drugih.

Postoje četiri različite vrste komponenti aplikacije:

* Aktivnosti(Activities)

* Usluge(Services)

* Prijemnici za emitovanje(Broadcast receivers)

* Dobavljači sadržaja(Content providers)

Svaki tip služi različitoj svrsi i ima poseban životni ciklus koji definiše kako se komponenta stvara i uništava. Sledeći odeljci opisuju četiri tipa komponenti aplikacije.

### **Prijemnici prenosa**

***Prijemnik** prenosa* je komponenta koja omogućava da sistem isporuči događaje aplikaciji izvan korisnikovog uobičajenog toka, omogućavajući aplikaciji da odgovori na najave prenosa širom sistema. Pošto su prijemnici prenosa još jedan dobro definisan unos u aplikaciju, sistem može da isporučuje prenose čak i aplikacijama koje trenutno nisu pokrenute. Tako, na primer, aplikacija može da zakaže alarm da objavi obaveštenje kako bi obavestila korisnika o predstojećem događaju... i isporukom tog alarma BroadcastReceiver-u aplikacije, nema potrebe da aplikacija ostane pokrenuta dok se alarm ne oglasi. Mnogi prenosi potiču iz sistema — na primer, prenos koji najavljuje da se ekran isključio, da je baterija prazna ili da je slika snimljena. Aplikacije takođe mogu da pokrenu prenose — na primer, da obaveste druge aplikacije da su neki podaci preuzeti na uređaj i da su im dostupni za korišćenje. Iako prijemnici prenosa ne prikazuju korisnički interfejs, oni mogu **kreirati obaveštenje na statusnoj traci** da bi upozorili korisnika kada se dogodi emitovani događaj. Češće je, da je prijemnik prenosa samo prolaz ka drugim komponentama i namenjen je za obavljanje veoma male količine posla. Na primer, može da zakaže **JobService** da izvrši neki posao na osnovu događaja sa **JobScheduler**-om. Prijemnik prenosa je implementiran kao podklasa **BroadcastReceiver**-a i svako emitovanje se isporučuje kao Intent objekat. Za više informacija pogledajte klasu **BroadcastReceiver**.

##### Aktivnosti

Aktivnost je ulazna tačka za interakciju sa korisnikom. Predstavlja jedan ekran sa korisničkim interfejsom. Na primer, aplikacija za e-poštu može imati jednu aktivnost koja prikazuje listu novih imejlova, drugu aktivnost za sastavljanje e-pošte i drugu aktivnost za čitanje e-pošte. Iako aktivnosti funkcionišu zajedno kako bi formirale kohezivno korisničko iskustvo u aplikaciji za e-poštu, svaka je nezavisna od drugih. Kao takva, druga aplikacija može pokrenuti bilo koju od ovih aktivnosti ako aplikacija za e-poštu to dozvoljava. Na primer, aplikacija za kameru može da pokrene aktivnost u aplikaciji za e-poštu koja sastavlja novu poštu kako bi omogućila korisniku da deli sliku. Aktivnost olakšava sledeće ključne interakcije između sistema i aplikacije:

* Praćenje onoga do čega je korisniku trenutno stalo (šta je na ekranu) kako bi se osiguralo da sistem nastavlja da pokreće proces koji hostuje aktivnost.

* Znajući da prethodno korišćeni procesi sadrže stvari na koje se korisnik može vratiti (zaustavljene aktivnosti), i samim tim daju veći prioritet zadržavanju tih procesa.

* Pomaganje aplikaciji da reši proces ukidanja kako bi korisnik mogao da se vrati aktivnostima sa vraćenim prethodnim stanjem.

* Obezbeđivanje načina da aplikacije implementiraju međusobne tokove korisnika i da sistem koordinira ove tokove. (Najklasičniji primer je deljenje.)

Vi implementirate aktivnost kao podklasu klase Aktivnost. Za više informacija o klasi Aktivnosti pogledajte vodič za programere Aktivnosti.

##### Servisi

Servis je ulazna tačka opšte namene za održavanje aplikacije u pozadini iz raznih razloga. To je komponenta koja radi u pozadini za obavljanje dugotrajnih operacija ili za obavljanje poslova za udaljene procese. Servis ne pruža korisnički interfejs. Na primer, servis može da pušta muziku u pozadini dok je korisnik u drugoj aplikaciji ili može da preuzima podatke preko mreže bez blokiranja interakcije korisnika sa aktivnošću. Druga komponenta, kao što je aktivnost, može pokrenuti servis i pustiti je da radi ili da se poveže sa njom kako bi bila u interakciji sa njom.

Postoje dve vrste servisa koje govore sistemu kako da upravlja aplikacijom: startovan servis i povezan servis.

##### Startovan servis

Startovani servisi govore sistemu da nastavi da radi dok se njihov rad ne završi. Ovo može biti sinhronizacija nekih podataka u pozadini ili puštanje muzike čak i nakon što korisnik napusti aplikaciju. Sinhronizacija podataka u pozadini ili puštanje muzike takođe predstavljaju dva različita tipa startovanih servisa koje menjaju način na koji sistem upravlja njima:

* Reprodukcija muzike je nešto čega je korisnik direktno svestan, tako da aplikacija to govori sistemu govoreći da želi da bude u prvom planu sa obaveštenjem da obavesti korisnika o tome; u ovom slučaju sistem zna da treba jako da se potrudi da održi proces te usluge u toku, jer će korisnik biti nezadovoljan ako nestane.

* Redovna pozadinska usluga nije nešto čega je korisnik direktno svestan da radi, tako da sistem ima više slobode u upravljanju svojim procesom. Može dozvoliti da se on ubije (i zatim ponovo pokrene uslugu kasnije) ako mu je potrebna RAM za stvari koje su od neposrednijeg značaja za korisnika.

##### Povezan servis

Povezani servisi se pokreću jer je neka druga aplikacija (ili sistem) rekla da želi da koristi servis. Ovo je u osnovi servis koji pruža API drugom procesu. Sistem stoga zna da postoji zavisnost između ovih procesa, tako da ako je proces A vezan za uslugu u procesu B, on zna da treba da zadrži proces B (i njegov servis) da radi za A. Dalje, ako je proces A nešto korisnik brine, onda on takođe zna da tretira proces B kao nešto do čega je korisniku stalo.

Zbog svoje fleksibilnosti (u dobru i zlu), servisi su se pokazali kao zaista koristan gradivni blok za sve vrste koncepta sistema višeg nivoa. Žive pozadine, slušaoci obaveštenja, čuvari ekrana, metode unosa, servisi pristupačnosti i mnoge druge osnovne sistemske funkcije su izgrađene kao servisi koje aplikacije implementiraju i sistem se vezuje za vreme kada bi trebalo da budu pokrenute.

Servis je implementiran kao podklasa **Service**. Za više informacija o klasi **Service** pogledajte vodič **Services** za programere.

##### Prijemnici za emitovanje

Prijemnik emitovanja je komponenta koja omogućava sistemu da isporuči događaje u aplikaciju izvan redovnog toka korisnika, omogućavajući aplikaciji da odgovori na najave emitovanja širom sistema. Pošto su prijemnici emitovanja još jedan dobro definisan unos u aplikaciju, sistem može da isporučuje emitovanje čak i aplikacijama koje trenutno nisu pokrenute. Tako, na primer, aplikacija može da zakaže alarm da objavi obaveštenje kako bi obavestila korisnika o predstojećem događaju... i isporukom tog alarma BroadcastReceiver aplikacije, nema potrebe da aplikacija ostane pokrenuta dok ne alarm se gasi. Mnoga emitovanja potiču iz sistema—na primer, emisija koja najavljuje da se ekran isključio, da je baterija prazna ili da je slika snimljena. Aplikacije takođe mogu da pokrenu emitovanje—na primer, da obaveste druge aplikacije da su neki podaci preuzeti na uređaj i da su im dostupni za korišćenje.Iako prijemnici emitovanja ne prikazuju korisnički interfejs, oni mogu da kreiraju obaveštenja u statusnoj traci **(create a status bar notification)** da bi upozorili korisnika kada se dogodi emitovani događaj. Češće je, međutim, radiodifuzni prijemnik samo prolaz ka drugim komponentama i namenjen je za obavljanje veoma minimalne količine posla. Na primer, može da zakaže **JobService** da izvrši neki posao na osnovu događaja sa **JobScheduler**.

Prijemnik emitovanja je implementiran kao podklasa **BroadcastReceiver** i svako emitovanje se isporučuje kao **Intent** objekat. Za više informacija pogledajte klasu **BroadcastReceiver**.

#### Aktiviranje komponenti

Tri od četiri vrste komponenti – aktivnosti, usluge i prijamnici emitovanja – aktiviraju se asinhronom porukom koja se zove namera (**intent**). Namere povezuju pojedinačne komponente jednu sa drugom prilikom izvođenja aplikacije. Mogu se opisati kao glasnici koji zahtevaju radnju od drugih komponenti, bilo da komponenta pripada vašoj aplikaciji ili nekoj drugoj.

Namera se stvara s objektom **Intent**, koji definiše poruku za aktiviranje određene komponente (eksplicitna namera) ili određenog tipa komponente (implicitna namera).

Za aktivnosti i usluge, namera definiše radnju koju treba izvršiti (na primer, pregledati ili poslati nešto) i može specificirati URI podataka na koje treba delovati, između ostalog koje komponenta koja se pokreće možda treba da zna. Na primer, namera može da prenese zahtev za aktivnost za prikazivanje slike ili za otvaranje veb stranice. U nekim slučajevima možete započeti aktivnost da biste dobili rezultat, u kom slučaju aktivnost takođe vraća rezultat u **Intent**. Na primer, možete dati nameru da dozvolite korisniku da izabere lični kontakt i da vam ga vrati. Povratna namera uključuje URI koji ukazuje na izabrani kontakt.

Za prijemnike emitovanja, namera jednostavno definiše najavu *(announcement)* koja se emituje. Na primer, emitovanje koje pokazuje da je baterija uređaja prazna uključuje samo poznati niz radnji koji pokazuju da je baterija tog uređaja prazna.

Za razliku od aktivnosti, usluga i prijemnika emitovanja, provajderi sadržaja se ne aktiviraju prema namerama. Umesto toga, oni se aktiviraju kada su ciljani zahtevom **ContentResolver**-a. Razređivač sadržaja upravlja svim direktnim transakcijama sa dobavljačem sadržaja tako da komponenta koja obavlja transakcije sa dobavljačem ne mora i umesto toga poziva metode na objektu **ContentResolver**. Ovo ostavlja sloj apstrakcije između dobavljača sadržaja i komponente koja zahteva informacije (radi bezbednosti).

Postoje odvojene metode za aktivaciju svake vrste komponente: Možete pokrenuti aktivnost ili joj dodati nešto novo prosleđivanjem **Intent** u **startActivity()** ili **startActivityForResult()** (kada želite da aktivnost vrati rezultat). Kod Android 5.0 (API level 21) i novijih verzija, možete koristitiklasu **JobScheduler** za planiranje radnji. Za starije verzije Android-a, možete pokrenuti uslugu (ili dati nove instrukcije usluzi koja je u toku) prosleđivanjem u **startService ()**. Možete se povezati s uslugom prosleđivanjem **Intent** u **bindService()**. Možete pokrenuti emitovanje prosleđivanjem **Intent** metodama kao što su **sendBroadcast()**, **sendOrderedBroadcast()**, ili **sendStickyBroadcast()**. Možete izvesti upit do provajdera sadržaja pozivanjem **query()** na **ContentResolveru**.

#### Deklaracija zahteva aplikacije

Postoji mnogo uređaja koji se oslanjaju na Android, medjutim ne može svaki uređaj da priušti iste karakteristike i sposobnosti. Da bismo izbegli da naša aplikacija bude instalirana na uređaju koji ima manjak sposobnosti koje naša aplikacija zahteva, važno je da jasno definišemo tipove uređaja koji podržavaju našu aplikaciju, deklarisanjem zahteva uređaja i softvera u našem manifest fajlu. Većina ovih deklaracija su informativnog tipa i sistem ih ne čita, ali spoljašnji servisi, kao što je Google Play, čitaju ih da bi obezbedili obradu podataka za korisnike, kada pretražuju aplikacije na njihovom uređaju.

Na primer, ako naša aplikacija zahteva korišćenje kamere i koristi API-je predstavljene u Androidu 8.0, morate deklarisati ove zahteve.

Vrednosti za **minSdkVersion** i **targetSdkVersion** su zadate u fajlu **build.gradle**. To izgleda ovako:

Deklarišite korišćenje kamere u vašem manifest fajlu:

Sa zahtevima deklarisanim u primeru uredjaji koji *nemaju* kameru ili imaju android verziju *stariju* od 8.0 ne mogu instalirati vašu aplikaciju sa Google Play prodavnice. Međutim, moguće je deklarisati da vaša aplikacija *može ali ne mora* da koristi kameru, to uradite tako što **required** ("traženo") polje podesite na *false* i proverite da li uređaj ima kameru tokom trajanja aplikacije, ukoliko nema onemogućite sve funkcije koje koriste kameru.

Više informacija o podešavanju kompatibilnosti vaše aplikacije sa različitim uređajima se može naći ovde. (link ka dokumentu na engleskom)

### Manifest fajla

Pre nego li Androidov sistem može pokrenuti komponentu aplikacije, on mora znati da komponenta postoji. Ovo se proverava čitanjem fajla manifesta aplikacije, *AndroidManifest.xml*. Vaša aplikacija mora deklarisati sve svoje komponente u ovom fajlu, koja mora biti u *root* direktorijumu projekta aplikacije. Manifest čini niz stvari osim deklarisanja komponenti aplikacije. Neke od njih su:

* Identifikuje sve korisničke permisije koje aplikacija zahteva, kao što je pristup internetu ili pristup za čitanje kontakata korisnika.
* Deklariše minimalni nivo API-ja potreban za aplikaciju, na osnovu toga koje API-je aplikacija koristi.
* Deklariše hardverske i softverske karakteristike koje koristi ili zahteva aplikacija, kao što su kamera, bluetooth usluge ili *multitouch screen*.
* Deklariše biblioteke API-ja s kojima se aplikacija mora povezati (osim API Android frameworka), kao što je na primer Google Maps biblioteka.

#### Deklarisanje komponenti

Primarni zadatak manifesta je da obavesti sistem o komponentama aplikacije. Na primer, fajl manifesta može da deklariše aktivnost na sledeći način:

`<?xml version=``"1.0"` `encoding=``"utf-8"``?>`

`<manifest ... >`

`<application` `android:icon=`"@drawable/app\_icon.png" ... `>`

`<activity` `android:name=`"com.example.project.ExampleActivity"

`android:label=`"@string/example\_label" ... `>`

`</activity>`

...

`</application>`

`</manifest>`

U elementu <application> element android:icon, ukazuje na resurse za ikonicu koja identifikuje aplikaciju.

U elementu <activity>, androind:name atribut precizira potpuno kvalifikovano ime klase od Activity podklase i android:label atribut precizira string koji se koristi kao korisniku vidljiva labela za neku aktivnost.

Morate deklarisati sve komponente aplikacije koristeći sledeće elemente:

* <activity> - elementi za aktivnosti.
* <services> - elementi za servise.
* <receiver> - elementi za prijemnike.
* <provider> - elementi za provajdere sadržaja.

Aktivnosti, servisi i provajderi sadržaja koje uključite u svoj izvor, ali ih ne deklarišete u manifestu nisu vidljivi sistemu i stoga nikada se ne mogu pokrenuti. Kako god prijemnici mogu biti deklarisani u manifestu ili biti dinamički kreirani u kodu kao BroadcastReceiver objekti i registrovani u sistemu pozivom registerReceiver().

Za više o strukturi manifest datoteke vaše aplikacije pogledati The AndroidManifest.xml File dokumentaciju.

#### Deklaracija sposobnosti komponenata

Kao što je gore rešeno, u aktivirajućim komponentama, može se koristiti Intent da se pokrenu aktivnosti, servisi, i prijemnici. Intent se može eksplicitno koristiti imenujući ciljnu komponentu (koristeći ime klase čija je komponenta) u Intent. Takođe se može koristiti implicintno intent, što opisuje tip akcije koja će se desiti, i opcionalno podaci sa kojima bi se izvršila akcija. Implicitno korišćenje intent dozvoljava sistemu da nađe komponentu na uređaju koja će izvšiti akciju i započeti je. Ako se nalazi više komponenata koje će izvršiti akciju opisanih pomoću itent, korisnik će izabrati koju da koristi.

Oprez: Ako se intent koristi da se pokrene servis, osigurati da vaša aplikacija koristi intent eksplicitno. ukoliko itent koristimo implicitno kako bi pokrenuli servis, to može dovesti do problema u bezbednosti, jer ne možemo biti sigurni da li će se servis odazvati na itent, a korisnik ne može videti koji se servis pokreće. Sa Androidom 5.0 (API nivo 21), sistem daje izuzetak ukoliko se bindService() zove implicitno sa itent.

Sistem identifikuje koje komponente se mogu odazvati na itent upoređujući itent primljen od itent filtera osiguranim u manifest fajlu drugih aplikacija na uređaju.

Kada se aktivnost deklariše u manifestu aplikacije, može se opcionalno uključiti intent filter koji deklariše sposobnosti aktivnosti, pa to može odgovoriti sa intent ostalih aplikacija. Može se deklarisati intent filter za komponentu dodajući <intent-filter> element kao dete od deklarisanog elementa komponente.

Na primer, napravite aplikaciju za elekteronsku poštu sa aktivnošću za sastavljanje novih mejlova, možemo deklarisati intent filter koji će primiti "poslate" inters (u slučaju slanja novih mejlova), kao što je pokazano u pratećem primeru:

```
<manifest ... >
    ...
    <application ... >
        <activity android:name="com.example.project.ComposeEmailActivity">
            <intent-filter>
                <action android:name="android.intent.action.SEND" />
                <data android:type="\*/\*" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
</manifest>

```

Ukoliko druga aplikacija kreira intent sa ACTION\_SEND akcijom i prosledije do startActivity(), sistem će pokrenuti aktivnost stoga korisnik može da sastavi i pošalje mail.

Za više o kreiranju intent filtera, posetiti Intents and Intent Filters dokument.

### Resursi aplikacije

Android aplikacija se ne sastoji samo od koda – ona zahteva resurse koji su zasebni od izvornog koda, kao što su slike, audio fajlu i sve što se odnosi na vizuelni prikaz aplikacije. Na primer, možete da definišete animacije, menije, stilove, boje i raspored korisničkih interfejsa aktivnosti sa XML fajlovima. Korišćenje resursa aplikacije olakšava ažuriranje različitih karakteristika aplikacije bez menjanja koda. Obezbeđivanje skupova alternativnih resursa vam omogućava da optimizujete aplikaciju za različite konfiguracije (postavke) uređaja, kao što su različiti jezici i veličine ekrana.

Za svaki resurs koji uključite u svoj Android projekat, alati za pravljenje SDK-a definišu jedinstveni celobrojni ID, koji možete da koristite za referencu na resurs iz koda aplikacije ili iz drugih resursa definisanih u KSML-u. Na primer, ako vaša aplikacija sadrži fajl slike pod nazivom logo.png(sačuvanu u res/drawable/direktorijumu), SDK alati generišu ID resursa pod nazivom R.drawable.logo. Ovaj ID se preslikava u celi broj specifičan za aplikaciju, koji možete da koristite da biste referencirali sliku i ubacili je u svoj korisnički interfejs.

Jedan od najvažnijih aspekata obezbeđivanja resursa odvojenih od vašeg izvornog koda je mogućnost obezbeđivanja alternativnih resursa za različite konfiguracije uređaja. Na primer, definisanjem UI stringova u KSML-u, možete prevesti stringove na druge jezike i sačuvati te nizove u zasebnim fajlovima. Zatim Android primenjuje odgovarajuće jezičke stringove na vaš korisnički interfejs na osnovu kvalifikatora jezika koji dodajete imenu direktorijuma resursa (kao što je res/values-fr/ za francuske vrednosti stringova) i postavke jezika korisnika.

Android podržava mnogo različitih kvalifikatora za vaše alternativne resurse. Kvalifikator je kratak string koji uključujete u ime direktorijuma resursa da biste definisali konfiguraciju uređaja za koju bi ti resursi trebalo da se koriste. Na primer, trebalo bi da kreirate različite izglede za svoje aktivnosti, u zavisnosti od orijentacije i veličine ekrana uređaja. Kada je ekran uređaja u portretnoj orijentaciji (visok), možda ćete želeti da raspored sa dugmadima bude vertikalni, ali kada je ekran u pejzažnoj orijentaciji (široko), dugmad bi mogla da budu poravnata horizontalno. Da biste promenili izgled u zavisnosti od orijentacije, možete definisati dva različita izgleda i primeniti odgovarajući kvalifikator na ime direktorijuma svakog izgleda. Zatim sistem automatski primenjuje odgovarajući raspored u zavisnosti od trenutne orijentacije uređaja.

Za više informacija o različitim vrstama resursa koje možete da uključite u svoju aplikaciju i kako da kreirate alternativne resurse za različite konfiguracije uređaja, pročitajte Pružanje resursa. Da biste saznali više o najboljim praksama i dizajniranju robusnih aplikacija proizvodnog kvaliteta, pogledajte Vodič za arhitekturu aplikacija.

## Deklarisanje zahteva aplikacije

Postoji niz uređaja koje pokreće Android i ne pružaju svi iste funkcije i mogućnosti. Da biste sprečili da se vaša aplikacija instalira na uređajima kojima nedostaju funkcije koje su potrebne vašoj aplikaciji, važno je da jasno definišete profil za tipove uređaja koje vaša aplikacija podržava tako što ćete navesti zahteve za uređaje i softver u datoteci manifesta.

Na primer, ako vaša aplikacija zahteva kameru i koristi API-je uvedene u Android 8.0 (API nivo 26), morate da navedete ove zahteve.

Vrednosti za minSdkVersion i targetSdkVersion se postavljaju u datoteci build.gradle modula aplikacije:

```
android {
 ...
 defaultConfig {
 ...
 minSdkVersion 26
 targetSdkVersion 29
 }
}

```
Deklarisite funkciju kamere direktno u datoteci manifesta aplikacije:

```
<manifest ... >
    <uses-feature android:name="android.hardware.camera.any"
                  android:required="true" />
    ...
</manifest>
```
Sa deklaracijama prikazanim u ovim primerima, uređaji koji nemaju kameru ili imaju Android verziju nižu od 8.0 ne mogu da instaliraju vašu aplikaciju sa Google Play-a.Međutim, možete da izjavite da vaša aplikacija koristi kameru, ali da je ne zahteva. U tom slučaju, vaša aplikacija mora da podesi traženi atribut na netačno i da proveri tokom rada da li uređaj ima kameru i da onemogući sve funkcije kamere prema potrebi.