安卓文件管理器簡單實現,包含文件類型篩選,異步緩存文件縮略圖獲取。

又消沉了很久,很久沒做一些總結了。公司事情比較忙,主要還是情況比較多,沒有時間空閒下來。剛好最近個人想試試ubuntu ,所以在自己的pc上裝了個ubuntu ,畢竟這種系統適合我們開發者胡作非爲。但是個人又是小白,所以一直在摸索,導致android 開發環境還沒有裝成功,所以在家裏也沒時間來寫寫demo,只是學習性的看了一些文章。
好了,不閒扯了。正題。閒來無事,寫了一個文件系統的應用。簡單的展示文件,然後對文件進行了一些分類。

好了。先上效果圖:
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述

第一步SD 卡檢測:

private void checkEnvironment() {
        File f = null;
        boolean sdCardExist = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED); //是否存在sd卡,這裏需要SD讀取權限
        if (sdCardExist) {//存在獲取sd卡目錄
            f = Environment.getExternalStorageDirectory();
            if (f != null) {
                mSDCardPath = f.getAbsolutePath();

            }

        } else {//不存在獲取手機根目錄
            f = Environment.getRootDirectory();
            if (f != null) {
                mSDCardPath = f.getAbsolutePath();
            }
        }
    }

接下來就是打開文件夾操作參數文件夾:

private void open(File f, boolean misAddToBackWardFiles) {
        if (f.isDirectory()) {
            deleteAllItems();

            mCurrentPathFile = f;
            file_path.setText(mCurrentPathFile.getAbsolutePath());

            if (misAddToBackWardFiles) {
                mbackwardfiles.add(mCurrentPathFile.getParentFile());
            }

            File[] files = f.listFiles();

            Arrays.sort(files, new FileComparator());//文件文件夾排序

            for (File file : files) {
                if (!misShowHiddenFiles && file.isHidden()) {
                    continue;
                }
                addItem(file);//加入文件列表
            }
        }
    }

文件和文件夾排序:

public class FileComparator implements Comparator<File> {//實現比較接口

    public int compare(File file1, File file2) { 
        if (file1.isDirectory() && !file2.isDirectory()) {//是否是文件夾  
            return -1000;
        } else if (!file1.isDirectory() && file2.isDirectory()) {
            return 1000;
        }
        return (file1.getName().toLowerCase()).compareTo(file2.getName() 
                .toLowerCase());   //都是文件夾  名字字母排序
    }
}

接下來就是文件類型判斷:我是自己寫了一個簡單的後綴名區分

/**
     * 
     * @param fileName
     * @return 0表示其他 1表示視屏2表示圖片
     */
    private int getFileType(String fileName){
        int filetype=0;
        String[] names=fileName.split("\\.");
        if(names.length==1){//沒有後綴名
            return 0;
        }
        String type=names[names.length-1];//拿到後綴名
        if(type.equalsIgnoreCase("JPGE")||type.equalsIgnoreCase("PNG")||type.equalsIgnoreCase("GIF")||type.equalsIgnoreCase("BMP")||type.equals("webp")||type.equalsIgnoreCase("jpg")){
            return 2;
        }else if(type.equalsIgnoreCase("mp4")||type.equalsIgnoreCase("3gp")||type.equalsIgnoreCase("mpg")||type.equalsIgnoreCase("rmvb")||type.equalsIgnoreCase("mov")||type.equalsIgnoreCase("avi")){
            return 1;
        }

        return filetype;
    }

接下來就是圖片和視屏縮略圖的獲取:我是通過從安卓系統數據庫去取,然後用了一個異步任務,並且爲了防止異步導致圖片加載錯亂,我就做了綁定,這樣可以解決錯亂問題。這部分網上有很多不詳細介紹了

/**
     * 獲取視頻縮略圖
     * 
     * @param videoPath
     * @return
     */
    private Bitmap getVideoThumbnail(String videoPath) {
        Bitmap bitmap = null;
        bitmap = ThumbnailUtils.createVideoThumbnail(videoPath, Images.Thumbnails.MINI_KIND);
        // bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,
        // ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
        return bitmap;
    }

    /**
     * 圖片縮略圖獲取
     * 
     * @param myPath
     * @return
     */
    public Bitmap getImageThumbnail(String myPath) {
        String[] projection = { MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID, };
        String whereClause = MediaStore.Images.Media.DATA + "='" + myPath + "'";
        Cursor cursor = contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, whereClause,
                null, null);
        int _id = 0;
        String imagePath = "";
        if (cursor == null || cursor.getCount() == 0) {
            return null;
        }
        int id = 0;
        if (cursor.moveToFirst()) {

            int _idColumn = cursor.getColumnIndex(MediaStore.Images.Media._ID);
            int _dataColumn = cursor.getColumnIndex(MediaStore.Images.Media.DATA);

            _id = cursor.getInt(_idColumn);
            imagePath = cursor.getString(_dataColumn);
            if (imagePath.equals(myPath)) {
                id = _id;
            }
        }
        cursor.close();
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inDither = false;
        options.inPreferredConfig = Bitmap.Config.RGB_565;
        Bitmap bitmap = MediaStore.Images.Thumbnails.getThumbnail(contentResolver, id, Images.Thumbnails.MINI_KIND,
                options);
        return bitmap;
    }

