Util.java,使用最广泛~
代码中很多地方,都写了注释说明~基本不需要怎么解释了~
package net.micode.fileexplorer.util;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.FilenameFilter;import java.io.IOException;import java.text.DateFormat;import java.util.ArrayList;import java.util.Date;import java.util.HashSet;import net.micode.fileexplorer.FileViewActivity;import net.micode.fileexplorer.GlobalConsts;import net.micode.fileexplorer.R;import net.micode.fileexplorer.model.FavoriteItem;import net.micode.fileexplorer.model.FileInfo;import android.app.Notification;import android.app.NotificationManager;import android.app.PendingIntent;import android.content.Context;import android.content.Intent;import android.content.pm.ApplicationInfo;import android.content.pm.PackageInfo;import android.content.pm.PackageManager;import android.graphics.drawable.Drawable;import android.os.Environment;import android.util.Log;import android.view.ActionMode;import android.view.View;import android.widget.TextView;/**工具类,包含了很多通用的工具方法,被项目中的很多类调用。*/public class Util { //这个文件夹里面存储的内容是app2sd产生的文件夹,也就是是你手机上所有安装到SD卡的应用程序的缓存文件夹。 //androidsecure文件夹可以删除吗? //如果删除之后,软件不能正常使用,和系统没有关系。 //删的话除了会可能导致移动至sd卡的程序损坏,数据丢失,并不会造成什么严重后果。只要把移动到sd卡的损坏程序卸载,重装,手机就完全没有损伤,文件夹也会在再次app2sd时自动重建的。 private static String ANDROID_SECURE = "/mnt/sdcard/.android_secure"; //android.util.Log.log第1个参数,用到“tag”,和log4j中Logger.getLogger(getClass())用法不太一样 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) { //Android系统为我们提供了很多服务管理类,包括ActivityManager、PowerManager(电源管理)、AudioManager(音频管理)。 //PackageManager主要是管理应用程序包,通过它就可以获取应用程序信息 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 getDefaultFavorites(Context context) { ArrayList list = new ArrayList (); 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); notification.setLatestEventInfo(context, title, body, contentIntent); 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(); } } } //MimeType public static HashSet sDocMimeTypesSet = new HashSet () { { add("text/plain"); add("text/plain"); add("application/pdf"); add("application/msword"); add("application/vnd.ms-excel"); add("application/vnd.ms-excel"); } }; public static String sZipFileMimeType = "application/zip"; public static int CATEGORY_TAB_INDEX = 0; public static int SDCARD_TAB_INDEX = 1;}
遇到一个奇怪的问题,为了验证某个函数,写了个main函数执行,结果发生了奇葩事项~
在Java环境下的工程中执行以下代码,正常输出。
public class Test { public static void main(String[] args) { System.out.println(getNameFromFilename("C:/a/b/c.png")); } public static String getNameFromFilename(String filename) { int dotPosition = filename.lastIndexOf('.'); if (dotPosition != -1) { return filename.substring(0, dotPosition); } return ""; }}
打印“C:/a/b/c”
在Android环境下的工程中,竟然直接把JVM搞崩溃了,不明所以啊~
Invalid layout of java.lang.String at value
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (javaClasses.cpp:129), pid=8236, tid=3188
# fatal error: Invalid layout of preloaded class
#
# JRE version: 7.0_17-b02
# Java VM: Java HotSpot(TM) 64-Bit Server VM (23.7-b01 mixed mode windows-amd64 compressed oops)
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# J:\AndroidCenter\MiCodeFileExplorer\hs_err_pid8236.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.sun.com/bugreport/crash.jsp
#