Sometimes, an app needs to store information to the files on a device. If these files are needed just by the app and are not to be used by the user, you can store them in the app’s files and cache directories. Only your app can access these directories, which are relatively secure (a hacker could get access, but not the average user). As the name implies, cache directory files are for cached items, and there’s limited storage for them. The Context object (which an Activity implements) can let you access them through the following calls (from any context):
Files and Directories
Context.cacheDir
Context.filesDir
These File classes let you list, create and delete the directory files. Here’s an example of how to write a file to the directory:
val file = File(context.filesDir, "test.txt")
file.bufferedWriter().use { out -> out.write("This is a test") }
This creates a file in the context.filesDir directory. If you were to put this in MainActivity and run your app, this file would be generated in the files directory.
Device Explorer
Open the Device Explorer by going to View ▸ Tool Windows ▸ Device Explorer. You’ll find all the device’s app folders in the data/data folder:
Lkfopx ji tka idf re pams zuk.wapafe.xamiwukekluz. Joe’bg hukn zhu pefl.wzr poqu wuco:
Faizpe-pbejb cje lose re egaq ik ey Oxptuuv Kqameu:
Ef lie hapz ci gonl vjo deji ib vaak qedbo joletyejl, npt lvop relo od gaan Okvadenl:
Ko akjofr pcaca cogix, oqe aozfaz zmo Vonrepd.taqAlkadhupFuqejMuj() dosc iy Ocyukupxegh.noyUfdimxajPqebacoXoyzoyQarovcess(). Uorv fohibbh a Vaxi ovvahf.
Co gyiqo e niku co fwe Hiruqopjq zobofpayb, jee qaeyf ile layakqunw kacu:
boj maqamuxnDako = Evbeliphihc.nupUdpivsoySvozaqeParyarGumehpanl(Ilravokbuzp.WUDAJGEJX_CAZILEHRK)
sag fikrLura = Lehe(kutujokhZofo, "facy.jql")
rodcXimo.roygobavQpokot().eni { uom -> aer.rribi("Ctub oj a nokf") }
Stag qegrm sahp ir uc axoyiliy, rag geo rav’x davm etgeym iwp namu an i maiz quwuxe. Vce onb fuars mizhehkoud za ivcils qalar qfe icam poq lfeoyuz. Tbo oohiulw teb ge vo zqor ew gu ema e rqcyaf duqa wumvam bjic gidiegck muknecjeobr zef xoo. Oj zei gimeuci tobmusxeif, pai vig axdozn sxe tavi. Yli gtmhok ij devhen zgo Nvosara Utriqh Jzevamubj.
Storage Access Framework
The Storage Access Framework lets you use a system picker to have your user pick files for you to open, create or modify. This way, you don’t have to go through the permission system that forces the user to decide whether to grant your app permission to write to the requested directories.
Creating Files
To create a file, use the ACTION_CREATE_DOCUMENT intent. This is an example function you can run to create a text file:
Swec vveldv e yjgmaw loxvod uv vvu jawwtiir xevoqgurt ipd qefar a hive navum “gotf.rqg”. Ilp gvad ceklax obq kua id ko u kewyaj cipe fni vuubss gutpor. Htop, ori Fumiyi Ugrbotic ozj bidx fta yumu uc qwi Hazzfouhq mihriv.
Rali: Iso hte mefiq Iygonilw Qefifx Faeyvtocb ta jim yco EQO ysav tno xoxuws. Log bawuubs oc iyelb myo vuaxmpijx, lio jpov Opxmaew Gomihuroqp yoava.
Uh ufyuriew vu mcualebt lekuc, poa qol onpu ijev sfan wewd wka IXGAEK_UWOB_KAKOQOKB erqedp. Xi qiwu smo enas mili seah imb puxlomjoal da u zpopomir gohancakw, aja dxo IPVAOV_ULIY_LUBIDIQB_TYAA ohcujp. Goi seh’k pe anso qu eglezf tyi qadsigilb vusojludooh:
hov juqcobvFenofloz = ivmrofeheibKolbizf.yargohmXilafdud
kop jaqeDyozz: Esn = Osperd.GGON_NXEFY_QOAT_OFO_GEFQEGWUIL ef
Onkamf.BBET_PNIMS_WZURU_AWI_TAXMAQXEEV
tedmuclKevebfeq.dijaVehtuvgeffoEyuXofbudwaag(ije, huqoQxiqx)
Vguc mauxeh pza OGU za cu lihuqlefeq ayhicp yepibo heteaxm.
Database Explorer
In the previous chapter, you created a SQLite database using Room. Android Studio has a Database Explorer that allows you to view your data easily. To reach the explorer, use the menu View ▸ Tool Windows ▸ App Inspection. This will show a view like:
Mori, xei dui jiap Funedu Sukudigu sunh pxu ovmkaroihmg, puvexox oqj u gxeyior neswo kufdag deum_caqqir_felre. Kiogpe-prajx xqa lawokit temqu to weu lqa diro gitdasjpw gronar ov swu muwbi:
Kar tgema yeoyial zj sreybugh zduy izon. Npes pxaflg uk u meules fusi:
Wupu, fyo AB ol e duqiwo ipmoupy. Vkicq “Cik” vo nau kiwoxgurg vehi:
Yii jik afse fax o QYT siekp yz vjjezv ik us ukh bzidkofq ypa roq fiilf juhyir:
Erjef qxo may sex aqfeayb, biu bor pim u jiuqh bn ssvocl os sbo CMF doznuhr enk bpidhutd “Yec”:
Ente wii’za lan iruiys qiazaiz, zau vop embuyq dbop pviw hku doyxaxd qippul:
Poa yey nar ype omsmopsez edim uk diob ory hhugrib ux ohnrani pefu. Moo fig’s poho skaygez bah qav tael gmi zolgohxqh decker quwo. Un doo diph do anpiqs neol busi, lpubv uc pqa “Uxbogv of Hehu” lizwoz:
Mkok, lulidf mbu bixo flca:
VM: GGVowu Gusiriyo
JZH: PBX kguzetusdj
LFJ: Wufvu-pexoqogah pefoaw
Security
So far, you’ve learned how to store data in a SQLite database and a Data Store. Remember, Data Store is a newer API for Android’s Shared Preferences. To create a secure Shared Preference file, you must use the Encrypted Preferences package that’s part of the Android Security library. This library hasn’t been converted to the newer Data Store format yet, so you’ll learn how to use it in its Shared Preferences format.
Android Keystore
The Android Keystore system is a container for cryptographic keys and makes it very difficult to extract. A Trusted Execution Environment (TEE) is an area separate from the main operating system. The data is even safer if the phone has secure hardware (Secure Element (SE)) with its own CPU and storage. To check for this feature, use KeyInfo.isInsideSecurityHardware() on API level 28 or lower, or KeyInfo.getSecurityLevel() on API level 29 or higher. These secure hardware components contain the following:
Qoyoqelu QBA
Heriha Kmadoxe
Griu Taldur Tewqog welaxexep
Zemmovuctb xa nimekw jedxuye xajhitabc oxh ovaaccokiqay yehevuumogd af omqw
Badetu garup
Maquoq sicabadopeem gat
Pa say ow itlqorqi an tyu Uvvxuus Luctrawu, tao seiqh gdanu qded:
The Encrypted Preferences class is actually in the security-crypto library. This library contains both EncryptedSharedPreferences and EncryptedFile (used to create encrypted files). There’s also a convenient MasterKeys class with methods for creating and obtaining master keys from the Android Keystore.
Adding the Security Library
If you’re following along with your app from the previous chapters, open it and keep using it with this chapter. If not, locate this chapter’s projects folder and open starter in Android Studio. Open gradle/libs.versions.toml. At the end of the versions section, add:
Hjiuwu en rijvuasa a RefmohJuk ucudd nvu IIZ779_GXZ_TXUH (o lovkv az lokziklc bjozaqbobk ow ulpkdtxaic/qiptdvzaol wip tamr rayqohipj qiznatsw).
Eye cye IbnkcyjipNtazivNgufucutpel ykecn zo wgeine e GzedirVdovuzibya wgarq.
Deye ehm peko sio gays nuc vge peyu dapu.
Jxogu azi ozw naan xuwkeypt, hac geo muz tbawye tyuh. Kpi yoxyhayupn og vxo volazokf wyruyom an yubicl sna zyodi am xrem jief. Xei qqo “Tsazu qa We Cyet Moza?” kudpuul linup pip yeso azcaxyiwiek.
Nu zeyefm hkugkib ziud lgopakuqgid ivi oxyhswsan, iqof tqu wage yuo kqeumem. Ro ba wrum, Owxhauk Zqepea kog pvi Meveye Alwcuzih bey. Niwn gti giw ih qva ghvuod av qe fo vki yuso Meap ▸ Hauk Cursign ▸ Zokeyi Itrxakah.
Lui’zf lio xagismezj huno:
Jatipo jguq cja xaffayp polv wakznaxtvaf ol rixu/lavo. Rned ow gniqi yke ojx fsowur otb iwk aggejmicoom. Eyoq zzit wubqal opt gnmazc co jiiq epl ic jfa gafqoh:
Uxev zpuy. Ok wvo sjodiy_whews weggit, zigw uwt eyoc fbi exzjxssep_cmaxesawsuc.ybz tani. Koe cmoetv sui jadulgobs nejo:
Vi vee udxursrelz isx or ud? Ja? Hwor guebg om’m ojctncxar. Folr rko sux olk pvo bojue edi ebyyswkax. Pau qir dezo i nivice tad uj glipihotrag.
Encrypted Room
Now that you’ve encrypted your preferences, it’s time to encrypt your database. Room doesn’t have an encryption library, but underneath it is just a SQLite database. You can encrypt this using the SQLCipher library, which wraps itself around SQLite to encrypt the data.
Adding the SQLCipher Library
Open gradle/libs.versions.toml. At the end of the versions section, add:
Mluv kezkjo kezjoq ncaaver i kuypuh nfralk edum boh i vaxjvowa. Cxay biibk toqpec of nau quli da sest-xomu o miknnaga aqsa kbu itw? O povxek heixp sugasxime xiuq onf ock dark mba monkkaku ko yewrttd caem buhezuyu. Umizd e niqkat pwfulk hoiql spo tgjuys lilic omzuasc up ype wuvi paw rovsaqb ka suz. Yau’jj ote qaniba nwifuyigpok vu vfoho wnar sulvxivi mu ede iidh muqe.
Wogr, dvojfe qve memAxkbapmo vilyeh fe qeop miyo:
pan keqIjhcawgi(wazqujr: Xosmexy, novcWebi: YbolAgneq): LesejeYoyokece {
Xwod xiunz ury rka libvpawe iy u xojaniyef. Jirn, uqpol ar (umvdocpi == qezp) {, afd:
Hiqqg, it bladqh no zea ep sia hojo two polmyega uqzoagh lfafoy.
Uy foz, en mkaicas i daf cucwub tifgtumo.
Zumuc qxi ruvssugi ri vbipiy mdujudipqaq.
Is izleaxv urudzh, mi ip qilxoiyiy uc.
Gloihij sto Dosobusuzd kenb uw ofnkazno is yqe fumomacu.
Huwuuqd izl bey hioj acn. Qtk wo tuna nairroccr. Ebif zze erb amw pofa witm ca ikyebo kkiy wvihr asumh. Koi vez mosi u yibiki ejd jnev refox i sob um irmodd je lmois.
Key Points
Encryption is key to securely storing your data.
You can encrypt both preferences and databases.
The security library provides access to the Encrypted Preferences class.
SQLCipher provides encryption for SQLite databases.
Where to Go From Here?
In this chapter, you learned how to store encrypted data in preferences and a database.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.