安卓外部存储,即将数据存储在sdcard中,当然存储的前提是手机或者模拟器先具有sdcard目录
然而上一句话还是有歧义的。
事实上所有的安卓设备都有外部存储和内部存储,这两个名称来源于安卓的早期设备,那个时候的设备内部存储确实是固定的,而外部存储确实是可以像U盘一样移动的。但是在后来的设备中,很多中高端机器都将自己的机身存储扩展到了8G以上,他们将存储在概念上分成了"内部internal" 和"外部external" 两部分,但其实都在手机内部。所以不管安卓手机是否有可移动的sdcard,他们总是有外部存储和内部存储。最关键的是,我们都是通过相同的api来访问可移动的sdcard或者手机自带的存储(外部存储)。
因为存储空间有限,内部存储只适用于存储数据量小的情况,当数据量比较大的时候(存放下载的电影音乐等),就需要将数据外部存储
-------------------------------------------------------------------------------------------------------------------------------
开发的时候在创建模拟器的时候
这里SD Card 要设置一个大小,否则模拟器没有sdcard目录
--------------------------------------------------------------------------------------------------------------------------
1 public static final String IMAGE_URL = Environment.getExternalStorageDirectory()+"/myfile/image"; 2 public static final int FORMAT_PNG = 1; 3 public static final int FOEMAT_JPEG = 2;
一些外部存储需要的方法:
1、判断扩展卡是否存在
1 public static boolean isMounted(){ 2 String state = Environment.getExternalStorageState(); 3 return state.equals(Environment.MEDIA_MOUNTED); 4 }
2、获取指定路径下的文件的文件名
1 public static String getFileName(String path) 2 { 3 return path.substring(path.lastIndexOf("/")+1); 4 }
3、获得当前sd卡中剩余存储空间的大小(单位兆)
1 public static int remainedSize(){ 2 //文件系统状态管理对象StatFs 3 StatFs fs = new StatFs(Environment.getExternalStorageDirectory().getAbsolutePath()); 4 int count = fs.getFreeBlocks(); //空闲的数据块个数 5 int size = fs.getBlockSize(); //返回每个数据块的大小 6 7 //计算剩余空间 8 long total_byte = count*size; //字节单位的大小 9 int total_m = (int) (total_byte*size/1024/1024);//兆单位的大小 10 11 return total_m; 12 }
4、将字节格式的图片数据源保存到sdcard中
1 public static void saveImage(String path, byte data[]) throws IOException 2 { 3 //判断扩展卡是否挂载 4 if(!isMounted()) 5 return ; 6 File fileDir = new File(IMAGE_URL); 7 //如果路径下该文件目录不存在,则新建目录 8 if(!fileDir.exists()) 9 { 10 fileDir.mkdirs(); 11 } 12 13 FileOutputStream fos = new FileOutputStream(new File(fileDir,getFileName(path))); 14 fos.write(data); 15 fos.close(); 16 17 }
5、将Bitmap格式的图片存放到sd卡
public static void saveImage(String path,Bitmap bitmap , int format) throws FileNotFoundException { //判断扩展卡是否挂载 if(!isMounted()) return; //判断目录是否存在 File fileDir = new File(IMAGE_URL); //如果路径下该文件目录不存在,则新建目录 if(!fileDir.exists()) { fileDir.mkdirs(); } //把图片数据写入到一个图片文件 FileOutputStream fos = new FileOutputStream(new File(fileDir,getFileName(path))); //压缩图片 第一个参数是压缩后的格式,第二个参数是压缩后的效果,值越大,效果越好,第三个参数是输入流 bitmap.compress(format==1?CompressFormat.PNG:CompressFormat.JPEG, 100, fos); }
6、从扩展卡中读取指定路径图片数据
1 public static Bitmap readImage(String path) 2 { 3 if(!isMounted()) 4 return null; 5 //获得文件名 6 String fileName = getFileName(path); 7 File file = new File(IMAGE_URL,fileName); 8 Bitmap bitmap = null; 9 if(file.exists()) 10 { 11 bitmap = BitmapFactory.decodeFile(file.getAbsolutePath()); 12 } 13 return bitmap; 14 }
7、清空指定路径下的所有文件夹和文件
1 public static void clear(){ 2 //判断扩展卡是否挂载 3 if(!isMounted()) 4 return ; 5 File fileDir = new File(IMAGE_URL); 6 //如果指定目录存在 7 if(fileDir.exists()) 8 { 9 //获取指定目录下的所有文件及目录 10 File fileArray[] = fileDir.listFiles(); 11 for(File f:fileArray) 12 { 13 f.delete(); 14 } 15 } 16 }
---------------------------------------------------------------------------------------------------------------------------
Demo:从指定路径下载一张图片保存到sdcard下并显示在ImageView视图中,如果本地已存在,则不再下载,直接显示图片在ImageView中
1 package com.xqx_outer; 2 3 import tools.DownImageAsycnTask; 4 import tools.FileUtil; 5 import android.app.Activity; 6 import android.graphics.Bitmap; 7 import android.os.Bundle; 8 import android.view.View; 9 import android.view.View.OnClickListener; 10 import android.widget.Button; 11 import android.widget.ImageView; 12 13 public class MainActivity extends Activity { 14 15 private ImageView imageView; 16 private Button btn_down; 17 public static final String path = "http://images2015.cnblogs.com/blog/493196/201509/493196-20150909121120762-2089133734.jpg"; 18 @Override 19 protected void onCreate(Bundle savedInstanceState) { 20 super.onCreate(savedInstanceState); 21 setContentView(R.layout.activity_main); 22 imageView = (ImageView) findViewById(R.id.id_image); 23 btn_down = (Button) findViewById(R.id.id_btn); 24 25 26 btn_down.setOnClickListener(new OnClickListener() { 27 28 @Override 29 public void onClick(View v) { 30 // TODO Auto-generated method stub 31 ImageDownLoad(); 32 } 33 }); 34 } 35 36 public void ImageDownLoad() 37 { 38 Bitmap bitmap = null; 39 //先从扩展卡中读取指定路径下的图片 40 bitmap = FileUtil.readImage(path); 41 //如果图片存在,则将图片放在图片视图中 42 if(bitmap!=null) 43 { 44 imageView.setImageBitmap(bitmap); 45 } 46 //如果不存在,开启异步任务下载图片 47 else 48 { 49 new DownImageAsycnTask(imageView).execute(path); 50 51 } 52 53 54 } 55 }
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" 6 android:gravity="center_horizontal" 7 > 8 9 <ImageView 10 android:layout_width="100dp" 11 android:layout_height="100dp" 12 android:id="@+id/id_image" 13 /> 14 <Button 15 android:layout_width="wrap_content" 16 android:layout_height="wrap_content" 17 android:id="@+id/id_btn" 18 android:text="下载" 19 /> 20 21 </LinearLayout>
1 package tools; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 6 import android.graphics.Bitmap; 7 import android.graphics.BitmapFactory; 8 import android.os.AsyncTask; 9 import android.widget.ImageView; 10 11 public class DownImageAsycnTask extends AsyncTask<String, Void, Bitmap>{ 12 private ImageView image ; 13 public DownImageAsycnTask(ImageView image){ 14 this.image = image; 15 } 16 @Override 17 protected Bitmap doInBackground(String... params) { 18 // TODO Auto-generated method stub 19 Bitmap bitmap = null; 20 //params[0] 为数据源路径 21 if(params[0]!=null) 22 { 23 try { 24 //获得指定路径上数据的字节数据 25 byte b[] = HttpUtil.getInput(params[0]); 26 //将字节数组数据转换为bitmap格式的图片 27 bitmap = BitmapFactory.decodeByteArray(b, 0, b.length); 28 //将图片缓冲到扩展卡中 29 FileUtil.saveImage(params[0], bitmap,2); 30 } catch (IOException e) { 31 // TODO Auto-generated catch block 32 e.printStackTrace(); 33 } 34 35 } 36 return bitmap; 37 } 38 @Override 39 protected void onPostExecute(Bitmap result) { 40 // TODO Auto-generated method stub 41 super.onPostExecute(result); 42 image.setImageBitmap(result); 43 } 44 }
1 package tools; 2 3 import java.io.File; 4 import java.io.FileNotFoundException; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7 import java.text.Normalizer.Form; 8 9 import android.graphics.Bitmap; 10 import android.graphics.Bitmap.CompressFormat; 11 import android.graphics.BitmapFactory; 12 import android.os.Environment; 13 import android.os.StatFs; 14 15 public class FileUtil { 16 //Environment.getExternalStorageDirectory()获取外部存储空间的目录 17 public static final String IMAGE_URL = Environment.getExternalStorageDirectory()+"/myfile/image"; 18 public static final int FORMAT_PNG = 1; 19 public static final int FOEMAT_JPEG = 2; 20 21 //判断扩展卡是否挂载 22 public static boolean isMounted(){ 23 String state = Environment.getExternalStorageState(); 24 return state.equals(Environment.MEDIA_MOUNTED); 25 } 26 27 //得到特定路径下的文件的文件名 28 public static String getFileName(String path) 29 { 30 return path.substring(path.lastIndexOf("/")+1); 31 } 32 33 //获取扩展卡的剩余内存空间 34 public static int remainedSize(){ 35 //文件系统状态管理对象StatFs 36 StatFs fs = new StatFs(Environment.getExternalStorageDirectory().getAbsolutePath()); 37 int count = fs.getFreeBlocks(); //空闲的数据块个数 38 int size = fs.getBlockSize(); //返回每个数据块的大小 39 40 //计算剩余空间 41 long total_byte = count*size; //字节单位的大小 42 int total_m = (int) (total_byte*size/1024/1024);//兆单位的大小 43 44 return total_m; 45 } 46 47 //将字节格式的图片保存到扩展卡 48 public static void saveImage(String path, byte data[]) throws IOException 49 { 50 //判断扩展卡是否挂载 51 if(!isMounted()) 52 return ; 53 File fileDir = new File(IMAGE_URL); 54 //如果路径下该文件目录不存在,则新建目录 55 if(!fileDir.exists()) 56 { 57 fileDir.mkdirs(); 58 } 59 60 FileOutputStream fos = new FileOutputStream(new File(fileDir,getFileName(path))); 61 fos.write(data); 62 fos.close(); 63 64 } 65 66 //保存bitmap格式的图片到扩展卡 67 public static void saveImage(String path,Bitmap bitmap , int format) throws FileNotFoundException 68 { 69 //判断扩展卡是否挂载 70 if(!isMounted()) 71 return; 72 //判断目录是否存在 73 File fileDir = new File(IMAGE_URL); 74 //如果路径下该文件目录不存在,则新建目录 75 if(!fileDir.exists()) 76 { 77 fileDir.mkdirs(); 78 } 79 //把图片数据写入到一个图片文件 80 FileOutputStream fos = new FileOutputStream(new File(fileDir,getFileName(path))); 81 82 //压缩图片 第一个参数是压缩后的格式,第二个参数是压缩后的效果,值越大,效果越好,第三个参数是输入流 83 bitmap.compress(format==1?CompressFormat.PNG:CompressFormat.JPEG, 100, fos); 84 85 } 86 87 //从扩展卡中读取图片的功能 88 public static Bitmap readImage(String path) 89 { 90 if(!isMounted()) 91 return null; 92 //获得文件名 93 String fileName = getFileName(path); 94 File file = new File(IMAGE_URL,fileName); 95 Bitmap bitmap = null; 96 if(file.exists()) 97 { 98 bitmap = BitmapFactory.decodeFile(file.getAbsolutePath()); 99 } 100 return bitmap; 101 } 102 //清空扩展卡中指定目录的所有数据 103 public static void clear(){ 104 //判断扩展卡是否挂载 105 if(!isMounted()) 106 return ; 107 File fileDir = new File(IMAGE_URL); 108 //如果指定目录存在 109 if(fileDir.exists()) 110 { 111 //获取指定目录下的所有文件及目录 112 File fileArray[] = fileDir.listFiles(); 113 for(File f:fileArray) 114 { 115 f.delete(); 116 } 117 } 118 } 119 120 121 }
1 package tools; 2 3 import java.io.ByteArrayOutputStream; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.net.HttpURLConnection; 7 import java.net.URL; 8 import java.nio.ByteOrder; 9 10 public class HttpUtil { 11 public static byte[] getInput(String path) throws IOException 12 { 13 URL url = new URL(path); 14 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 15 conn.setRequestMethod("GET"); 16 conn.setConnectTimeout(5000); 17 conn.setDoInput(true); 18 if(conn.getResponseCode()==200) 19 { 20 InputStream in = conn.getInputStream(); 21 return getbyte(in); 22 } 23 return null; 24 25 } 26 27 public static byte[] getbyte(InputStream in) throws IOException 28 { 29 ByteArrayOutputStream out = new ByteArrayOutputStream(); 30 int len = 0; 31 byte b[] = new byte[1024]; 32 while((len=in.read(b))!=-1) 33 { 34 out.write(b,0,len); 35 } 36 return out.toByteArray(); 37 38 39 } 40 }
文件保存位置:mnt/sdcard/myfile/image/下载的文件
-------------------------------------------------------------------------------------------------------------------------------------
相关知识: