又消沉了很久,很久没做一些总结了。公司事情比较忙,主要还是情况比较多,没有时间空闲下来。刚好最近个人想试试ubuntu ,所以在自己的pc上装了个ubuntu ,毕竟这种系统适合我们开发者胡作非为。但是个人又是小白,所以一直在摸索,导致android 开发环境还没有装成功,所以在家里也没时间来写写demo,只是学习性的看了一些文章。
好了,不闲扯了。正题。闲来无事,写了一个文件系统的应用。简单的展示文件,然后对文件进行了一些分类。

好了。先上效果图:

android 文件管理器媒体扫描 android 文件管理器的实现_异步加载-缓存


android 文件管理器媒体扫描 android 文件管理器的实现_图片视屏缩略图获取_02


android 文件管理器媒体扫描 android 文件管理器的实现_android_03

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

代码差不多介绍完了。希望对某些有需要的小伙伴有帮助。