Estoy usando el siguiente código para descargar un archivo de mi servidor y luego escribirlo en el directorio raíz de la tarjeta SD, todo funciona bien:
package com.downloader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.os.Environment;
import android.util.Log;
public class Downloader {
public void DownloadFile(String fileURL, String fileName) {
try {
File root = Environment.getExternalStorageDirectory();
URL u = new URL(fileURL);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
FileOutputStream f = new FileOutputStream(new File(root, fileName));
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = in.read(buffer)) > 0) {
f.write(buffer, 0, len1);
}
f.close();
} catch (Exception e) {
Log.d("Downloader", e.getMessage());
}
}
}
Sin embargo, usar Environment.getExternalStorageDirectory();
significa que el archivo siempre se escribirá en la raíz /mnt/sdcard
. ¿Es posible especificar una carpeta determinada para escribir el archivo?
Por ejemplo: /mnt/sdcard/myapp/downloads
Respuestas:
File sdCard = Environment.getExternalStorageDirectory(); File dir = new File (sdCard.getAbsolutePath() + "/dir1/dir2"); dir.mkdirs(); File file = new File(dir, "filename"); FileOutputStream f = new FileOutputStream(file); ...
fuente
getExternalStorageDirectory()
quedó obsoleto en API 29.Agregar permiso al manifiesto de Android
Agregue este permiso WRITE_EXTERNAL_STORAGE a su manifiesto de aplicaciones.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="your.company.package" android:versionCode="1" android:versionName="0.1"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <!-- ... --> </application> <uses-sdk android:minSdkVersion="7" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> </manifest>
Verifique la disponibilidad de almacenamiento externo
Siempre debe verificar primero la disponibilidad. Un fragmento de la documentación oficial de Android sobre almacenamiento externo .
boolean mExternalStorageAvailable = false; boolean mExternalStorageWriteable = false; String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { // We can read and write the media mExternalStorageAvailable = mExternalStorageWriteable = true; } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { // We can only read the media mExternalStorageAvailable = true; mExternalStorageWriteable = false; } else { // Something else is wrong. It may be one of many other states, but all we need // to know is we can neither read nor write mExternalStorageAvailable = mExternalStorageWriteable = false; }
Utilice un redactor de archivos
Por último, pero no menos importante, olvídate de
FileOutputStream
y usa aFileWriter
en su lugar. Más información sobre esa clase forma el javadoc FileWriter . Es posible que desee agregar más control de errores aquí para informar al usuario.// get external storage file reference FileWriter writer = new FileWriter(getExternalStorageDirectory()); // Writes the content to the file writer.write("This\n is\n an\n example\n"); writer.flush(); writer.close();
fuente
FileOutputStream
(bueno, no cubre las alternativas). ¿Por qué es mejor usar elFileWriter
en su lugar? ¿Es más rápido / más confiable / algo más?FileWriter
tiene métodos convenientes para escribir cadenas directamente, que no están presentes en unFileOutputStream
. Si no está escribiendo archivos de texto,FileWriter
no es de mucha ayuda. De hecho, si está escribiendo un archivo de imagen , en realidad no se puede hacer con unFileWriter
Por supuesto, si realmente desea una buena API para texto, envuelva suFileOutputStream
enPrintStream
y tendrá los mismos métodos queSystem.out
.Encontré la respuesta aquí: http://mytechead.wordpress.com/2014/01/30/android-create-a-file-and-write-to-external-storage/
Dice,
/** * Method to check if user has permissions to write on external storage or not */ public static boolean canWriteOnExternalStorage() { // get the state of your external storage String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { // if storage is mounted return true Log.v("sTag", "Yes, can write to external storage."); return true; } return false; }
y luego usemos este código para escribir en el almacenamiento externo:
// get the path to sdcard File sdcard = Environment.getExternalStorageDirectory(); // to this path add a new directory path File dir = new File(sdcard.getAbsolutePath() + "/your-dir-name/"); // create this directory if not already created dir.mkdir(); // create the file in which we will write the contents File file = new File(dir, "My-File-Name.txt"); FileOutputStream os = outStream = new FileOutputStream(file); String data = "This is the content of my file"; os.write(data.getBytes()); os.close();
Y esto es todo. Si ahora visita su carpeta / sdcard / your-dir-name /, verá un archivo llamado - My-File-Name.txt con el contenido especificado en el código.
PD: - Necesita el siguiente permiso -
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
fuente
/sdcard/
no siempre es la sdcard.Para descargar un archivo para descargar o carpeta de música en la tarjeta SD
File downlodDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);// or DIRECTORY_PICTURES
Y no olvide agregar estos permisos en el manifiesto
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
fuente