una samsung para guardar fotos espaƱol crear como celular carpetas carpeta card archivos app android android-sdcard android-4.4-kitkat

samsung - crear carpeta en android



Carpeta Android KitKat 4.4 en tarjeta sd (2)

Acabamos de perder los nuevos permisos que se aplican a la escritura de archivos en tarjetas SD (almacenamiento externo) en Android 4.4 (Permiso denegado EACCES)

Antes de KitKat, configuramos nuestra carpeta de escritura como esta:

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

Sin embargo, después de horas de búsqueda, he llegado a la conclusión, con razón o sin ella, que en los dispositivos 4.4 para permitir la escritura de archivos, esto debe cambiarse a:

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

Así que mfolder sería algo como: /mnt/sdcard/Android/data/com.xyz.abc/appfiles

¿Es correcto? ¿Creamos una carpeta como la de arriba en la sdcard para permitir que 4.4 dispositivos escriban archivos?

mfolder es una cadena que guardamos en preferencias compartidas.

Luego tenemos este código que se ejecuta una vez si API> = 19 cambia la cadena de la carpeta y luego copia todos los archivos de la carpeta antigua a la nueva carpeta ''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) { } } } } }

Luego notifico al usuario que sus archivos se han copiado en la nueva carpeta y que, debido a los nuevos permisos, tendrían que eliminar manualmente la carpeta anterior de la carpeta de prekitkat. ¿Supongo que solo podrán hacer esto si tienen un administrador de archivos de archivo o si desmontan la tarjeta SD y la colocan en una PC, debido a los nuevos 4.4 permisos?

Además, para nosotros, parece que estos permisos 4.4 no están afectando a todos nuestros usuarios con Kitkat. Algunos todavía pueden escribir en la ubicación de la carpeta original en su almacenamiento externo y otros obtienen el error EACCES (Permiso Denegado). ¿Alguien puede arrojar alguna luz sobre por qué podría ser esto, uno podría pensar que se aplicaría a todos los dispositivos 4.4 que utilizan almacenamiento externo?

Como no tenemos un dispositivo 4.4 real, tenemos que probar este código usando el emulador (API 19) pero no recibimos el error EACCES Permission Denied. Así que lanzamos una versión beta con el código anterior y se nos ha dicho que los archivos copiados terminaron en el almacenamiento interno, ¿cómo puede ser eso?

Cualquier idea de lo que estamos haciendo mal, gracias de antemano



Solución actualizada.

Esto establece y también crea la carpeta en el lugar correcto para KitKat.

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

Sin embargo, esto no es una prueba completa, si el dispositivo Android tiene ubicaciones de almacenamiento secundario interno y externo, el anterior usará el interno. No es realmente lo que queremos, ya que requerimos una ruta a una tarjeta SD extraíble o, mejor aún, la ruta a la ubicación de almacenamiento secundario con el espacio más libre disponible.

File[] possible_kitkat_mounts = getExternalFilesDirs(null);

Tenga en cuenta la "s" al final de getExternalFilesDirs. Esto crea una matriz de ubicaciones de almacenamiento externo secundario.

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... }

Desde la matriz de possible_kitkat_mounts, verificamos a través de test_mount para ver si realmente podemos escribir en la ubicación seleccionada y si tenemos éxito, agregamos esa ubicación a arrMyMounts.

Al ordenar arrMyMounts, podemos obtener la ubicación con el mayor espacio libre disponible.

Hey presto, arrMyMounts.get (0) .name es una ubicación de almacenamiento secundario de kitkat con el mayor espacio libre.