现在的位置: 首页 > 综合 > 正文

android in practice_Using external storage(FileExplorer project)

2018年04月13日 ⁄ 综合 ⁄ 共 7191字 ⁄ 字号 评论关闭

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();
		   }
	   }
   }
}

create Util class FileUtil:

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

FileWriter G and FileReader,if we needed more control, such as specifying the file encoding, we could’ve used the lower-level FileInputStream and or FileOutputStream classes.

抱歉!评论已关闭.