You want to store data on the external storage. Also, you want to be able to easily determine when the external storage is and isn’t available.
create layout file external_storage.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/external_storage_label" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="10px" android:text="Enter some text to write on the external storage, then read back:" /> <EditText android:id="@+id/external_storage_input" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="10px" /> <Button android:id="@+id/external_storage_write_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Write" /> <Button android:id="@+id/external_storage_read_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Read" /> <TextView android:id="@+id/external_storage_output" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="10px" /> </LinearLayout>create activity class ExternalStorage
public class ExternalStorage extends Activity { // wrap some operations that are likely to be needed in more than one place in FileUtil private EditText input; private TextView output; private Button write; private Button read; @Override public void onCreate(final Bundle icicle) { super.onCreate(icicle); this.setContentView(R.layout.external_storage); this.input = (EditText) findViewById(R.id.external_storage_input); this.output = (TextView) findViewById(R.id.external_storage_output); this.write = (Button) findViewById(R.id.external_storage_write_button); this.write.setOnClickListener(new OnClickListener() { public void onClick(final View v) { write(); } }); this.read = (Button) findViewById(R.id.external_storage_read_button); this.read.setOnClickListener(new OnClickListener() { public void onClick(final View v) { read(); } }); } private void write() { if(FileUtil.isExternalStorageWritable()){ File dir=FileUtil.getExternalFilesDirAllApiLevels(this.getPackageName()); File file=new File(dir,"test.txt"); FileUtil.writeStringAsFile(input.getText().toString(), file); Toast.makeText(this, "File written", Toast.LENGTH_SHORT).show(); input.setText(""); output.setText(""); } else{ Toast.makeText(this, "External storage not writable", Toast.LENGTH_SHORT).show(); } } private void read() { if(FileUtil.isExternalStorageReadable()){ File dir=FileUtil.getExternalFilesDirAllApiLevels(this.getPackageName()); File file=new File(dir,"test.txt"); if(file.exists()&&file.canRead()){ output.setText(FileUtil.readFileAsString(file)); Toast.makeText(this, "File read", Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(this, "External storage not readable", Toast.LENGTH_SHORT).show(); } } } }
public final class FileUtil { // from the Android docs, these are the recommended paths private static final String EXT_STORAGE_PATH_PREFIX = "/Android/data/"; private static final String EXT_STORAGE_FILES_PATH_SUFFIX = "/files/"; private static final String EXT_STORAGE_CACHE_PATH_SUFFIX = "/cache/"; // Object for intrinsic lock use as a lock for synchronized blocks /** * these utility methods may be accessed by different threads and could possibly touch the same files, we’ll synchronize them to avoid concurrent modification problems. */ public static final Object[] DATA_LOCK = new Object[0]; private FileUtil() { } /** * Use Environment to check if external storage is writable. * * @return */ public static boolean isExternalStorageWritable() { /** * We could call Environment from our activities (and sometimes that makes sense), * but here we chose to put the logic in one place so as not to have to repeat it. */ return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED); } /** * Use environment to check if external storage is readable. */ public static boolean isExternalStorageReadable() { if (isExternalStorageWritable()) { return true; } return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED_READ_ONLY); } /** * Return the recommended external files directory, whether using API level 8 or lower. * (Uses getExternalStorageDirectory and then appends the recommended path.) * * @param packageName * @return */ public static File getExternalFilesDirAllApiLevels(final String packageName) { return FileUtil.getExternalDirAllApiLevels(packageName, EXT_STORAGE_FILES_PATH_SUFFIX); } /** * Return the recommended external cache directory, whether using API level 8 or lower. * (Uses getExternalStorageDirectory and then appends the recommended path.) * * @param packageName * @return */ public static File getExternalCacheDirAllApiLevels(final String packageName) { return FileUtil.getExternalDirAllApiLevels(packageName, EXT_STORAGE_CACHE_PATH_SUFFIX); } private static File getExternalDirAllApiLevels(final String packageName, final String suffixType) { File dir = new File(Environment.getExternalStorageDirectory() + EXT_STORAGE_PATH_PREFIX + packageName + suffixType); synchronized(FileUtil.DATA_LOCK){ try{ dir.mkdirs(); dir.createNewFile(); }catch (IOException e) { Log.e(Constants.LOG_TAG, "Error creating file", e); } } return dir; } /** * Copy file, return true on success, false on failure. * */ public static boolean copyFile(final File src, final File dst) { boolean result=false; FileChannel inChannel=null; FileChannel outChannel=null; synchronized(FileUtil.DATA_LOCK){ try{ inChannel=new FileInputStream(src).getChannel(); outChannel=new FileOutputStream(dst).getChannel(); inChannel.transferTo(0, inChannel.size(), outChannel); result=true; }catch (IOException e) { }finally{ if(inChannel!=null&&inChannel.isOpen()){ try{ inChannel.close(); }catch(IOException e){ } } if(outChannel!=null&&outChannel.isOpen()){ try{ outChannel.close(); }catch(IOException e){ } } } } return result; } /** * Replace entire File with contents of String, return true on success, false on failure. */ public static boolean writeStringAsFile(final String fileContents, final File file) { boolean result = false; try { synchronized (FileUtil.DATA_LOCK) { if (file != null) { file.createNewFile(); // ok if returns false, overwrite Writer out = new BufferedWriter(new FileWriter(file), 1024); out.write(fileContents); out.close(); result = true; } } } catch (IOException e) { Log.e(Constants.LOG_TAG, "Error writing string data to file " + e.getMessage(), e); } return result; } /** * Append String to end of File, return true on success, false on failure. */ public static boolean appendStringToFile(final String appendContents, final File file) { boolean result = false; try { synchronized (FileUtil.DATA_LOCK) { if ((file != null) && file.canWrite()) { file.createNewFile(); // ok if returns false, overwrite Writer out = new BufferedWriter(new FileWriter(file, true), 1024); out.write(appendContents); out.close(); result = true; } } } catch (IOException e) { Log.e(Constants.LOG_TAG, "Error appending string data to file " + e.getMessage(), e); } return result; } /** * Read file as String, return null if file is not present or not readable. */ public static String readFileAsString(final File file) { StringBuilder sb = null; try { synchronized (FileUtil.DATA_LOCK) { if ((file != null) && file.canRead()) { sb = new StringBuilder(); String line = null; BufferedReader in = new BufferedReader(new FileReader(file), 1024); while ((line = in.readLine()) != null) { sb.append(line + System.getProperty("line.separator")); } } } } catch (IOException e) { Log.e(Constants.LOG_TAG, "Error reading file " + e.getMessage(), e); } if (sb != null) { return sb.toString(); } return null; } }