2014-05-07 25 views
16

Abbiamo appena caduto fallo delle nuove autorizzazioni che si applicano alla scrittura di file su schede SD (di archiviazione esterna) su Android 4.4 (EACCES Autorizzazione negata)Android KitKat 4.4 cartella su scheda SD

Prima di KitKat abbiamo fissato i nostri cartella scrivibile in questo modo:

mfolder = Environment.getExternalStorageDirectory().getPath() + "/appfiles"; 

Tuttavia dopo ore di ricerca sono giunto alla conclusione, a torto oa ragione, che il 4.4 dispositivi per consentire la scrittura di file di questo deve essere cambiato in:

mfolder = Environment.getExternalStorageDirectory().getPath() + "/Android/data/com.xyz.abc/appfiles"; 

Quindi mfolder sarebbe qualcosa di simile: /mnt/sdcard/Android/data/com.xyz.abc/appfiles

E 'corretto, creiamo una cartella come quella sopra sulla sdcard per abilitare i dispositivi 4.4 scrivere file?

mfolder è una stringa che viene salvata in preferenze condivise.

Quindi abbiamo questo codice che viene eseguito una volta se API> = 19 che modifica la stringa mfolder e quindi copia tutti i file dalla vecchia cartella nella nuova cartella 'kitkat'.

