Obțineți calea către cardul SD pe Android +14
- 03.04.15 07:21 •
- vait •
- # 254813
- Habrahabr •
- 16 •
- 11897
- la fel ca Forbes, doar mai bine.
Dezvoltând aplicația pentru concurs, am intrat în problema stocării bazei de date. Problema a fost cum să definiți o cartelă de memorie externă. În general, căutarea în rețea nu a dat un răspuns exact. Prin urmare, combinând toate rezultatele, mi-am asamblat clasa. Dacă cineva este interesat, ne uităm sub tăiere.
Deci, să începem cu teoria.
terminologie
Înainte de KitKat 4.4, API nu oferă funcționalitate pentru obținerea de căi către memoria externă. Începând cu această versiune (API 19), funcția public abstract File [] primeșteExternalFilesDirs (String type), care returnează un șir de șiruri cu căi către memoria internă și externă. Dar cum rămâne cu cardul SD, care este introdus în slot? Calea către ea din nou nu putem obține.
Rezultatele căutării
Pentru a răspunde la această întrebare, m-am îndreptat spre Google cu toată cunoașterea. Dar nu mi-a dat un răspuns clar. Acesta a fost analizat mai multe opțiuni pentru a defini utilizarea funcțiilor standard care conduc la memorie externă, dar nimic de-a face cu dispozitivele de stocare amovibile, acestea nu trebuie să montați regulile de unități de procesare (Android ruleaza, de asemenea, pe kernel-ul Linux). În ultimele cazuri, au fost utilizate căile "prin cablu" către dosarul cu dispozitivele montate (în diferite versiuni acest director este diferit). Nu uitați că de la versiune la versiune, regulile de montare se modifică.
În cele din urmă, am decis să combin toate cunoștințele dobândite și am scris clasa mea, care ne poate reveni la dispozitive externe și detașabile.
Cod Descriere
Clasa MountDevice a fost creată. care conține calea către dispozitiv, tipul de dispozitiv și un hash.
Tipurile de dispozitive sunt alocate două (nu am atins memoria internă, deoarece poate fi accesată prin API-ul sistemului).
Și a fost creată clasa StorageHelper. care caută carduri de memorie disponibile.
În clasa StorageHelper, există două modalități de căutare - prin mediul de sistem (Mediu) și utilizând utilitarul de instalare Linux. ci mai degrabă rezultatul implementării sale.
Metoda 1 - Mediu
Când lucrez cu mediul, folosesc funcția standard getExternalStorageDirectory () pentru a obține informații despre memoria externă. Pentru a obține informații despre memoria care se șterge, folosesc variabila de mediu "SECONDARY_STORAGE".
Memoria externă este întotdeauna una și, de obicei, întotdeauna este, așa că am verificat-o pentru citire, calculați hash-ul și amintiți-vă. Poate fi o mulțime de memorie care trebuie șters, deci trebuie să împărțiți șirul rezultat într-un separator și să verificați fiecare valoare.
Soluția este preluată din stackoverflow. Răspunsul este undeva jos.
Al doilea mod este montarea
Deoarece nu puteam să-mi spună că calea către memorie a fost îndepărtată pentru o lungă perioadă de timp, am decis să mă uit la dispozitivele montate. Sistemul are fișiere de configurare care descriu regulile de montare a dispozitivelor externe. Totul ar fi bine, dar pe versiunea Android 4. * Nu există acces ușor la acest fișier pentru muritor, așa că nu voi lua în considerare această metodă.
Să ne întoarcem la utilitarul de montare. Când se execută fără parametri, comanda returnează o listă de sisteme de fișiere montate. Dispozitivele amovibile au de obicei formatul sistemului de fișiere FAT, apoi vom selecta liniile în care există o caracteristică a "grasimii". Memoria externă va fi caracterizată de parametrul "siguranțe".
Notă: atunci când utilizați această metodă, nu este întotdeauna corectă (cel mai probabil nu am luat în considerare ceva) sunt determinate tipurile de dispozitive care sunt scanate. Am observat o diferență pe diferite versiuni de Android. Prin urmare, această metodă poate fi utilizată ca una suplimentară.
Soluția este preluată din stackoverflow. Răspunsurile sunt cam similare.
Despre duplicare
Mulți oameni au observat în directorul de instalare a dispozitivului următoarea imagine:
Și, cel mai interesant, toate acestea sunt aceleași carduri de memorie externe. Această zdrobire începe cu versiunea Jelly Bean și se face pentru a sprijini modul multi-utilizator al sistemului. Mai multe detalii aici. Și astfel, pentru a nu primi unul și același card de memorie ca și alte dispozitive, este nevoie de o modalitate de determinare a identității. Dacă a existat acces la configurația mountului, atunci nu au existat întrebări. Dar nu există acces. Prin urmare, am văzut aici soluția cu calculul hash-ului pentru fiecare dispozitiv:
- creați StringBuilder
- scrieți-i dimensiunea totală a dispozitivului și dimensiunea spațiului dispozitivului utilizat
- ocolind conținutul dispozitivului rădăcină
- scrieți numele directorului
- scrieți numele și dimensiunea fișierului
- calculați hash
Funcția hash CalcHash
Exemplu de utilizare
concluzie
Discuții detaliate despre această problemă de înțelegere a memoriei în Android, câteva sfaturi pot fi citite aici.
Codul sursă al întregii clase nu este localizat în altă parte. Una dintre aceste zile voi încerca să pun pe gitHub.
Cine mai foloseste ce metode?
UPD1: codul sursă al clasei pe bitbucket
Acum, acest lucru nu este foarte relevant, dar în teorie, cardurile de memorie sunt mai mari decât memoria "externă" încorporată. Prin urmare, este mai bine să stocați o bază de date potențial mai mare pe o cartelă de memorie. Am început să caut o astfel de alternativă de la astfel de considerații.
În prezent am LG L65. El are 4 GB de memorie, dintre care numai 1,5 sunt disponibile pentru utilizator. Am pus aplicații, tonuri de apel etc. și rămâne doar 200 MB.
UPD. Viber, de exemplu, stochează totul în memoria externă. În consecință, locul este în continuă scădere.
Cred că VibER stochează numai fișiere media cu volum mare, nu toată corespondența. Este posibil ca un număr mare de fișiere relativ mari să fie actual, dar cu siguranță nu pentru o "bază potențial mare".
1) Cât de mare ar fi baza de date pentru getExternalStorageDirectory () să nu satisfacă complet? (Sper că nu stocați fișiere media în blobs)
2) Dacă baza de date este foarte mare, atunci stochează un număr mare de înregistrări. Nu cred că merită să strălucească aceste înregistrări tuturor utilizatorilor (chiar fără înrădăcinare).
Și eu nu înțeleg, dar cât de mulți oameni sunt strigând indignați de a juca descarcat resursele-l pe o unitate flash, și nu în Environment.getExternalStorageDirectory () - nu au fost încă făcut mii de unități într-un comentariu din acest motiv. Apropo, tot șamanismul descris mai sus nu mai salvează și vor exista dispozitive exotice în care nu poate fi determinată corect - de aceea ei au adăugat și posibilitatea de a intra pe calea cu mâinile.
Um ... Mi se pare sau mai exact pentru asta este fișierul de expansiune?
Locația specifică pentru fișierele de extensie este:
Nu pot să înțeleg nemulțumirea utilizatorilor dvs. Practică destul de normală.
obb nu va ajuta - pe acele dispozitive pe care getExternalStorageDirectory indică memoria internă dacă există o cartelă SD, obb se va deplasa, de asemenea, în memoria internă
De exemplu, pe mașina mea din directorul / mnt / există un folder "sdcard" - se referă la memoria externă. Cardurile de memorie din / mnt / nu sunt montate. Cred că nu este cel mai bun mod.
O optiune minunata si cea mai buna, dupa parerea mea, ar fi prin harta "vold.fstab". Dar din păcate, pe cele mai recente versiuni de androyd (de la 4.3), accesul la acest fișier fără root nu este obținut. Da, și se numește diferit și se află în altă parte:
Pentru Android 4.2.2 și versiuni anterioare, fișierul de configurare vold.fstab specific dispozitivului definește mapările de la dispozitivele sysfs la punctele de montare a sistemelor de fișiere
Pentru versiunile Android 4.3 și ulterioare, diferitele fișiere fstab utilizate de init, vold și recuperare au fost unificate în / fstab.
Sursă: source.android.com