Android获取可存储文件所有路径

引言:大家在做app开发的时候,基本都会保存文件到手机,android存储文件的地方有很多,不像ios一样,只能把文件存储到当前app目录下,并且android手机由于厂家定制了rom,sdcard的路径在不同手机上都会不一样.我这边封装了获取路径的几个方法,放在一个工具类里面.

1.获取扩展存储设备
2.获取sdcard2外部存储空间
3.获取可用的 EMMC 内部存储空间
4.获取其他外部存储可用空间
5.获取内部存储目录


Activity  程序的入口,在oncreate方法里面通过工具类获取文件保存路径,并且打印出来.(还写了一个创建指定大小空文件的方法,有需要的可以调用)

/**
 * 获取存储路径,并且打印出来
 * @author ansen
 * @create time 2015-09-07
 */
public class MainActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		String str=FileUtil.getCachePath();
//		writeFileSize(str+"/ansen.mp3",50);  //在当前目录下创建ansen.mp3文件  文件长度50兆
		System.out.println(str);
	}
	
	/**
	 * 创建指定大小的文件.写入空数据
	 * @param filePath  文件路径
	 * @param size  文件长度  单位是兆
	 */
	private void writeFileSize(String filePath,int size){
		try {
			RandomAccessFile raf = new RandomAccessFile(filePath,"rw");
			raf.seek(raf.length());//每次从文件末尾写入
			for (int i = 0; i < size; i++) {//一共写入260兆,想写多大的文件改变这个值就行
			    byte[] buffer = new byte[1024*1024]; //1次1M,这样内存开的大一些,又不是特别大。
			    raf.write(buffer);
			    System.out.println("写入1兆..."+i);
			}
			raf.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


文件工具类  封装了一个公共方法,获取文件保存路径,一共可以获取5个路径,依次判断5个路径预留空间是否大于50兆.大于就直接返回路径

/**
 * 文件工具类
 * @author ansen
 * @create time 2015-09-07
 */
public final class FileUtil {
	private static final String FOLDER_NAME = "ansen";//这里可以换成你的app名称
	private static final long MIN_STORAGE=52428800;//50*1024*1024最低50m
	
	//缓存路径
	public static String getCachePath(){
		String path = getSavePath(MIN_STORAGE);
		if(TextUtils.isEmpty(path)){
			return null;
		}
		path= path + FOLDER_NAME + "/cache";
		makeDir(path);
		return path;
	}
	
	/**
	 * 获取保存文件路径  
	 * @param saveSize  预留空间
	 * @return 文件路径
	 */
	private static String getSavePath(long saveSize) {
	    String savePath = null;
	    if (StorageUtil.getExternaltStorageAvailableSpace() > saveSize) {//扩展存储设备>预留空间
	        savePath = StorageUtil.getExternalStorageDirectory();
	        File saveFile = new File(savePath);
	        if (!saveFile.exists()) {
	            saveFile.mkdirs();
	        } else if (!saveFile.isDirectory()) {
	            saveFile.delete();
	            saveFile.mkdirs();
	        }
	    } else if (StorageUtil.getSdcard2StorageAvailableSpace() > saveSize) {//sdcard2外部存储空间>预留空间
	        savePath = StorageUtil.getSdcard2StorageDirectory();
	        File saveFile = new File(savePath);
	        if (!saveFile.exists()) {
	            saveFile.mkdirs();
	        } else if (!saveFile.isDirectory()) {
	            saveFile.delete();
	            saveFile.mkdirs();
	        }
	    } else if (StorageUtil.getEmmcStorageAvailableSpace() > saveSize) {//可用的 EMMC 内部存储空间>预留空间
	        savePath = StorageUtil.getEmmcStorageDirectory();
	        File saveFile = new File(savePath);
	        if (!saveFile.exists()) {
	            saveFile.mkdirs();
	        } else if (!saveFile.isDirectory()) {
	            saveFile.delete();
	            saveFile.mkdirs();
	        }
	    } else if (StorageUtil.getOtherExternaltStorageAvailableSpace()>saveSize) {//其他外部存储可用空间>预留空间
	        savePath = StorageUtil.getOtherExternalStorageDirectory();
	        File saveFile = new File(savePath);
	        if (!saveFile.exists()) {
	            saveFile.mkdirs();
	        } else if (!saveFile.isDirectory()) {
	            saveFile.delete();
	            saveFile.mkdirs();
	        }
	    }else if (StorageUtil.getInternalStorageAvailableSpace() > saveSize) {//内部存储目录>预留空间
	        savePath = StorageUtil.getInternalStorageDirectory() + File.separator;
	    }
	    return savePath;
	}
	
	/**
	 * 创建文件夹
	 * @param path
	 */
	private static void makeDir(String path){
		File file = new File(path);
		if(!file.exists()){
			file.mkdirs();
		}
		file = null;
	}
}



封装了获取各种路径的一些方法,供FileUtil类调用.

/**
 * 封装了获取文件路径的一些方法
 * @author ansen
 * @create time 2015-09-07
 */
@SuppressLint("NewApi")
public final class StorageUtil {
	private static String otherExternalStorageDirectory = null;
	private static int kOtherExternalStorageStateUnknow = -1;
	private static int kOtherExternalStorageStateUnable = 0;
	private static int kOtherExternalStorageStateIdle = 1;
	private static int otherExternalStorageState = kOtherExternalStorageStateUnknow;
	private static String internalStorageDirectory;
	
	public static Context context;

	public static void init(Context cxt) {
		context = cxt;
	}
	
	/** get external Storage available space */
	public static long getExternaltStorageAvailableSpace() {
		if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
			return 0;
		}
		File path = Environment.getExternalStorageDirectory();
		StatFs statfs = new StatFs(path.getPath());
		
		long blockSize;
		if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
			blockSize = statfs.getBlockSizeLong();
		}else {
			blockSize = statfs.getBlockSize();
		}

		long availableBlocks;
		if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
			availableBlocks = statfs.getAvailableBlocksLong();
		}else {
			availableBlocks = statfs.getAvailableBlocks();
		}
		return blockSize * availableBlocks;
	}
	
	public final static String getInternalStorageDirectory() {
		if (TextUtils.isEmpty(internalStorageDirectory)) {
			File file = context.getFilesDir();
			internalStorageDirectory = file.getAbsolutePath();
			if (!file.exists())
				file.mkdirs();
			String shellScript = "chmod 705 " + internalStorageDirectory;
			runShellScriptForWait(shellScript);
		}
		return internalStorageDirectory;
	}
	
	public static long getInternalStorageAvailableSpace() {
		String path = getInternalStorageDirectory();
		StatFs stat = new StatFs(path);
//		long blockSize = stat.getBlockSizeLong();
		long blockSize;
		if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
			blockSize = stat.getBlockSizeLong();
		}else {
			blockSize = stat.getBlockSize();
		}