if (android.os.Build.VERSION.SDK_INT>=19){ 
     if (!mfolder.contains("/Android/data/com.xyz.abc/appfiles")){ 
      if (prefs.getBoolean("kitkatcheck", false)==false){ 

       //update mfolder from 
         // /mnt/sdcard/appfiles 
         // to 
         // /mnt/sdcard/Android/data/com.xyz.abc/appfiles 
       String prekitkatfolder = mfolder; 
       String kitkatfolder = mfolder.replace("/appfiles", "/Android/data/com.xyz.abc/appfiles"); 
       mfolder = kitkatfolder; 
       try { 
        File sd = new File(mfolder); 
        if(!sd.exists() || !sd.isDirectory()) { 
         sd.mkdirs(); 
        } 
       } catch (Exception e) { 
        Toast.makeText(getBaseContext(), "Error creating Kitkat folder!\n" + e.toString(), Toast.LENGTH_LONG).show(); 
        return; 
       } 
       prefEditor.putString("patternfolder", mfolder); 
       prefEditor.putBoolean("kitkatcheck", true); 
       prefEditor.commit(); 

       //copy files and folder from old appfiles folder to new. 
       AllFiles.clear(); 
       listFilesAndFilesSubDirectories(prekitkatfolder); 
       if (AllFiles.size()>0){ 
        for (File child : AllFiles) { 
         try { 

          File dest = new File(child.toString().replace(prekitkatfolder, kitkatfolder)); 


          try { 
           String filePath = dest.getPath().substring(0, dest.getPath().lastIndexOf(File.separator)); 
           File subfolder = new File(filePath); 
           if(!subfolder.exists() || !subfolder.isDirectory()) { 
            subfolder.mkdirs(); 
           } 
          } catch (Exception ex) { 
          } 

          copyFile(child, dest); 

         } catch (Throwable t) { 

         } 
        } 

       } 


      } 

     } 

Ho poi informare l'utente che i loro file sono stati copiati nella nuova cartella e che a causa delle nuove autorizzazioni avrebbero dovuto eliminare manualmente la vecchia cartella prekitkatfolder. Immagino che saranno in grado di farlo solo se hanno un gestore di file di magazzino o se hanno smontato la scheda SD e lo mettono in un PC, a causa delle nuove autorizzazioni 4.4?

Inoltre, per noi sembra che queste autorizzazioni 4.4 non abbiano effetto su tutti i nostri utenti con Kitkat. Alcuni possono ancora scrivere nella cartella originale sulla loro memoria esterna e alcuni ottengono l'errore EACCES (Permission Denied). Qualcuno può far luce sul motivo per cui questo potrebbe essere, si potrebbe pensare che si applicherebbe a tutti i dispositivi 4.4 che utilizzano memoria esterna?

Dato che non abbiamo un dispositivo 4.4 reale, dobbiamo testare questo codice usando l'emulatore (API 19) ma non otteniamo l'errore EACCES Permission Denied. Quindi abbiamo rilasciato una versione beta con il codice sopra e ci è stato detto che i file copiati sono finiti nella memoria interna, come può essere?

Tutte le idee che stiamo facendo di sbagliato, grazie in anticipo

+0

Ciao Zorac, sono in una situazione simile su alcuni dispositivi funziona senza nome pacchetto nel percorso e su alcuni è necessario il lungo percorso aggiunto come /Android/data/com.xyz.abc/appfiles non è sicuro di cosa sta succedendo . Hai già trovato una soluzione ? – Ahmed

risposta

7

soluzione Aggiornato.

Imposta e crea anche la cartella nella posizione corretta per il KitKat.

mfolder = this.getExternalFilesDir("asubfoldername").getAbsolutePath(); 

Tuttavia, questo non è full-prova, se l'Android il dispositivo ha sia una posizione di archiviazione secondaria interna che esterna, quella sopra utilizzerà quella interna. Non proprio quello che vogliamo dato che richiediamo il percorso della sdcard rimovibile o, meglio ancora, il percorso verso la storagelocation secondaria con lo spazio disponibile più libero.

File[] possible_kitkat_mounts = getExternalFilesDirs(null); 

Nota "s" alla fine di getExternalFilesDirs. Questo crea una serie di posizioni di archiviazione esterne secondarie.

for (int x = 0; x < possible_kitkat_mounts.length; x++) { 
    //Log.d("test", "possible_kitkat_mounts " + possible_kitkat_mounts[x].toString()); 
    boolean isgood=false; 
    if (possible_kitkat_mounts[x] != null){ 
     isgood = test_mount(possible_kitkat_mounts[x].toString()); 
     if (isgood==true){ 
      arrMyMounts.add(newymounts(Device_get_device_info(possible_kitkat_mounts[x].toString()), possible_kitkat_mounts[x].toString())); 
     } 
    } 
}       

//sort arrMyMounts size so we can use largest 
Collections.sort(arrMyMounts, new Comparator<mymounts>(){ 
    public int compare(mymounts obj1, mymounts obj2){ 
     return (obj1.avaliablesize > obj2.avaliablesize) ? -1: (obj1.avaliablesize > obj2.avaliablesize) ? 1:0 ; 
    } 
}); 


if (arrMyMounts.size()>0){ 
    mfolder = arrMyMounts.get(0).name + "/asubfoldername"; 
    //Log.d("test", "selected kitkat mount " + kitkatfolder); 
}else{ 
    //do something else... 
} 

dalla matrice di possible_kitkat_mounts controlliamo via test_mount per vedere se siamo in grado di effettivamente scrivere nella posizione selezionata e in caso di successo si aggiunge che posizione per arrMyMounts.

Selezionando arrMyMounts, è possibile ottenere la posizione con lo spazio libero più disponibile.

Ehi, arrMyMounts.get (0) .name è una posizione di archiviazione secondaria di Kitkat con lo spazio più libero.

+0

Ho un'applicazione installata su Samsung Galaxy Note 10.1 che fornisce sia una memoria esterna incorporata che opzioni di scheda SD rimovibili. Ho provato a recuperare il percorso per la scheda SD rimovibile usando il metodo come sopra menzionato (cioè getExternalFilesDirs (null)) ma non esiste alcun metodo simile sul contesto. Tutto ciò di cui ho bisogno è di ottenere un percorso per la scheda SD in modo da poter creare una directory specifica per leggere/scrivere i file delle app. Ho anche provato a creare questa directory usando il percorso hardcoded ma non lo consente. Per favore, puoi aiutarmi a riguardo? Grazie –

+0

cos'è "questo"? che classe è questa? –

5

Google ha bloccato l'accesso in scrittura a dispositivi di memorizzazione esterni in Android 4.4. Fino a quando non lo cambiano, non c'è modo di ripristinarlo senza root.

Maggiori informazioni: https://groups.google.com/forum/#!msg/android-platform/14VUiIgwUjY/UsxMYwu02z0J

Potrebbe essere al lavoro su alcuni dispositivi con KitKat che hanno slot per schede miniSD. E 'confuso :(

+2

ma es explorer può creare una cartella nel mio dispositivo kitkat! non posso –

Problemi correlati