文件管理器源码分析(五)

/**
 * 这个文件夹里储的内容是app2sd产生的文件夹,也就是是你手机上所安装到SD的应用程序的缓存文件夹。
 * androidsecure文件可以删除吗?
 *如果删除之后,软件不能正常使用,和系统没关系。
 *话除能导致移sd损坏,数据丢失,并不会造成什么严重后果。
 * 只要把移sd损坏程,重装,手机就完全没损伤,文件夹也会在再次app2sd时自重建
 */
public class Util {
    private static String ANDROID_SECURE = "/mnt/sdcard/.android_secure";
    private static final String LOG_TAG = "Util";
    //获得SD卡的存储状态,“mounted”表示已经就绪
    public static boolean isSDCardReady() {
        return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
    }
    // if path1 contains path2
    public static boolean containsPath(String path1, String path2) {
        String path = path2;
        while (path != null) {
            if (path.equalsIgnoreCase(path1))
                return true;
            if (path.equals(GlobalConsts.ROOT_PATH))
                break;
            path = new File(path).getParent();
        }
        return false;
    }
    //2个路径相加的时候,是否需要加上文件分隔符
    public static String makePath(String path1, String path2) {
        if (path1.endsWith(File.separator))
            return path1 + path2;
        return path1 + File.separator + path2;
    }
    //获得SD卡的存储目录
    public static String getSdDirectory() {
        return Environment.getExternalStorageDirectory().getPath();
    }
    //判断1个文件是否为“普通文件”,ANDROID_SECURE下的文件都不是普通的
    public static boolean isNormalFile(String fullName) {
        return !fullName.equals(ANDROID_SECURE);
    }
    //根据文件路径,获得Java文件File,再包装成FileInfo
    public static FileInfo GetFileInfo(String filePath) {
        File lFile = new File(filePath);
        if (!lFile.exists())
            return null;
        FileInfo lFileInfo = new FileInfo();
        lFileInfo.canRead = lFile.canRead();
        lFileInfo.canWrite = lFile.canWrite();
        lFileInfo.isHidden = lFile.isHidden();
        lFileInfo.fileName = Util.getNameFromFilepath(filePath);
        lFileInfo.ModifiedDate = lFile.lastModified();
        lFileInfo.IsDir = lFile.isDirectory();
        lFileInfo.filePath = filePath;
        lFileInfo.fileSize = lFile.length();
        return lFileInfo;
    }
    //根据File对象,和FilenameFilter等选项,获得包装的FileInfo
    //需要注意多少,如果File是个目录,Count就是当前目录下的文件的个数。如果是普通文件,就计算文件大小。
    //这个时候,我们知道Count字段的含义了
    public static FileInfo GetFileInfo(File f, FilenameFilter filter, boolean showHidden) {
        FileInfo lFileInfo = new FileInfo();
        String filePath = f.getPath();
        File lFile = new File(filePath);
        lFileInfo.canRead = lFile.canRead();
        lFileInfo.canWrite = lFile.canWrite();
        lFileInfo.isHidden = lFile.isHidden();
        lFileInfo.fileName = f.getName();
        lFileInfo.ModifiedDate = lFile.lastModified();
        lFileInfo.IsDir = lFile.isDirectory();
        lFileInfo.filePath = filePath;
        if (lFileInfo.IsDir) {
            int lCount = 0;
            File[] files = lFile.listFiles(filter);
            // null means we cannot access this dir
            if (files == null) {
                return null;
            }
            for (File child : files) {
                if ((!child.isHidden() || showHidden)
                        && Util.isNormalFile(child.getAbsolutePath())) {
                    lCount++;
                }
            }
            lFileInfo.Count = lCount;
        } else {
            lFileInfo.fileSize = lFile.length();
        }
        return lFileInfo;
    }
    /*
     * 采用了新的办法获取APK图标,之前的失败是因为android中存在的一个BUG,通过
     * appInfo.publicSourceDir = apkPath;来修正这个问题,详情参见:
     * http://code.google.com/p/android/issues/detail?id=9151
     */
    public static Drawable getApkIcon(Context context, String apkPath) {
        PackageManager pm = context.getPackageManager();
        PackageInfo info = pm.getPackageArchiveInfo(apkPath,
                PackageManager.GET_ACTIVITIES);
        if (info != null) {
            ApplicationInfo appInfo = info.applicationInfo;
            appInfo.sourceDir = apkPath;
            appInfo.publicSourceDir = apkPath;
            try {
                return appInfo.loadIcon(pm);
            } catch (OutOfMemoryError e) {
                Log.e(LOG_TAG, e.toString());
            }
        }
        return null;
    }
    //获得文件的扩展名
    public static String getExtFromFilename(String filename) {
        int dotPosition = filename.lastIndexOf(‘.‘);
        if (dotPosition != -1) {
            return filename.substring(dotPosition + 1, filename.length());
        }
        return "";
    }
    //获得去掉“文件后缀”的文件名字,比如“C:/a/b/c.png”,输出“C:/a/b/c”
    public static String getNameFromFilename(String filename) {
        int dotPosition = filename.lastIndexOf(‘.‘);
        if (dotPosition != -1) {
            return filename.substring(0, dotPosition);
        }
        return "";
    }
    //从文件路径中,获得路径
    public static String getPathFromFilepath(String filepath) {
        int pos = filepath.lastIndexOf(‘/‘);
        if (pos != -1) {
            return filepath.substring(0, pos);
        }
        return "";
    }
    //从文件路径中,获得文件名(带后缀,如果有)
    public static String getNameFromFilepath(String filepath) {
        int pos = filepath.lastIndexOf(‘/‘);
        if (pos != -1) {
            return filepath.substring(pos + 1);
        }
        return "";
    }
    // return new file path if successful, or return null
    public static String copyFile(String src, String dest) {
        File file = new File(src);
        if (!file.exists() || file.isDirectory()) {
            Log.v(LOG_TAG, "copyFile: file not exist or is directory, " + src);
            return null;
        }
        FileInputStream fi = null;
        FileOutputStream fo = null;
        try {
            fi = new FileInputStream(file);
            File destPlace = new File(dest);
            if (!destPlace.exists()) {
                if (!destPlace.mkdirs())
                    return null;
            }
            String destPath = Util.makePath(dest, file.getName());
            File destFile = new File(destPath);
            int i = 1;
            while (destFile.exists()) {
                String destName = Util.getNameFromFilename(file.getName()) + " " + i++ + "."
                        + Util.getExtFromFilename(file.getName());
                destPath = Util.makePath(dest, destName);
                destFile = new File(destPath);
            }
            if (!destFile.createNewFile())
                return null;
            fo = new FileOutputStream(destFile);
            int count = 102400;
            byte[] buffer = new byte[count];
            int read = 0;
            while ((read = fi.read(buffer, 0, count)) != -1) {
                fo.write(buffer, 0, read);
            }
            // TODO: set access privilege
            return destPath;
        } catch (FileNotFoundException e) {
            Log.e(LOG_TAG, "copyFile: file not found, " + src);
            e.printStackTrace();
        } catch (IOException e) {
            Log.e(LOG_TAG, "copyFile: " + e.toString());
        } finally {
            try {
                if (fi != null)
                    fi.close();
                if (fo != null)
                    fo.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
    // does not include sd card folder
    private static String[] SysFileDirs = new String[] {
        "miren_browser/imagecaches"
    };
    //判断一个文件是否需要显示,根据Setting中的设置。特别说明:某个系统文件目录,不显示。
    public static boolean shouldShowFile(String path) {
        return shouldShowFile(new File(path));
    }
    //判断一个文件是否需要显示,根据Setting中的设置。特别说明:某个系统文件目录,不显示。
    public static boolean shouldShowFile(File file) {
        boolean show = Settings.instance().getShowDotAndHiddenFiles();
        if (show)
            return true;
        if (file.isHidden())
            return false;
        if (file.getName().startsWith("."))
            return false;
        String sdFolder = getSdDirectory();
        for (String s : SysFileDirs) {
            if (file.getPath().startsWith(makePath(sdFolder, s)))
                return false;
        }
        return true;
    }
    //根据上下文对象Context,获得默认的收藏集合
    public static ArrayList<FavoriteItem> getDefaultFavorites(Context context) {
        ArrayList<FavoriteItem> list = new ArrayList<FavoriteItem>();
        list.add(new FavoriteItem(context.getString(R.string.favorite_photo), makePath(getSdDirectory(), "DCIM/Camera")));
        list.add(new FavoriteItem(context.getString(R.string.favorite_sdcard), getSdDirectory()));
        //list.add(new FavoriteItem(context.getString(R.string.favorite_root), getSdDirectory()));
        list.add(new FavoriteItem(context.getString(R.string.favorite_screen_cap), makePath(getSdDirectory(), "MIUI/screen_cap")));
        list.add(new FavoriteItem(context.getString(R.string.favorite_ringtone), makePath(getSdDirectory(), "MIUI/ringtone")));
        return list;
    }
    //向View中的某个TextView设置文本
    public static boolean setText(View view, int id, String text) {
        TextView textView = (TextView) view.findViewById(id);
        if (textView == null)
            return false;
        textView.setText(text);
        return true;
    }
    //向View中的某个TextView设置文本
    public static boolean setText(View view, int id, int text) {
        TextView textView = (TextView) view.findViewById(id);
        if (textView == null)
            return false;
        textView.setText(text);
        return true;
    }
    // comma separated number
    public static String convertNumber(long number) {
        return String.format("%,d", number);
    }
    // storage, G M K B
    public static String convertStorage(long size) {
        long kb = 1024;
        long mb = kb * 1024;
        long gb = mb * 1024;
        if (size >= gb) {
            return String.format("%.1f GB", (float) size / gb);
        } else if (size >= mb) {
            float f = (float) size / mb;
            return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f);
        } else if (size >= kb) {
            float f = (float) size / kb;
            return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f);
        } else
            return String.format("%d B", size);
    }
    public static class SDCardInfo {
        public long total;
        public long free;
    }
    //获得SD卡的各种信息,总容量大小和剩余容量大小等
    public static SDCardInfo getSDCardInfo() {
        String sDcString = android.os.Environment.getExternalStorageState();
        if (sDcString.equals(android.os.Environment.MEDIA_MOUNTED)) {
            File pathFile = android.os.Environment.getExternalStorageDirectory();
            try {
                android.os.StatFs statfs = new android.os.StatFs(pathFile.getPath());
                // 获取SDCard上BLOCK总数
                long nTotalBlocks = statfs.getBlockCount();
                // 获取SDCard上每个block的SIZE
                long nBlocSize = statfs.getBlockSize();
                // 获取可供程序使用的Block的数量
                long nAvailaBlock = statfs.getAvailableBlocks();
                // 获取剩下的所有Block的数量(包括预留的一般程序无法使用的块)
                long nFreeBlock = statfs.getFreeBlocks();
                SDCardInfo info = new SDCardInfo();
                // 计算SDCard 总容量大小MB
                info.total = nTotalBlocks * nBlocSize;
                // 计算 SDCard 剩余大小MB
                info.free = nAvailaBlock * nBlocSize;
                return info;
            } catch (IllegalArgumentException e) {
                Log.e(LOG_TAG, e.toString());
            }
        }
        return null;
    }
    //显示一条系统通知
    public static void showNotification(Context context, Intent intent, String title, String body, int drawableId) {
        NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        Notification notification = new Notification(drawableId, body, System.currentTimeMillis());
        notification.flags = Notification.FLAG_AUTO_CANCEL;
        notification.defaults = Notification.DEFAULT_SOUND;
        if (intent == null) {
            // FIXEME: category tab is disabled
            intent = new Intent(context, FileViewActivity.class);
        }
        PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_ONE_SHOT);
        manager.notify(drawableId, notification);
    }
    //格式化毫秒格式的时间
    public static String formatDateString(Context context, long time) {
        DateFormat dateFormat = android.text.format.DateFormat
                .getDateFormat(context);
        DateFormat timeFormat = android.text.format.DateFormat
                .getTimeFormat(context);
        Date date = new Date(time);
        return dateFormat.format(date) + " " + timeFormat.format(date);
    }
    public static void updateActionModeTitle(ActionMode mode, Context context, int selectedNum) {
        if (mode != null) {
            mode.setTitle(context.getString(R.string.multi_select_title,selectedNum));
            if(selectedNum == 0){
                mode.finish();
            }
        }
    }
//對sDocMimeTypesSet查詢拼接條件是
    public static HashSet<String> sDocMimeTypesSet = new HashSet<String>() {
        {
            add("text/plain");
            add("text/plain");
            add("application/pdf");
            add("application/msword");
            add("application/vnd.ms-excel");
            add("application/vnd.ms-excel");
        }
    };
//对于压缩文件(Zip)的查詢條件是:
    public static String sZipFileMimeType = "application/zip";
    public static int CATEGORY_TAB_INDEX = 0;
    public static int SDCARD_TAB_INDEX = 1;
}
时间: 2024-08-29 02:03:30