//		long availableBlocks = stat.getAvailableBlocksLong();
		long availableBlocks;
		if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
			availableBlocks = stat.getAvailableBlocksLong();
		}else {
			availableBlocks = stat.getAvailableBlocks();
		}
		
		return blockSize * availableBlocks;
	}
	
	
	
	public final static String getExternalStorageDirectory() {
		return Environment.getExternalStorageDirectory() + File.separator + "";
	}
	
	/** get sdcard2 external Storage available space */
	public static long getSdcard2StorageAvailableSpace() {
		if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
			return 0;
		}
		String path = getSdcard2StorageDirectory();
		File file = new File(path);
		if (!file.exists())
			return 0;
		StatFs statfs = new StatFs(path);
//		long blockSize = statfs.getBlockSizeLong();
		long blockSize;
		if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
			blockSize = statfs.getBlockSizeLong();
		}else {
			blockSize = statfs.getBlockSize();
		}
		
//		long availableBlocks = statfs.getAvailableBlocksLong();
		long availableBlocks;
		if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
			availableBlocks = statfs.getAvailableBlocksLong();
		}else {
			availableBlocks = statfs.getAvailableBlocks();
		}
		
		return blockSize * availableBlocks;
	}
	
	public final static String getSdcard2StorageDirectory() {
		return "/mnt/sdcard2/";
	}
	
	public static boolean runShellScriptForWait(final String cmd)throws SecurityException {
		ShellThread thread = new ShellThread(cmd);
		thread.setDaemon(true);
		thread.start();
		int k = 0;
		while (!thread.isReturn() && k++ < 20) {
			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if (k >= 20) {
			thread.interrupt();
		}
		return thread.isSuccess();
	}
	
	/** 用于执行shell脚本的线程 */
	private static class ShellThread extends Thread {
		private boolean isReturn;
		private boolean isSuccess;
		private String cmd;

		public boolean isReturn() {
			return isReturn;
		}

		public boolean isSuccess() {
			return isSuccess;
		}

		/**
		 * @param cmd shell命令内容
		 * @param isReturn  线程是否已经返回
		 * @param isSuccess Process是否执行成功
		 */
		public ShellThread(String cmd) {
			this.cmd = cmd;
		}

		@Override
		public void run() {
			try {
				Runtime runtime = Runtime.getRuntime();
				Process proc;
				try {
					proc = runtime.exec(cmd);
					isSuccess = (proc.waitFor() == 0);
				} catch (IOException e) {
					e.printStackTrace();
				}
				isSuccess = true;
			} catch (InterruptedException e) {
			}
			isReturn = true;
		}
	}
	
	/** get EMMC internal Storage available space */
	public static long getEmmcStorageAvailableSpace() {
		String path = getEmmcStorageDirectory();
		File file = new File(path);
		if (!file.exists())
			return 0;
		StatFs statfs = new StatFs(path);
//		long blockSize = statfs.getBlockSizeLong();
		long blockSize;
		if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
			blockSize = statfs.getBlockSizeLong();
		}else {
			blockSize = statfs.getBlockSize();
		}
		
//		long availableBlocks = statfs.getAvailableBlocksLong();
		long availableBlocks;
		if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
			availableBlocks = statfs.getAvailableBlocksLong();
		}else {
			availableBlocks = statfs.getAvailableBlocks();
		}

		return blockSize * availableBlocks;
	}
	
	public final static String getEmmcStorageDirectory() {
		return "/mnt/emmc/";
	}
	
	/** get other external Storage available space */
	public static long getOtherExternaltStorageAvailableSpace() {
		if (!Environment.getExternalStorageState().equals(
				Environment.MEDIA_MOUNTED)) {
			return 0;
		}
		if (otherExternalStorageState == kOtherExternalStorageStateUnable)
			return 0;
		if (otherExternalStorageDirectory == null) {
			getOtherExternalStorageDirectory();
		}
		if (otherExternalStorageDirectory == null)
			return 0;
		StatFs statfs = new StatFs(otherExternalStorageDirectory);
//		long blockSize = statfs.getBlockSizeLong();
		long blockSize;
		if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
			blockSize = statfs.getBlockSizeLong();
		}else {
			blockSize = statfs.getBlockSize();
		}
