从框架到完整项目搭建,实战项目《约个球》(3)-为library引入超全的工具类

项目github地址:https://github.com/CameloeAnthony/DatingBall

工具类相信大家都不陌生,在app开发中我们会发现有许多共用的模块和功能,我们可以将以前用到过的一些方法和类写成工具类,在以后的开发中,日积月累,这也能够极大程度的减少我们每次工作的负担。

在日常的开发中用到的工具类也很多,比如说,日期时间,网络请求,app相关信息,SharedPreference等等。github上面也有一些比较优秀的工具类源码,这里推荐几个:

https://github.com/wyouflf/xUtils3   非常出名的Xutil

https://github.com/CommonUtils/android   工具类集合

https://github.com/jingle1267/android-utils  工具类集合


这里分析几个我引入到我的library中的工具类:


1AppUtil:app常用工具类

package com.nsu.library.utils;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.content.*;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Environment;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.inputmethod.InputMethodManager;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.List;

/**
 * Create By Anthony on 2016/1/18
 * 当前类注释:App工具类,获取包名,屏幕宽度等
 */
public class AppUtil {
    /**
     *获取屏幕宽度
     */
    public static int getWidth(Activity context) {
        DisplayMetrics dm = new DisplayMetrics();
        context.getWindowManager().getDefaultDisplay().getMetrics(dm);
        return dm.widthPixels;
    }

    /**
     *获取屏幕高度
     */
    public static int getHeight(Activity context) {
        DisplayMetrics dm = new DisplayMetrics();
        context.getWindowManager().getDefaultDisplay().getMetrics(dm);
        return dm.heightPixels;
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
     */
    public static int px2dip(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }

    /**
     * 根据手机的分辨率从 px(像素) 的单位 转成为 sp
     */
    public static int px2sp(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }

    /**
     * 根据手机的分辨率从 sp(像素) 的单位 转成为 px
     */
    public static int sp2px(Context context, float spValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (spValue * scale + 0.5f);
    }

    /**
     * 获取App安装包信息
     *
     * @return
     */
    public static PackageInfo getPackageInfo(Context context) {
        PackageInfo info = null;
        try {
            info = context.getPackageManager().getPackageInfo(
                    context.getPackageName(), 0);
        } catch (NameNotFoundException e) {
            e.printStackTrace(System.err);
        }
        if (info == null)
            info = new PackageInfo();
        return info;
    }

    public static boolean isStorageExists() {
        if (Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED)) {
            return true;
        }
        return false;
    }

    /**
     *隐藏键盘
     */
    public static void hideKeyboard(Activity activity) {
        try {
            ((InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE))
                    .hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 判断网络是否正常连接
     *
     */
    public static boolean isNetworkConnected(Context context) {
        if(null == context){
            return false;
        }
        // 获取手机所有连接管理对象(包括wifi,net等连接的管理)
        ConnectivityManager connectivityManager = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivityManager != null) {
            // 获取网络连接管理的对象
            NetworkInfo info = connectivityManager.getActiveNetworkInfo();
            if (info != null && info.isConnected()) {
                // 判断当前网络是否已经连接
                if (info.getState() == NetworkInfo.State.CONNECTED) {
                    return true;
                }
            }
        }
        return false;
    }

    /** 没有网络 */
    public static final int NETWORKTYPE_INVALID = 0;
    /** wap网络 */
    public static final int NETWORKTYPE_WAP = 1;
    /** 2G网络 */
    public static final int NETWORKTYPE_2G = 2;
    /** 3G和3G以上网络,或统称为快速网络 */
    public static final int NETWORKTYPE_3G = 3;
    /** wifi网络 */
    public static final int NETWORKTYPE_WIFI = 4;

    /**
     * 获取网络状态,wifi,wap,2g,3g.
     *
     */
    public static int getNetWorkType(Context context) {
        int mNetWorkType = NETWORKTYPE_INVALID;
        ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = manager.getActiveNetworkInfo();
        if (networkInfo != null && networkInfo.isConnected()) {
            String type = networkInfo.getTypeName();
            if (type.equalsIgnoreCase("WIFI")) {
                mNetWorkType = NETWORKTYPE_WIFI;
            } else if (type.equalsIgnoreCase("MOBILE")) {
                String proxyHost = android.net.Proxy.getDefaultHost();
                mNetWorkType = TextUtils.isEmpty(proxyHost)
                        ? (isFastMobileNetwork(context) ? NETWORKTYPE_3G : NETWORKTYPE_2G)
                        : NETWORKTYPE_WAP;
            }
        } else {
            mNetWorkType = NETWORKTYPE_INVALID;
        }
        return mNetWorkType;
    }

    private static boolean isFastMobileNetwork(Context context) {
        TelephonyManager telephonyManager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
        switch (telephonyManager.getNetworkType()) {
            case TelephonyManager.NETWORK_TYPE_1xRTT:
                return false; // ~ 50-100 kbps
            case TelephonyManager.NETWORK_TYPE_CDMA:
                return false; // ~ 14-64 kbps
            case TelephonyManager.NETWORK_TYPE_EDGE:
                return false; // ~ 50-100 kbps
            case TelephonyManager.NETWORK_TYPE_EVDO_0:
                return true; // ~ 400-1000 kbps
            case TelephonyManager.NETWORK_TYPE_EVDO_A:
                return true; // ~ 600-1400 kbps
            case TelephonyManager.NETWORK_TYPE_GPRS:
                return false; // ~ 100 kbps
            case TelephonyManager.NETWORK_TYPE_HSDPA:
                return true; // ~ 2-14 Mbps
            case TelephonyManager.NETWORK_TYPE_HSPA:
                return true; // ~ 700-1700 kbps
            case TelephonyManager.NETWORK_TYPE_HSUPA:
                return true; // ~ 1-23 Mbps
            case TelephonyManager.NETWORK_TYPE_UMTS:
                return true; // ~ 400-7000 kbps
            case TelephonyManager.NETWORK_TYPE_EHRPD:
                return true; // ~ 1-2 Mbps
            case TelephonyManager.NETWORK_TYPE_EVDO_B:
                return true; // ~ 5 Mbps
            case TelephonyManager.NETWORK_TYPE_HSPAP:
                return true; // ~ 10-20 Mbps
            case TelephonyManager.NETWORK_TYPE_IDEN:
                return false; // ~25 kbps
            case TelephonyManager.NETWORK_TYPE_LTE:
                return true; // ~ 10+ Mbps
            case TelephonyManager.NETWORK_TYPE_UNKNOWN:
                return false;
            default:
                return false;
        }
    }

    /*
     * 打开设置网络界面
     */
    public static void setNetworkMethod(final Context context) {
        // 提示对话框
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setCancelable(false);
        try {
            builder.setTitle("网络设置提示")
                    .setMessage("网络连接不可用,是否进行设置?")
                    .setPositiveButton("设置",
                            new DialogInterface.OnClickListener() {

                                @Override
                                public void onClick(DialogInterface dialog,
                                                    int which) {
                                    Intent intent = null;
                                    // 判断手机系统的版本 即API大于10 就是3.0或以上版本
                                    if (android.os.Build.VERSION.SDK_INT > 10) {
                                        intent = new Intent(
                                                android.provider.Settings.ACTION_WIRELESS_SETTINGS);
                                    } else {
                                        intent = new Intent();
                                        ComponentName component = new ComponentName(
                                                "com.android.settings",
                                                "com.android.settings.WirelessSettings");
                                        intent.setComponent(component);
                                        intent.setAction("android.intent.action.VIEW");
                                    }
                                    context.startActivity(intent);
                                }
                            })
                    .setNegativeButton("取消",
                            new DialogInterface.OnClickListener() {

                                @Override
                                public void onClick(DialogInterface dialog,
                                                    int which) {
                                    dialog.dismiss();
                                }
                            }).show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     *得到本地的IP
     */
    public static String getLocalIpAddress() {
        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en
                    .hasMoreElements();) {
                NetworkInterface intf = en.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr
                        .hasMoreElements();) {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (!inetAddress.isLoopbackAddress()) {
                        return inetAddress.getHostAddress().toString();
                    }
                }
            }
        } catch (SocketException ex) {
            Log.e("WifiPreferenceIpAddress", ex.toString());
        }
        return null;
    }

