1. 程式人生 > >android檔案快取及SD卡建立資料夾失敗解決和bitmap記憶體溢位解決

android檔案快取及SD卡建立資料夾失敗解決和bitmap記憶體溢位解決

 1.相關程式碼:

    新增許可權:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>  
    /** 獲取SD卡路徑 **/
    private static String getSDPath() {
        String sdcardPath = null;
        boolean sdCardExist = Environment.getExternalStorageState().equals(
                android.os.Environment.MEDIA_MOUNTED);  //判斷sd卡是否存在
        if (sdCardExist) {
            sdcardPath = Environment.getExternalStorageDirectory();//獲取根目錄
        }
        if (sdcardPath != null) {
            return sdcardPath;
        } else {
            return "";
        }
    }

  解決方法:獲取根目錄的程式碼改為:
  sdcardPath = Environment.getExternalStorageDirectory().getAbsolutePath();

這樣就可以了。

----------------------------------------------------------------------------------------------------------------------------------

附檔案快取類:

package com.etnet.utilities;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Comparator;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.os.StatFs;
import android.util.Log;

/**
 * 圖片檔案儲存、讀寫類
 * @author Barry
 */
public class FileOperationUtil {
	private static final String TAG = "FileOperationUtil";
    private static final String CACHE_DIRECTORY = "TqProCache";
                                                            
    private static final int MB = 1024*1024;
    private static final int MAX_CACHE_SIZE = 10 * MB;
    private static final int LEAST_SIZE_OF_SDCARD = 10 * MB;
    
    /** 從快取中獲取圖片 **/
    public static Bitmap getImage(final String imageUrl) {   
        final String path = getCacheDirectory() + "/" + convertUrlToFileName(imageUrl);
       // Log.i(TAG, "getImage filepath:" + path);
       // Log.i(TAG, "getImage url:" + url);
        File file = new File(path);
        if (file.exists()) {
//        	Log.i(TAG, "getImage file exists");
        	Bitmap bmp = null;
        	try {
        		//寬變為原圖的1/3,高也變為原圖的1/3。這樣是為了降低記憶體的消耗,防止記憶體溢位
        		BitmapFactory.Options options=new BitmapFactory.Options(); 
        		options.inSampleSize = 3; 
        		bmp = BitmapFactory.decodeFile(path,options);
        		LogUtil.d(TAG, "bmp size="+bmp.getByteCount());
			} catch (Exception e) {
				e.printStackTrace();
			}
            if (bmp == null) {
                file.delete();
            } else {
            	updateFileTime(path);
                return bmp;
            }
        }
        return null;
    }
                                                                
    /** 將圖片存入檔案快取 **/
    public static void saveBitmap(String imageUrl, Bitmap bm ) {
        if (bm == null) {
            return;
        }
        //判斷sdcard上的空間
        if (getFreeSpaceOfSdcard() < LEAST_SIZE_OF_SDCARD) {
            //SD空間不足
            return;
        }
        String filename = convertUrlToFileName(imageUrl);
        String dir = getCacheDirectory();
        File dirFile = new File(dir);
        if (!dirFile.exists()){
        	if(!dirFile.mkdirs()){
        		Log.w(TAG, "create cache file directorys failed");
        	}
        }
        File file = new File(dir +"/" + filename);
        try {
            file.createNewFile();
            OutputStream outStream = new FileOutputStream(file);
            bm.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
            outStream.flush();
            outStream.close();
        } catch (FileNotFoundException e) {
            Log.w(TAG, "FileNotFoundException");
        } catch (IOException e) {
            Log.w(TAG, "IOException");
        }
    }
                                                                
    /**
     * 計算儲存目錄下的檔案大小,
     * 當檔案總大小大於指定的MAX_CACHE_SIZE或者sdcard剩餘空間小於指定的LEAST_SIZE_OF_SDCARD
     * 那麼刪除40%最近沒有被使用的檔案
     */
    public static boolean removeExtraCache() {
        File dir = new File(getCacheDirectory());
        File[] files = dir.listFiles();
        if (files == null) {
            return true;
        }
        if (!android.os.Environment.getExternalStorageState().equals(
                android.os.Environment.MEDIA_MOUNTED)) {
            return false;
        }
                                                            
        int dirSize = 0;
        for (int i = 0; i < files.length; i++) {
        	dirSize += files[i].length();
        }
//        LogUtil.d("Barry", "dirSize="+dirSize);
                                                            
        if (dirSize > MAX_CACHE_SIZE || getFreeSpaceOfSdcard() < LEAST_SIZE_OF_SDCARD) {
            int removeNum = (int) ((0.4 * files.length) + 1);
            /* 根據檔案的最後修改時間進行升序排序 */
            Arrays.sort(files, new Comparator<File>() {
            	@Override
            	 public int compare(File file1, File file2) {
                     if (file1.lastModified() > file2.lastModified()) {
                         return 1;
                     } else if (file1.lastModified() == file2.lastModified()) {
                         return 0;
                     } else {
                         return -1;
                     }
                 }
			});
           /* for (int i = 0; i < files.length; i++) {
            	LogUtil.d("Barry", "file.modifiedTime="+files[i].lastModified());
			}*/
            for (int i = 0; i < removeNum; i++) {
            	files[i].delete();
            }
            return true;
        }else{
        	return false;
        }
    }
                                                                
    /** 修改檔案的最後修改時間 **/
    public static void updateFileTime(String path) {
        File file = new File(path);
        long newModifiedTime = System.currentTimeMillis();
        file.setLastModified(newModifiedTime);
    }
                                                                
    /** 計算sdcard上的剩餘空間 **/
    private static int getFreeSpaceOfSdcard() {
        StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
        double sdFreeSize = ((double)stat.getAvailableBlocks() * (double) stat.getBlockSize());
        return (int) sdFreeSize;
    }
                                                                
    private static String convertUrlToFileName(String url) {
        String[] strs = url.split("/");
        String savedImageName = strs[strs.length - 1];
        return savedImageName;
    }
                                                                
    /** 獲得快取目錄 **/
    private static String getCacheDirectory() {
        String dir = getSDPath() + "/" + CACHE_DIRECTORY;
        return dir;
    }
                                                                
    /** 獲取SD卡路徑 **/
    private static String getSDPath() {
        String sdcardPath = null;
        boolean sdCardExist = Environment.getExternalStorageState().equals(
                android.os.Environment.MEDIA_MOUNTED);  //判斷sd卡是否存在
        if (sdCardExist) {
            sdcardPath = Environment.getExternalStorageDirectory().getAbsolutePath();  //獲取根目錄
        }
        if (sdcardPath != null) {
            return sdcardPath;
        } else {
            return "";
        }
    }
}