//		long availableBlocks = statfs.getAvailableBlocksLong();
		long availableBlocks;
		if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
			availableBlocks = statfs.getAvailableBlocksLong();
		}else {
			availableBlocks = statfs.getAvailableBlocks();
		}
		return blockSize * availableBlocks;
	}
	
	
	public static String getOtherExternalStorageDirectory() {
		if (otherExternalStorageState == kOtherExternalStorageStateUnable)
			return null;
		if (otherExternalStorageState == kOtherExternalStorageStateUnknow) {
			FstabReader fsReader = new FstabReader();
			if (fsReader.size() <= 0) {
				otherExternalStorageState = kOtherExternalStorageStateUnable;
				return null;
			}
			List<StorageInfo> storages = fsReader.getStorages();
			/* 对于可用空间小于100M的挂载节点忽略掉 */
			long availableSpace = 100 << (20);
			String path = null;
			for (int i = 0; i < storages.size(); i++) {
				StorageInfo info = storages.get(i);
				if (info.getAvailableSpace() > availableSpace) {
					availableSpace = info.getAvailableSpace();
					path = info.getPath();
				}
			}
			otherExternalStorageDirectory = path;
			if (otherExternalStorageDirectory != null) {
				otherExternalStorageState = kOtherExternalStorageStateIdle;
			} else {
				otherExternalStorageState = kOtherExternalStorageStateUnable;
			}
			if(!TextUtils.isEmpty(otherExternalStorageDirectory)){
				if(!otherExternalStorageDirectory.endsWith("/")){
					otherExternalStorageDirectory=otherExternalStorageDirectory+"/";
				}
			}
		}
		return otherExternalStorageDirectory;
	}
	
	public static class FstabReader {
		public FstabReader() {
			init();
		}

		public int size() {
			return storages == null ? 0 : storages.size();
		}

		public List<StorageInfo> getStorages() {
			return storages;
		}

		final List<StorageInfo> storages = new ArrayList<StorageInfo>();

		public void init() {
			File file = new File("/system/etc/vold.fstab");
			if (file.exists()) {
				FileReader fr = null;
				BufferedReader br = null;
				try {
					fr = new FileReader(file);
					if (fr != null) {
						br = new BufferedReader(fr);
						String s = br.readLine();
						while (s != null) {
							if (s.startsWith("dev_mount")) {
								/* "\s"转义符匹配的内容有:半/全角空格 */
								String[] tokens = s.split("\\s");
								String path = tokens[2]; // mount_point
								StatFs stat = new StatFs(path);
								
								long blockSize;
								long totalBlocks;
								long availableBlocks;
								if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
									blockSize = stat.getBlockSizeLong();
								}else {
									blockSize = stat.getBlockSize();
								}
								if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
									totalBlocks = stat.getBlockCountLong();
								}else {
									totalBlocks = stat.getBlockCount();
								}
								if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
									availableBlocks = stat.getAvailableBlocksLong();
								}else {
									availableBlocks = stat.getAvailableBlocks();
								}
								
//								if (null != stat&& stat.getAvailableBlocksLong() > 0) {
//
//									long availableSpace = stat.getAvailableBlocksLong()* stat.getBlockSizeLong();
//									long totalSpace = stat.getBlockCountLong()* stat.getBlockSizeLong();
								if (null != stat&& availableBlocks > 0) {

									long availableSpace = availableBlocks* blockSize;
									long totalSpace = totalBlocks* blockSize;
									StorageInfo storage = new StorageInfo(path,
											availableSpace, totalSpace);
									storages.add(storage);
								}
							}
							s = br.readLine();
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					if (fr != null)
						try {
							fr.close();
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					if (br != null)
						try {
							br.close();
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
				}
			}
		}
	}

	static class StorageInfo implements Comparable<StorageInfo> {
		private String path;
		private long availableSpace;
		private long totalSpace;

		StorageInfo(String path, long availableSpace, long totalSpace) {
			this.path = path;
			this.availableSpace = availableSpace;
			this.totalSpace = totalSpace;
		}

		@Override
		public int compareTo(StorageInfo another) {
			if (null == another)
				return 1;

			return this.totalSpace - another.totalSpace > 0 ? 1 : -1;
		}

		long getAvailableSpace() {
			return availableSpace;
		}

		long getTotalSpace() {
			return totalSpace;
		}

		String getPath() {
			return path;
		}
	}
	
}


最后记得在AndroidManifest.xml中配置读写sdcard权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />


点击下载源码


推荐一个Android开发者公众号,每周都有原创干货


阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lowprofile_coding/article/details/48269011
个人分类: android
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