    /**
     * 判断应用是否处于后台状态
     */
    public static boolean isBackground(Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
        if (!tasks.isEmpty()) {
            ComponentName topActivity = tasks.get(0).topActivity;
            if (!topActivity.getPackageName().equals(context.getPackageName())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 复制文本到剪贴板
     */
    public static void copyToClipboard(Context context,String text){
        ClipboardManager cbm = (ClipboardManager) context.getSystemService(Activity.CLIPBOARD_SERVICE);
        cbm.setPrimaryClip(ClipData.newPlainText(context.getPackageName(), text));
    }

    /**
     * 经纬度测距
     */
    public static double distance(double jingdu1, double weidu1, double jingdu2,   double weidu2) {
        double a, b, R;
        R = 6378137; // 地球半径
        weidu1 = weidu1 * Math.PI / 180.0;
        weidu2 = weidu2 * Math.PI / 180.0;
        a = weidu1 - weidu2;
        b = (jingdu1 - jingdu2) * Math.PI / 180.0;
        double d;
        double sa2, sb2;
        sa2 = Math.sin(a / 2.0);
        sb2 = Math.sin(b / 2.0);
        d = 2
                * R
                * Math.asin(Math.sqrt(sa2 * sa2 + Math.cos(weidu1)
                * Math.cos(weidu2) * sb2 * sb2));
        return d;
    }
    /**
     *得到比例图片
     */
    public static Bitmap getScaleBitmap(Bitmap srcBitmap, int dstWidth, int dstHeight) {
        if (srcBitmap == null) {
            return null;
        }
        int bitmapWidth = srcBitmap.getWidth();
        int bitmapHeight = srcBitmap.getHeight();
        float scaleWidth = (float)dstWidth / bitmapWidth;
        float scaleHeight = (float)dstHeight / bitmapHeight;
        float scale;
        if (scaleWidth > scaleHeight) {
            scale = scaleWidth;
        } else {
            scale = scaleHeight;
        }
        Matrix m = new Matrix();
        m.postScale(scale, scale);
        Bitmap bp = Bitmap.createBitmap(srcBitmap, 0, 0, bitmapWidth, bitmapHeight, m, true);
        Bitmap finallBp = Bitmap.createBitmap(bp, 0, 0, dstWidth, dstHeight, null, false);
        if (!bp.isRecycled()) {
            bp.recycle();
            System.gc();
        }
        return finallBp;
    }
}
2 FIleUtil: 文件工具类

package com.nsu.library.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;

import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * Create By Anthony on 2016/1/15
 * 当前类注释:文件工具类,删除和读写文件等
 */
public class FileUtil {

	public static String FILE_WRITING_ENCODING = "UTF-8";

	public static String FILE_READING_ENCODING = "UTF-8";

	private static final String HTTP_PREFIX = "http://";
	private static final String ASSETS_PREFIX = "file://android_assets/";
	private static final String ASSETS_PREFIX2 = "file://android_asset/";
	private static final String ASSETS_PREFIX3 = "assets://";
	private static final String ASSETS_PREFIX4 = "asset://";
	private static final String RAW_PREFIX = "file://android_raw/";
	private static final String RAW_PREFIX2 = "raw://";
	private static final String FILE_PREFIX = "file://";
	private static final String DRAWABLE_PREFIX = "drawable://";
	private static final int HTTP_CONNECTION_TIMEOUT = 4 * 1000;
	private static final int HTTP_READ_TIMEOUT = HTTP_CONNECTION_TIMEOUT * 2;
	/**
	 * 删除文件路径以及底下的子文件和文件夹
	 */
	public static boolean deleteDir(File _path) {
		// 1. to check whether the path exists
		if (!_path.exists()) {
			return false;
		}

		// 2. to delete the files in the path
		if (_path.isDirectory()) {
			// if _path is not a dir,files=null
			File[] files = _path.listFiles();
			File aFile;
			for (int i = 0; i < files.length; i++) {
				aFile = files[i];
				if (aFile.isDirectory()) {
					deleteDir(aFile);
				} else {
					aFile.delete();
				}
			}// endfor
		}

		// 3. to delete the path self
		return _path.delete();
	}

	/**
	 * 删除指定的文件
	 */
	public static boolean deleteFile(String _sFilePathName) {
		File file = new File(_sFilePathName);
		return file.exists() ? file.delete() : false;
	}

	/**
	 * 检查文件是否存在
	 */
	public static boolean fileExists(String _sPathFileName) {
		File file = new File(_sPathFileName);
		return file.exists();
	}

	/**
	 *读文件
     */
	public static String readFile(String _sFileName, String _sEncoding)
			throws Exception {
		FileReader fileReader = null;
		StringBuffer buffContent = null;
		String sLine;

		FileInputStream fis = null;
		BufferedReader buffReader = null;
		if (_sEncoding == null || "".equals(_sEncoding)) {
			_sEncoding = FILE_READING_ENCODING;
		}

		try {
			fis = new FileInputStream(_sFileName);
			buffReader = new BufferedReader(new InputStreamReader(fis,
					_sEncoding));
			boolean zFirstLine = "UTF-8".equalsIgnoreCase(_sEncoding);
			while ((sLine = buffReader.readLine()) != null) {
				if (buffContent == null) {
					buffContent = new StringBuffer();
				} else {
					buffContent.append("\n");
				}
				if (zFirstLine) {
					sLine = removeBomHeaderIfExists(sLine);
					zFirstLine = false;
				}
				buffContent.append(sLine);
			}// end while
			return (buffContent == null ? "" : buffContent.toString());
		} catch (FileNotFoundException ex) {
			throw new Exception("要读取得文件没有找到!", ex);
		} catch (IOException ex) {
			throw new Exception("读文件时错误!", ex);
		} finally {
			// 增加异常时资源的释放
			try {
				if (fileReader != null)
					fileReader.close();
				if (buffReader != null)
					buffReader.close();
				if (fis != null)
					fis.close();
			} catch (Exception ex) {
			}
		}
	}

	/**
	 *写文件
     */
	public static boolean writeFile(String _sFileName, String _sFileContent,
			String _sFileEncoding) throws Exception {
		// 1.创建目录
		// FIXME: 这里获取到的文件名会重复, 也会包含非法字符, 会导致写文件出错
		String sPath = extractFilePath(_sFileName);
		if (!pathExists(sPath)) {
			makeDir(sPath, true);
		}

		String sFileEncoding = (_sFileEncoding == null || "".equals("")) ? FILE_WRITING_ENCODING
				: _sFileEncoding;
		boolean bRet = false;
		FileOutputStream fos = null;
		Writer outWriter = null;
		try {
			fos = new FileOutputStream(_sFileName);
			outWriter = new OutputStreamWriter(fos, sFileEncoding); // 指定编码方式
			outWriter.write(_sFileContent); // 写操作
			bRet = true;
		} catch (Exception ex) {
			// CMyLog.e("FileHelper", "写文件[" + _sFileName + "]发生异常");
			throw new Exception("写文件错误", ex);
		} finally {
			try {
				if (outWriter != null) {
					outWriter.flush();
					outWriter.close();
				}
				if (fos != null)
					fos.close();
			} catch (Exception ex) {
			}
		}
		return bRet;
	}

	/**
	 * 从文件的完整路径名(路径+文件名)中提取 路径(包括:Drive+Directroy )
	 */
	public static String extractFilePath(String _sFilePathName) {
		int nPos = _sFilePathName.lastIndexOf('/');
		if (nPos < 0) {
			nPos = _sFilePathName.lastIndexOf('\\');
		}

		return (nPos >= 0 ? _sFilePathName.substring(0, nPos + 1) : "");
	}

	/**
	 * 从文件的完整路径名(路径+文件名)中提取文件名(包含扩展名) <br>
	 * 如:d:\path\file.ext --> file.ext
	 */
	public static String extractFileName(String _sFilePathName) {
		return extractFileName(_sFilePathName, File.separator);
	}

	/**
	 * 从文件的完整路径名(路径+文件名)中提取文件名(包含扩展名) <br>
	 * 如:d:\path\file.ext --> file.ext
	 */
	public static String extractFileName(String _sFilePathName,
			String _sFileSeparator) {
		int nPos = -1;
		if (_sFileSeparator == null) {
			nPos = _sFilePathName.lastIndexOf(File.separatorChar);
			if (nPos < 0) {
				nPos = _sFilePathName
						.lastIndexOf(File.separatorChar == '/' ? '\\' : '/');
			}
		} else {
			nPos = _sFilePathName.lastIndexOf(_sFileSeparator);
		}

		if (nPos < 0) {
			return _sFilePathName;
		}

		return _sFilePathName.substring(nPos + 1);
	}

	/**
	 * 从文件名或者文件的完整路径中解析出文件的后缀
	 */
	public static String extractFileExt(String _sFilePathName) {
		int nPos = _sFilePathName.lastIndexOf('.');
		return (nPos >= 0 ? _sFilePathName.substring(nPos + 1) : "");
	}

	/**
	 * 检查指定文件的路径是否存在
	 */
	public static boolean pathExists(String _sPathFileName) {
		String sPath = extractFilePath(_sPathFileName);
		return fileExists(sPath);
	}

	/**
	 * 移除字符串中的BOM前缀
	 */
	private static String removeBomHeaderIfExists(String _sLine) {
		if (_sLine == null) {
			return null;
		}
		String line = _sLine;
		if (line.length() > 0) {
			char ch = line.charAt(0);
			// 使用while是因为用一些工具看到过某些文件前几个字节都是0xfffe.
			// 0xfeff,0xfffe是字节序的不同处理.JVM中,一般是0xfeff
			while ((ch == 0xfeff || ch == 0xfffe)) {
				line = line.substring(1);
				if (line.length() == 0) {
					break;
				}
				ch = line.charAt(0);
			}
		}
		return line;
	}


	/**
	 * 从文件的完整路径名(路径+文件名)中提取:主文件名(不包括路径和扩展名)
	 */
	public static String extractMainFileName(String _sFilePathName) {
		String sFileMame = extractFileName(_sFilePathName);
		int nPos = sFileMame.lastIndexOf('.');
		if (nPos > 0) {
			return sFileMame.substring(0, nPos);
		}
		return sFileMame;
	}

	/**
	 *解压
     */
	public static void unzip(String zipFile, String destination)
			throws IOException { // 参数为文件所在路径,比如zipFile
		// 为E:\ABC.ZIP,destination为E:\
		ZipFile zip = new ZipFile(zipFile);
		Enumeration<?> en = zip.entries();
		ZipEntry entry = null;
		byte[] buffer = new byte[8192];
		int length = -1;
		InputStream input = null;
		BufferedOutputStream bos = null;
		File file = null;

		while (en.hasMoreElements()) {
			entry = (ZipEntry) en.nextElement();
			if (entry.isDirectory()) {
				continue;
			}
			input = zip.getInputStream(entry);
			file = new File(destination, entry.getName());
			if (!file.getParentFile().exists()) {
				file.getParentFile().mkdirs();
			}
			bos = new BufferedOutputStream(new FileOutputStream(file));

			while (true) {
				length = input.read(buffer);
				if (length == -1)
					break;
				bos.write(buffer, 0, length);
			}
			bos.close();
			input.close();

		}
		zip.close();
	}

	/** 获取本地文件大小 -1表示不存在 */
	public static long getLocalFileSize(String _filePath) {
		File file = new File(_filePath);
		if (!file.exists()) {
			return -1;
		}

		long size = 0L;
		FileInputStream inputStream = null;
		try {
			inputStream = new FileInputStream(file);
			size = inputStream.available();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				inputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return size;
	}

	/**
	 * 创建目录
	 */
	public static boolean makeDir(String _sDir, boolean _bCreateParentDir) {
		boolean zResult = false;
		File file = new File(_sDir);
		if (_bCreateParentDir)
			zResult = file.mkdirs(); // 如果父目录不存在,则创建所有必需的父目录
		else
			zResult = file.mkdir(); // 如果父目录不存在,不做处理
		if (!zResult)
			zResult = file.exists();
		return zResult;
	}

	/**
	 * 将raw文件拷贝到指定目录
	 */
	public static void copyRawFile(Context ctx, String rawFileName, String to) {
		String[] names = rawFileName.split("\\.");
		String toFile = to + "/" + names[0] + "." + names[1];
		File file = new File(toFile);
		if (file.exists()) {
			return;
		}
		try {
			InputStream is = getStream(ctx, "raw://" + names[0]);
			OutputStream os = new FileOutputStream(toFile);
			int byteCount = 0;
			byte[] bytes = new byte[1024];

			while ((byteCount = is.read(bytes)) != -1) {
				os.write(bytes, 0, byteCount);
			}
			os.close();
			is.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获取各种文件url中的输入流
     */
	public static InputStream getStream(Context context, String url) throws IOException {
		String lowerUrl = url.toLowerCase();

		InputStream is;
		if (lowerUrl.startsWith(HTTP_PREFIX)) {
			is = getHttpStream(url);
		} else if (lowerUrl.startsWith(ASSETS_PREFIX)) {
			String assetPath = url.substring(ASSETS_PREFIX.length());
			is = getAssetsStream(context, assetPath);
		} else if (lowerUrl.startsWith(ASSETS_PREFIX2)) {
			String assetPath = url.substring(ASSETS_PREFIX2.length());
			is = getAssetsStream(context, assetPath);
		} else if (lowerUrl.startsWith(ASSETS_PREFIX3)) {
			String assetPath = url.substring(ASSETS_PREFIX3.length());
			is = getAssetsStream(context, assetPath);
		} else if (lowerUrl.startsWith(ASSETS_PREFIX4)) {
			String assetPath = url.substring(ASSETS_PREFIX4.length());
			is = getAssetsStream(context, assetPath);
		} else if (lowerUrl.startsWith(RAW_PREFIX)) {
			String rawName = url.substring(RAW_PREFIX.length());
			is = getRawStream(context, rawName);
		} else if (lowerUrl.startsWith(RAW_PREFIX2)) {
			String rawName = url.substring(RAW_PREFIX2.length());
			is = getRawStream(context, rawName);
		} else if (lowerUrl.startsWith(FILE_PREFIX)) {
			String filePath = url.substring(FILE_PREFIX.length());
			is = getFileStream(filePath);
		} else if (lowerUrl.startsWith(DRAWABLE_PREFIX)) {
			String drawableName = url.substring(DRAWABLE_PREFIX.length());
			is = getDrawableStream(context, drawableName);
		} else {
			throw new IllegalArgumentException(String.format("Unsupported url: %s \n" +
					"Supported: \n%sxxx\n%sxxx\n%sxxx\n%sxxx", url, HTTP_PREFIX, ASSETS_PREFIX, RAW_PREFIX, FILE_PREFIX));
		}
		return is;
	}

	public static InputStream getRawStream(Context context, String rawName) throws IOException {

		int id = context.getResources().getIdentifier(rawName, "raw", context.getPackageName());
		if (id != 0) {
			try{
				return context.getResources().openRawResource(id);
			} catch (Exception e){
				e.printStackTrace();
			}
		}
		throw new IOException(String.format("raw of id: %s from %s not found", id, rawName));
	}
	public static InputStream getHttpStream(String url) throws IOException {
		URLConnection conn = new URL(url).openConnection();

		conn.setConnectTimeout(HTTP_CONNECTION_TIMEOUT);
		conn.setReadTimeout(HTTP_READ_TIMEOUT);
		conn.connect();
		InputStream is = conn.getInputStream();

		return is;
	}
	public static InputStream getFileStream(String path) throws IOException {
		FileInputStream fis = new FileInputStream(path);
		return fis;
	}

	public static InputStream getAssetsStream(Context context, String path) throws IOException {
		InputStream is = context.getAssets().open(path);
		return is;
	}

	public static InputStream getDrawableStream(Context context, String rawName) throws IOException {

		int id = context.getResources().getIdentifier(rawName, "drawable", context.getPackageName());
		if (id != 0) {
			BitmapDrawable drawable = (BitmapDrawable) context.getResources().getDrawable(id);
			Bitmap bitmap = drawable.getBitmap();

			ByteArrayOutputStream os = new ByteArrayOutputStream();
			bitmap.compress(Bitmap.CompressFormat.PNG, 0, os);
			return new ByteArrayInputStream(os.toByteArray());
		}

		throw new IOException(String.format("bitmap of id: %s from %s not found", id, rawName));
	}

}

3 HttpUtil: 网络请求工具类

<span style="font-size:14px;">package com.nsu.library.utils;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.message.BasicHeader;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * Create By Anthony on 2016/1/17
 * 当前类注释:Http get 和post请求的工具类
 *
 */
public class HttpUtil {

    private static final String TAG = "HttpHelper";

    /**
     * 连接超时的时间
     */
    public static int TIMEOUT_CONNECTION = 40000;

    /**
     * 读超时的时间
     */
    public static int TIMEOUT_SOCKET = 60000;

    /**
     * 发出get请求
     */
    public static String doGet(String sUrl) throws ClientProtocolException, IOException {
        return doGet(sUrl, TIMEOUT_CONNECTION, TIMEOUT_SOCKET);
    }


    public static String doGet(String sUrl, int nTimeout) throws ClientProtocolException,
			IOException {
        return doGet(sUrl, nTimeout, nTimeout);
    }


    public static String doGet(String sUrl, int nTimeoutConn, int nTimeoutSocket)
            throws ClientProtocolException, IOException {
        if (StringUtil.isEmpty(sUrl)) {
            return null;
        }

        String sResult = null;

        Log.d(TAG, "开始请求:" + sUrl);

        HttpGet httpRequest = new HttpGet(sUrl);
        HttpParams httpParams = new BasicHttpParams();

        // 设置超时时间
        HttpConnectionParams.setConnectionTimeout(httpParams, nTimeoutConn);
//        HttpConnectionParams.setSoTimeout(httpParams, nTimeoutSocket);

        DefaultHttpClient httpClient = new DefaultHttpClient(httpParams);
        httpClient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler());
        HttpResponse httpResponse = httpClient.execute(httpRequest);

        // 请求成功
        if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            Log.d(TAG, "请求成功:" + sUrl);

            sResult = EntityUtils.toString(httpResponse.getEntity(), HTTP.UTF_8);

            Log.d(TAG, sUrl + "返回內容:" + sResult);

        } else {
            Log.w(TAG, "请求失败:" + sUrl);
        }

        httpClient.getConnectionManager().shutdown();

        return sResult;
    }


    public static String doPost(String url, String params) throws ClientProtocolException, IOException {
        return doPost(url, params, TIMEOUT_CONNECTION, TIMEOUT_SOCKET);
    }


    public static String doPost(String url, String params, int nTimeout) throws ClientProtocolException, IOException {
        return doPost(url, params, nTimeout, nTimeout);
    }


    public static String doPost(String sUrl, String params, int nTimeoutConn, int nTimeoutSocket)
            throws ClientProtocolException, IOException {

        if (StringUtil.isEmpty(sUrl)) {
            return null;
        }

        params = params == null? "": params;

        String sResult = null;

        // HttpPost连接对象
        HttpPost httpRequest = new HttpPost(sUrl);

        HttpParams httpParams = new BasicHttpParams();
        HttpConnectionParams.setConnectionTimeout(httpParams, nTimeoutConn);
        HttpConnectionParams.setSoTimeout(httpParams, nTimeoutSocket);

        httpRequest.setHeader(new BasicHeader("Content-type", "application/json"));

        httpRequest.setEntity((new ByteArrayEntity(params.getBytes())));

        // 取得默认的HttpClient
        HttpClient httpClient = new DefaultHttpClient();

        // 取得HttpResponse
        HttpResponse httpResponse = httpClient.execute(httpRequest);

        // httpstatus.sc_ok 表示连接成功
        if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            Log.d(TAG, "请求成功:" + sUrl);

            sResult = EntityUtils.toString(httpResponse.getEntity());

            Log.d(TAG, sUrl + "返回內容:" + sResult);
        }

        return sResult;
    }

    /**
     *  url 转换为bitmap
     */
    public static Bitmap uRl2Bitmap(String uriPic) {
        URL imageUrl = null;
        Bitmap bitmap = null;
        try {
            /* new URL对象将网址传入 */
            imageUrl = new URL(uriPic);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        try {
            /* 取得联机 */
            HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
            conn.connect();
            /* 取得回传的InputStream */
            InputStream is = conn.getInputStream();
            /* 将InputStream变成Bitmap */
            bitmap = BitmapFactory.decodeStream(is);
            /* 关闭InputStream */
            is.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
        return bitmap;
    }

}
</span>

4 LogUtil: 日志打印工具类

package com.nsu.library.utils;
/**
 * Create By Anthony on 2016/1/15
 * 当前类注释:重写系统日志管理类
 * 使用方法:还是和平时Log.v(key,value)这样使用,需要导入当前类,该类会打印比系统更多的日志信息,
 * 例如:类名称,当前运行的方法,行数,和日志信息 .在app发布的时候将INNER_SHOW_LOG置为false,将不
 * 会打印任何日志信息,保护app隐私。
 */
public class LogUtil {

	private static final boolean INNER_SHOW_LOG = true;

	public static void v(String tag,String msg)
	{
		if(INNER_SHOW_LOG){
			StackTraceElement ste = new Throwable().getStackTrace()[1];
			String traceInfo = ste.getClassName() + "::";
			traceInfo += ste.getMethodName();
			traceInfo += "@" + ste.getLineNumber() + ">>>";
			android.util.Log.v(tag, traceInfo+msg);
		}
	}

	public static void v(String tag, String message, Throwable t){
		if(INNER_SHOW_LOG) android.util.Log.v(tag, message, t);
	}

	public static void d(String tag, String msg){
		if(INNER_SHOW_LOG){
			StackTraceElement ste = new Throwable().getStackTrace()[1];
			String traceInfo = ste.getClassName() + "::";
			traceInfo += ste.getMethodName();
			traceInfo += "@" + ste.getLineNumber() + ">>>";
			android.util.Log.d(tag, traceInfo+msg);
		}
	}

	public static void d(String tag, String message, Throwable t){
		if(INNER_SHOW_LOG) android.util.Log.d(tag, message,t);
	}

	public static void i(String tag, String msg){
		if(INNER_SHOW_LOG){
			StackTraceElement ste = new Throwable().getStackTrace()[1];
			String traceInfo = ste.getClassName() + "::";
			traceInfo += ste.getMethodName();
			traceInfo += "@" + ste.getLineNumber() + ">>>";
			android.util.Log.i(tag, traceInfo+msg);
		}
	}

	public static void i(String tag, String message, Throwable t){
		if(INNER_SHOW_LOG) android.util.Log.i(tag, message, t);
	}

	public static void w(String tag, String msg){
		if(INNER_SHOW_LOG){
			StackTraceElement ste = new Throwable().getStackTrace()[1];
			String traceInfo = ste.getClassName() + "::";
			traceInfo += ste.getMethodName();
			traceInfo += "@" + ste.getLineNumber() + ">>>";
			android.util.Log.w(tag, traceInfo+msg);
		}
	}

	public static void w(String tag, String message, Throwable t){
		if(INNER_SHOW_LOG) android.util.Log.w(tag, message, t);
	}

	public static void e(String tag, String msg){
		if(INNER_SHOW_LOG){
			StackTraceElement ste = new Throwable().getStackTrace()[1];
			String traceInfo = ste.getClassName() + "::";
			traceInfo += ste.getMethodName();
			traceInfo += "@" + ste.getLineNumber() + ">>>";
			android.util.Log.e(tag, traceInfo+msg);
		}
	}
	public static void e(String tag, String message, Throwable t){
		if(INNER_SHOW_LOG) android.util.Log.e(tag, message, t);
	}
}


5 PropToHash Util: 将properties文件转化为hashmap的工具类

package com.nsu.library.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;

import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;

/**
 * Create By Anthony on 2016/1/15
 * 当前类注释:properties 处理成HashMap
 *
 */
public class PropToHashUtil {

    private static final String HTTP_PREFIX = "http://";
    private static final String ASSETS_PREFIX = "file://android_assets/";
    private static final String ASSETS_PREFIX2 = "file://android_asset/";
    private static final String ASSETS_PREFIX3 = "assets://";
    private static final String ASSETS_PREFIX4 = "asset://";
    private static final String RAW_PREFIX = "file://android_raw/";
    private static final String RAW_PREFIX2 = "raw://";
    private static final String FILE_PREFIX = "file://";
    private static final String DRAWABLE_PREFIX = "drawable://";
    private static final int HTTP_CONNECTION_TIMEOUT = 4 * 1000;
    private static final int HTTP_READ_TIMEOUT = HTTP_CONNECTION_TIMEOUT * 2;
    /**
     * properties 处理成HashMap
     */
    public static HashMap<String, String> simpleProperty2HashMap(Context context, String path){
        try {
            InputStream is = FileUtil.getStream(context, path);
            HashMap<String, String> map = simpleProperty2HashMap(is);
            return map;
        } catch (IOException e) {
            e.printStackTrace();
        }

        return new HashMap<String, String>();
    }
    /**
     * properties 处理成HashMap
     */
    private static HashMap<String, String> simpleProperty2HashMap(InputStream in) throws IOException {
        HashMap<String, String> hashMap = new HashMap<String, String>();
        Properties properties = new Properties();
        properties.load(in);
        in.close();
        Set keyValue = properties.keySet();
        for (Iterator it = keyValue.iterator(); it.hasNext();){
            String key = (String) it.next();
            hashMap.put(key, (String) properties.get(key));
        }
        return hashMap;
    }



}


6 SharedPreferenceUtil: Sp的封装工具类

package com.nsu.library.utils;

import android.content.Context;
import android.content.SharedPreferences;

/**
 * Create By Anthony on 2016/1/15
 * 当前类注释:为SharedPerferences进行封装基本的方法,SharedPerferences已经封装成单例模式
 * 可以通过SharedPreferences sp=SharedPreferencesHelper.getInstances(AbsApplication.getInstance())进行获取当前对象
 * sp.putStringValue(key,value)进行使用
 */
public class SharedPreferenceUtil {
    private static final String SHARED_PATH = "mine_shared";
    private static SharedPreferenceUtil instance;
    private SharedPreferences sp;
    private SharedPreferences.Editor editor;

    public static SharedPreferenceUtil getInstance(Context context) {
        if (instance == null && context != null) {
            instance = new SharedPreferenceUtil(context);
        }
        return instance;
    }

    private SharedPreferenceUtil(Context context) {
        sp = context.getSharedPreferences(SHARED_PATH, Context.MODE_PRIVATE);
        editor = sp.edit();
    }

    public long getLongValue(String key) {
        if (key != null && !key.equals("")) {
            return sp.getLong(key, 0);
        }
        return 0;
    }

    public String getStringValue(String key) {
        if (key != null && !key.equals("")) {
            return sp.getString(key, null);
        }
        return null;
    }

    public int getIntValue(String key) {
        if (key != null && !key.equals("")) {
            return sp.getInt(key, 0);
        }
        return 0;
    }

    public int getIntValueByDefault(String key)
    {
        if (key != null && !key.equals("")) {
            return sp.getInt(key, 0);
        }
        return 0;
    }
    public boolean getBooleanValue(String key) {
        if (key != null && !key.equals("")) {
            return sp.getBoolean(key, false);
        }
        return true;
    }

    public float getFloatValue(String key) {
        if (key != null && !key.equals("")) {
            return sp.getFloat(key, 0);
        }
        return 0;
    }

    public void putStringValue(String key, String value) {
        if (key != null && !key.equals("")) {
            editor = sp.edit();
            editor.putString(key, value);
            editor.commit();
        }
    }

    public void putIntValue(String key, int value) {
        if (key != null && !key.equals("")) {
            editor = sp.edit();
            editor.putInt(key, value);
            editor.commit();
        }
    }

    public void putBooleanValue(String key, boolean value) {
        if (key != null && !key.equals("")) {
            editor = sp.edit();
            editor.putBoolean(key, value);
            editor.commit();
        }
    }

    public void putLongValue(String key, long value) {
        if (key != null && !key.equals("")) {
            editor = sp.edit();
            editor.putLong(key, value);
            editor.commit();
        }
    }

    public void putFloatValue(String key, Float value) {
        if (key != null && !key.equals("")) {
            editor = sp.edit();
            editor.putFloat(key, value);
            editor.commit();
        }
    }
}


7 StringUtil: 常用字符串工具类

package com.nsu.library.utils;

import android.text.TextUtils;

import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Create By Anthony on 2016/1/15
 * 当前类注释:String工具类
 */
public class StringUtil {
    /**
     * 判断指定字符串是否为空
     * 
     * @param string
     *            指定的字符串
     * @return 若字符串为空对象(_string==null)或空串(长度为0),则返回true;否则,返回false.
     */
    public static boolean isEmpty(String string) {
        return ((string == null) || (string.trim().length() == 0));
    }

	public static boolean isWebPage(String url){
		if(url == null){
			return false;
		}

		url = url.toLowerCase();
		return url.contains(".jsp") ||
				url.contains(".php") ||
				url.contains(".html") ||
				url.contains(".do") ||
				url.contains("?");
	}

    /**
     * 返回string里面的所有url
     */
    public static ArrayList<String> getUrlsFromString(String data) {
        if (TextUtils.isEmpty(data)) {
            return null;
        }

        ArrayList<String> urls = new ArrayList<String>();
        Pattern pattern = Pattern
                .compile("(http://|https://){1}[\\w\\.\\-/:]+");
        Matcher matcher = pattern.matcher(data);
        while (matcher.find()) {
            urls.add(matcher.group());
            System.out.println("url from json:" + matcher.group());
        }

        return urls;
    }

    public static boolean isImgUrl(String url){
        if(url.endsWith("jpg")|| url.endsWith("jpeg") || url.endsWith("png")|| url.endsWith("bmp")|| url.endsWith("gif")){
            return true;
        }
        return false;
    }
}
8 TimeDateUtil: 日期时间工具类
package com.nsu.library.utils;

import android.text.TextUtils;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Create By Anthony on 2016/1/15
 * 当前类注释:时间和日期工具类
 */
public class TimeDateUtil {
    /**
     *得到当前时间
     */
    public static String getCurrentTime() {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);
        int second = calendar.get(Calendar.SECOND);

        return String.format("%04d-%02d-%02d %02d:%02d:%02d", year, month + 1, day, hour, minute,
                second);
    }

    /** 得到当前的年.月.日 */
    public static String getCurrentDate() {
        Date date = new Date(System.currentTimeMillis());
        SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd");
        return format.format(date);
    }

    /** 字节转换成kb Mb Gb */
    public static String byteFormat(long _byte) {
        if ((_byte >> 10) < 1) {
            return _byte + "b";
        } else if ((_byte >> 20) < 1) {
            return String.format("%.2f", (float) _byte / (1024)) + "K";
        } else if ((_byte >> 30) < 1) {
            return String.format("%.2f", (float) _byte / (1024 * 1024)) + "M";
        }
        return String.format("%.2f", (float) _byte / (1024 * 1024 * 1024)) + "G";
    }

    /** 0代表星期一,6代表星期天 */
    public static int getCurrentWeekDay() {
        Date date = new Date(System.currentTimeMillis());
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int index = calendar.get(Calendar.DAY_OF_WEEK) - 2; // Java默认从星期天开始
        if (index == -1) {
            index = 6;
        }
        return index;
    }

    /** 从00:00到现在的分钟 */
    public static int getCurrentMinuteInDay() {
        Date date = new Date(System.currentTimeMillis());
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int mimute = calendar.get(Calendar.MINUTE);
        return hour * 60 + mimute;

    }

    /** 将hh:mm转化成分钟 */
    public static int getTotalMinute(String _time) {
        String[] array = _time.trim().split(":");
        int hour = Integer.parseInt(array[0]);
        int mimute = Integer.parseInt(array[1]);
        return hour * 60 + mimute;
    }

    /** _time以毫秒为单位 ,转换成hh:mm:ss的形式 */
    public static String translateLongToTime(long _time) {
        _time = _time / 1000; // 转换成秒
        if (_time < 60) {
            return "00:" + String.format("%02d", _time);
        }
        long temp = _time / 60;
        if (temp < 60) {
            return String.format("%02d", temp) + ":" + String.format("%02d", _time % 60);
        }
        return String.format("%02d", temp / 60) + ":" + String.format("%02d", temp % 60) + ":"
                + String.format("%02d", _time % 60);
    }

    /**
     * 返回系统当前时间
     */
    public static long getNowTime() {
        return System.currentTimeMillis();
    }

    private static final long ONE_MINUTE = 60000L;
    private static final long ONE_HOUR = 3600000L;
    private static final long ONE_DAY = 86400000L;
    private static final long ONE_WEEK = 604800000L;

    private static final String ONE_SECOND_AGO = "秒前";
    private static final String ONE_MINUTE_AGO = "分钟前";
    private static final String ONE_HOUR_AGO = "小时前";
    private static final String ONE_DAY_AGO = "天前";
    private static final String ONE_MONTH_AGO = "月前";
    private static final String ONE_YEAR_AGO = "年前";

    /**
     *将传入的时间转化为**分钟前,**天前。这种形式
     */
    public static String format(long millis) {
        long delta = System.currentTimeMillis() - millis;
        if (delta < 1L * ONE_MINUTE) {
//            long seconds = toSeconds(delta);
//            return (seconds <= 0 ? 1 : seconds) + ONE_SECOND_AGO;
            return 1 + ONE_MINUTE_AGO;
        }
        if (delta < 45L * ONE_MINUTE) {
            long minutes = toMinutes(delta);
            return (minutes <= 0 ? 1 : minutes) + ONE_MINUTE_AGO;
        }
        if (delta < 24L * ONE_HOUR) {
            long hours = toHours(delta);
            return (hours <= 0 ? 1 : hours) + ONE_HOUR_AGO;
        }
        if (delta < 48L * ONE_HOUR) {
            return "昨天";
        }
        if (delta < 30L * ONE_DAY) {
            long days = toDays(delta);
            return (days <= 0 ? 1 : days) + ONE_DAY_AGO;
        }
        if (delta < 12L * 4L * ONE_WEEK) {
            long months = toMonths(delta);
            return (months <= 0 ? 1 : months) + ONE_MONTH_AGO;
        } else {
            long years = toYears(delta);
            return (years <= 0 ? 1 : years) + ONE_YEAR_AGO;
        }
    }

    private static long toSeconds(long date) {
        return date / 1000L;
    }

    private static long toMinutes(long date) {
        return toSeconds(date) / 60L;
    }

    private static long toHours(long date) {
        return toMinutes(date) / 60L;
    }

    private static long toDays(long date) {
        return toHours(date) / 24L;
    }

    private static long toMonths(long date) {
        return toDays(date) / 30L;
    }

    private static long toYears(long date) {
        return toMonths(date) / 365L;
    }

}

9异常捕获的工具类

package com.nsu.library.utils;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Environment;

import java.io.*;
import java.util.Calendar;
import java.util.Locale;

/**
 * Create By Anthony on 2016/1/16
 * 当前类注释:异常处理类,将我们的异常信息保存到本地SD卡上面或者上传到服务器
 */
public class UncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
	private static final boolean DEBUG =true;
	private static final String TAG ="UncaughtExceptionHandler";
	private Context mContext;
	private Thread.UncaughtExceptionHandler mDefaultHandler;

	public UncaughtExceptionHandler(Context context, Thread.UncaughtExceptionHandler defaultHandler){
		this.mDefaultHandler = defaultHandler;
		this.mContext = context;
	}

	@Override
	public void uncaughtException(Thread thread, Throwable ex) {
		LogUtil.e("Crash", "Application crash", ex);
		writeFile(thread, ex);//将异常信息保存到SD卡上面
		//TODO 在这里写方法将异常信息上传到服务器
		mDefaultHandler.uncaughtException(thread, ex);
	}

	private void writeFile(final Thread thread, final Throwable ex){
		//如果SD卡不存在则无法写入
		if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
			if(DEBUG){
				LogUtil.w(TAG,"SDCard unmounted, skip write exception to file");
				return ;
			}
		}
		try {
			OutputStream os = getLogStream();
			os.write(getExceptionInformation(thread, ex).getBytes("utf-8"));
			os.flush();
			os.close();

			android.os.Process.killProcess(android.os.Process.myPid());
		}
		catch(Exception e){
			e.printStackTrace();
		}
	}

	private OutputStream getLogStream() throws IOException {

		//crash_log_pkgname.log
		String fileName = String.format("crash_%s.log", mContext.getPackageName());
		File file  = new File(Environment.getExternalStorageDirectory(), fileName);

		if(!file.exists()){
			file.createNewFile();
		}

		OutputStream os = new FileOutputStream(file, true);

		return os;
	}



	private String getExceptionInformation(Thread thread, Throwable ex){
		long current = System.currentTimeMillis();
		StringBuilder sb = new StringBuilder().append('\n');
		sb.append("THREAD: ").append(thread).append('\n');
		sb.append("BOARD: ").append(Build.BOARD).append('\n');
		sb.append("BOOTLOADER: ").append(Build.BOOTLOADER).append('\n');
		sb.append("BRAND: ").append(Build.BRAND).append('\n');
		sb.append("CPU_ABI: ").append(Build.CPU_ABI).append('\n');
		sb.append("CPU_ABI2: ").append(Build.CPU_ABI2).append('\n');
		sb.append("DEVICE: ").append(Build.DEVICE).append('\n');
		sb.append("DISPLAY: ").append(Build.DISPLAY).append('\n');
		sb.append("FINGERPRINT: ").append(Build.FINGERPRINT).append('\n');
		sb.append("HARDWARE: ").append(Build.HARDWARE).append('\n');
		sb.append("HOST: ").append(Build.HOST).append('\n');
		sb.append("ID: ").append(Build.ID).append('\n');
		sb.append("MANUFACTURER: ").append(Build.MANUFACTURER).append('\n');
		sb.append("MODEL: ").append(Build.MODEL).append('\n');
		sb.append("PRODUCT: ").append(Build.PRODUCT).append('\n');
		sb.append("SERIAL: ").append(Build.SERIAL).append('\n');
		sb.append("TAGS: ").append(Build.TAGS).append('\n');
		sb.append("TIME: ").append(Build.TIME).append(' ').append(toDateString(Build.TIME)).append('\n');
		sb.append("TYPE: ").append(Build.TYPE).append('\n');
		sb.append("USER: ").append(Build.USER).append('\n');
		sb.append("VERSION.CODENAME: ").append(Build.VERSION.CODENAME).append('\n');
		sb.append("VERSION.INCREMENTAL: ").append(Build.VERSION.INCREMENTAL).append('\n');
		sb.append("VERSION.RELEASE: ").append(Build.VERSION.RELEASE).append('\n');
		sb.append("VERSION.SDK_INT: ").append(Build.VERSION.SDK_INT).append('\n');
		sb.append("LANG: ").append(mContext.getResources().getConfiguration().locale.getLanguage()).append('\n');
		sb.append("APP.VERSION.NAME: ").append(getVersionName()).append('\n');
		sb.append("APP.VERSION.CODE: ").append(getVersionCode()).append('\n');
		sb.append("CURRENT: ").append(current).append(' ').append(toDateString(current)).append('\n');

		sb.append(getErrorInformation(ex));

		return sb.toString();
	}

	private String getVersionName(){
		PackageManager packageManager = mContext.getPackageManager();
		PackageInfo packInfo = null;
		try {
			packInfo = packageManager.getPackageInfo(mContext.getPackageName(),0);
		} catch (PackageManager.NameNotFoundException e) {
			e.printStackTrace();
		}
		String version = packInfo.versionName;

		return version;
	}

	private int getVersionCode(){
		PackageManager packageManager = mContext.getPackageManager();
		PackageInfo packInfo = null;
		try {
			packInfo = packageManager.getPackageInfo(mContext.getPackageName(),0);
		} catch (PackageManager.NameNotFoundException e) {
			e.printStackTrace();
		}
		int version = packInfo.versionCode;

		return version;
	}


	private String getErrorInformation(Throwable t){
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		PrintWriter writter = new PrintWriter(baos);
		t.printStackTrace(writter);
		writter.flush();
		String result = new String(baos.toByteArray());
		writter.close();

		return result;
	}

	private String toDateString(long timeMilli){
		Calendar calc = Calendar.getInstance();
		calc.setTimeInMillis(timeMilli);
		return String.format(Locale.CHINESE, "%04d.%02d.%02d %02d:%02d:%02d:%03d",
				calc.get(Calendar.YEAR), calc.get(Calendar.MONTH) + 1, calc.get(Calendar.DAY_OF_MONTH),
				calc.get(Calendar.HOUR_OF_DAY), calc.get(Calendar.MINUTE), calc.get(Calendar.SECOND), calc.get(Calendar.MILLISECOND));
	}

}
好了。这里引入的是我在工作和学习中遇到的一些工具类,以后会根据情况进行添加。第9个工具类的用法在上面一篇文章中已经分析过了,可以点击这里:

从框架到完整项目搭建,实战项目《约个球》(2)-框架搭建之使用CrashHandler来获取应用的Crash信息
在后面的项目中我们也会引入Xutil来极大程度的减轻开发的难度。


你可能感兴趣的:(github,工具类,library)