接下來是異步獲取加綁定,並且縮略圖緩存下來方便下次獲取。

/**
     * 圖片緩存技術的核心類,用於緩存所有下載好的圖片,在程序內存達到設定值時會將最少最近使用的圖片移除掉。
     */
    private LruCache<String, BitmapDrawable> mMemoryCache;

    /**
     * 異步下載圖片的任務。
     * 
     * @author guolin
     */
    class BitmapWorkerTask extends AsyncTask<String, Void, BitmapDrawable> {

        String imageUrl;

        private WeakReference<ImageView> imageViewReference;

        public BitmapWorkerTask(ImageView imageView) {
            imageViewReference = new WeakReference<ImageView>(imageView);
        }

        @Override
        protected BitmapDrawable doInBackground(String... params) {
            imageUrl = params[0];
            // 在後臺開始下載圖片
            Bitmap bitmap = null;
            if (getFileType(imageUrl) == 2) {
                bitmap = getImageThumbnail(imageUrl);
                if (bitmap == null) {
                    bitmap = mImageBitmap;
                }
            } else {
                getVideoThumbnail(imageUrl);
                if (bitmap == null) {
                    bitmap = mVideoBitmap;
                }
            }

            BitmapDrawable drawable = new BitmapDrawable(context.getResources(), bitmap);
            addBitmapToMemoryCache(imageUrl, drawable);
            return drawable;
        }

        @Override
        protected void onPostExecute(BitmapDrawable drawable) {
            ImageView imageView = getAttachedImageView();
            if (imageView != null && drawable != null) {
                imageView.setImageDrawable(drawable);
            }
        }

        /**
         * 獲取當前BitmapWorkerTask所關聯的ImageView。
         */
        private ImageView getAttachedImageView() {
            ImageView imageView = imageViewReference.get();
            BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
            if (this == bitmapWorkerTask) {
                return imageView;
            }
            return null;
        }

    }

    /**
     * 自定義的一個Drawable,讓這個Drawable持有BitmapWorkerTask的弱引用。
     */
    class AsyncDrawable extends BitmapDrawable {

        private WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;

        public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) {
            super(res, bitmap);
            bitmapWorkerTaskReference = new WeakReference<BitmapWorkerTask>(bitmapWorkerTask);
        }

        public BitmapWorkerTask getBitmapWorkerTask() {
            return bitmapWorkerTaskReference.get();
        }

    }

    /**
     * 獲取傳入的ImageView它所對應的BitmapWorkerTask。
     */
    private BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
        if (imageView != null) {
            Drawable drawable = imageView.getDrawable();
            if (drawable instanceof AsyncDrawable) {
                AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
                return asyncDrawable.getBitmapWorkerTask();
            }
        }
        return null;
    }

    /**
     * 取消掉後臺的潛在任務,當認爲當前ImageView存在着一個另外圖片請求任務時 ,則把它取消掉並返回true,否則返回false。
     */
    public boolean cancelPotentialWork(String url, ImageView imageView) {
        BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
        if (bitmapWorkerTask != null) {
            String imageUrl = bitmapWorkerTask.imageUrl;
            if (imageUrl == null || !imageUrl.equals(url)) {
                bitmapWorkerTask.cancel(true);
            } else {
                return false;
            }
        }
        return true;
    }

    /**
     * 將一張圖片存儲到LruCache中。
     * 
     * @param key
     *            LruCache的鍵,這裏傳入圖片的URL地址。
     * @param drawable
     *            LruCache的值,這裏傳入從網絡上下載的BitmapDrawable對象。
     */
    public void addBitmapToMemoryCache(String key, BitmapDrawable drawable) {
        if (getBitmapFromMemoryCache(key) == null) {
            mMemoryCache.put(key, drawable);
        }
    }

    /**
     * 從LruCache中獲取一張圖片,如果不存在就返回null。
     * 
     * @param key
     *            LruCache的鍵,這裏傳入圖片的URL地址。
     * @return 對應傳入鍵的BitmapDrawable對象,或者null。
     */
    public BitmapDrawable getBitmapFromMemoryCache(String key) {
        return mMemoryCache.get(key);
    }

adapter中關鍵代碼

if (getFileType(curFile.getName()) != 0) {//判斷是否是圖片或者是視屏
                BitmapDrawable drawable = getBitmapFromMemoryCache(curFile.getAbsolutePath());//先查看緩存是否有
                if (drawable != null) {
                    vh.list_file_imag.setImageDrawable(drawable);
                } else if (cancelPotentialWork(curFile.getAbsolutePath(), vh.list_file_imag)) {//沒有就異步緩存
                    BitmapWorkerTask task = new BitmapWorkerTask(vh.list_file_imag);
                    AsyncDrawable asyncDrawable = new AsyncDrawable(context.getResources(), mLoadingBitmap, task);
                    vh.list_file_imag.setImageDrawable(asyncDrawable);
                    task.execute(curFile.getAbsolutePath());
                }
            }

代碼差不多介紹完了。希望對某些有需要的小夥伴有幫助。

下面是源碼地址。可自行下載。
http://download.csdn.net/detail/qq_35522272/9620969

發佈了34 篇原創文章 · 獲贊 88 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章