文件管理器源码分析(五)的相关文章

文件管理器源码分析(一)

Aboutmillet file management source code analysis Openthe file manager millet, we will soon see the interface as shownbelow: Amongthem, will be a variety of document classification. And show thenumber of each file. Androidframework of the MediaStore h

文件管理器源码分析(三)

//存储favorite数据,到数据库 //SQLiteOpenHelper是一个帮助管理数据库和版本的工具类. //通过继承并重载方法,快速实现了我们自己的Favorite表的CRUD. //怎么感觉和FileOperationHelper类似,仍然是CRUD,只不过1个是数据库中的,1个是文件的. public class FavoriteDatabaseHelper extends SQLiteOpenHelper { //下面6个字段是数据库的名字和版本号.表的名字和3个字段 priva

文件管理器源码分析(二)

/** * 文件操作工具类,执行文件的创建.移动.粘贴.重命名.删除等 * 任务的异步执行和IOperationProgressListener. 拷贝和删除等操作,是比较费时的,采用了异步执行的方式~ http://blog.csdn.net/xufenghappy6/article/details/7343899 异步执行+事件通知 是一种比较流行的模式,比同步等待很多时候要好. */ public class FileOperationHelper { private static fin

baksmali和smali源码分析(五)

官方文档对于dex中的class数据结构表示如下: class_idx uint index into the type_ids list for this class. This must be a class type, and not an array or primitive type. access_flags uint access flags for the class (public, final, etc.). See "access_flags Definitions&quo

linux调度器源码分析 - 运行(四)

本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 引言 之前的文章已经将调度器的数据结构.初始化.加入进程都进行了分析,这篇文章将主要说明调度器是如何在程序稳定运行的情况下进行进程调度的. 系统定时器 因为我们主要讲解的是调度器,而会涉及到一些系统定时器的知识,这里我们简单讲解一下内核中定时器是如何组织,又是如何通过通过定时器实现了调度器的间隔调度.首先我们先看一下内核定时器的框架 在内核中,会使用strut clock_event_device结构描述硬件

Nouveau源码分析(五):NVIDIA设备初始化之nouveau_drm_load (2)

Nouveau源码分析(五) 接着上一篇来,先把nouveau_drm_load再贴出一遍来吧: // /drivers/gpu/drm/nouveau/nouveau_drm.c 364 static int 365 nouveau_drm_load(struct drm_device *dev, unsigned long flags) 366 { 367 struct pci_dev *pdev = dev->pdev; 368 struct nouveau_drm *drm; 369 i

[Android] Volley源码分析(五)答疑

Volley源码分析系列出了有一段日子了,有不少看官私底下给我留言,同时抛出了一些问题.对于一些比较简单的问题我们跳过去,这两天接到网友是@smali提出的问题.不得不赞一下这位看官看源码时候的细腻程度,我引出这个问题供大家一块思考一下. Q:在写入文件头数据的时候为何不直接写入Int而是通过移位的方式来完成? 我们来看一下对应的源码: writeInt(os, CACHE_MAGIC); static void writeInt(OutputStream os, int n) throws I

linux调度器源码分析 - 初始化(二)

本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 引言 上期文章linux调度器源码分析 - 概述(一)已经把调度器相关的数据结构介绍了一遍,本篇着重通过代码说明调度器在系统启动初始化阶段是如何初始化和工作的.通过上期文章我们知道,在多核CPU和SMP系统中,每个CPU(多核COU中的每个核)都有自己的struct rq队列,而rq队列中又有着自己的struct cfs_rq和struct rt_rq.在初始化时就是对这三个结构进行初始化. init_tas

Vue系列---理解Vue.nextTick使用及源码分析(五)

_ 阅读目录 一. 什么是Vue.nextTick()? 二. Vue.nextTick()方法的应用场景有哪些? 2.1 更改数据后,进行节点DOM操作. 2.2 在created生命周期中进行DOM操作. 三. Vue.nextTick的调用方式如下: 四:vm.$nextTick 与 setTimeout 的区别是什么? 五:理解 MutationObserver 六:nextTick源码分析 回到顶部 一. 什么是Vue.nextTick()? 官方文档解释为:在下次DOM更新循环结束之