在平时的项目开发中,总有那么一个包是必不可少的。我要说的就是utils包。没了这个,代码怎么公用,功能怎么公用,所谓磨刀不误砍柴工,充分的准备是快速开发的前提。utils包对项目而言,就像人体的肺,没了肺,怎么呼吸?今天,老夫就将我珍藏多年的...,不是,积累的工具类我替你总结了,看你手指精奇,是个写程序的奇才,拿走不谢,持续更新中。
啥也不说了,先上效果图:
文件列表
1.Bitmap处理工具类:包括bitmap保存本地;bytebuffer转bitmap;对bitmap高效高斯模糊;bitmap二次采样;bitmap图片压缩;
public class BitmapUtils {
/**
* 将bitmap保存为文件
* @param bitmap
* @param file
* @return
*/
public static boolean bitmapToFile(Bitmap bitmap, File file) {
try {
if (!file.exists()) {
file.createNewFile();
}
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
return true;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
/**
* 将byteBuffer转为Bitmap
* @param byteBuffer
* @param width
* @param height
* @return
*/
public static Bitmap byteBufferToBitmap(ByteBuffer byteBuffer, int width, int height) {
IntBuffer intBuffer = byteBuffer.asIntBuffer();
final int[] ret = new int[byteBuffer.limit() / 4];
IntBuffer retBuffer = IntBuffer.wrap(ret);
retBuffer.put(intBuffer);
for (int i = 0; i < ret.length; i++) {
int src = ret[i];
int dest = (src & 0xFF) << 24 | (src & 0xFF000000) >> 8 | (src & 0xFF0000) >> 8 | (src & 0xFF00) >> 8;
ret[i] = dest;
}
Bitmap bitmap = Bitmap.createBitmap(ret, width, height, Bitmap.Config.ARGB_8888);
return bitmap;
}
/**
* 高效率Bitmap高斯模糊
* 还需在build.gradle加入 defaultConfig {
renderscriptTargetApi 19
renderscriptSupportModeEnabled true
}
* @param context
* @param ivBlurBg
* @param bitmap
* param scaleRatio bitmap分辨率缩小比例,计算速度更快,范围 1-10
*
*/
public static void bitmapBlur(Context context, ImageView ivBlurBg, Bitmap bitmap, int scaleRatio){
int x = (int) ivBlurBg.getX();
int y = (int) ivBlurBg.getY();
int bitmapX = bitmap.getWidth();
int bitmapY = bitmap.getHeight();
Bitmap bitmapNew = Bitmap.createBitmap(bitmap,x,y,bitmapX-x,bitmapY-y);
if(bitmap != null){
Bitmap overlay = Bitmap.createScaledBitmap(bitmapNew, bitmapNew.getWidth() / scaleRatio, bitmapNew.getHeight() / scaleRatio, false);
overlay = handleGlassblur(context,overlay,15);
ivBlurBg.setImageBitmap(overlay);
}
bitmap.recycle();
}
public static Bitmap handleGlassblur(Context context, Bitmap originBitmap, int radius){
RenderScript renderScript = RenderScript.create(context);
Allocation input = Allocation.createFromBitmap(renderScript,originBitmap);
Allocation output = Allocation.createTyped(renderScript,input.getType());
ScriptIntrinsicBlur scriptIntrinsicBlur = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript));
scriptIntrinsicBlur.setRadius(radius);
scriptIntrinsicBlur.setInput(input);
scriptIntrinsicBlur.forEach(output);
output.copyTo(originBitmap);
return originBitmap;
}
/**
* 根据指定的宽、高,对图片进行二次采样
* @param bytes
* @return
*/
public static Bitmap ScaleBitmap(byte[] bytes,int width,int height){
//获取图片的解码参数设置
BitmapFactory.Options options = new BitmapFactory.Options();
//设置为true仅仅解码图片的边缘
options.inJustDecodeBounds = true;
//对图片进行解码,如果指定了inJustDecodeBounds=true,decodeByteArray将返回为空
BitmapFactory.decodeByteArray(bytes,0,bytes.length,options);
int outWidth = options.outWidth;
int outHeight = options.outHeight;
int sampleSizeX = width/outWidth;
int sampleSizeY = height/outHeight;
int simpleSize = sampleSizeX < sampleSizeY ? sampleSizeX : sampleSizeY;
//设置inJustDecodeBounds为false重新将图片读进内存中
options.inJustDecodeBounds = false;
//实际要进行缩放的比例
options.inSampleSize = simpleSize;
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
}
/**
* 图片质量压缩
* @param bitmap 需要质量压缩的图片
* @param size 指定最大要压缩成的大小,单位为k
* @return
*/
public static Bitmap compressBitmap(Bitmap bitmap,int size){
ByteArrayOutputStream bos = new ByteArrayOutputStream();
//将压缩后的数据放入bos中
bitmap.compress(Bitmap.CompressFormat.JPEG,100,bos);
int quality = 100;
while(bos.toByteArray().length / 1024 > size){
//循环判断如果压缩后的图片大于100k,则清空bos,质量压缩比减小10%
bos.reset();
quality -= 10;
bitmap.compress(Bitmap.CompressFormat.JPEG,quality,bos);
}
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
//通过字节输入流转为bitmap
return BitmapFactory.decodeStream(bis,null,null);
}
}
2.万能接口回调类,一个类能回调任何数据类型,从此不需要再创建其他单一回调接口。
public abstract class CallBackimpl implements IcallBack{
@Override
public void callBack(List datas) {
}
@Override
public void callBack(List list, boolean charge) {
}
@Override
public void callBack(String str) {
}
@Override
public void callBack(String str, int code) {
}
@Override
public void callBack(byte[] bytes) {
}
@Override
public void callBack(Bitmap bitmap) {
}
@Override
public void confirmHandle() {
}
@Override
public void callBack(int progress) {
}
@Override
public void callBack(float num) {
}
@Override
public void callBack(int page,int subpage) {
}
@Override
public void callBack(boolean boo) {
}
@Override
public void callBack(JSONObject obj) {
}
@Override
public void callBack(String... args) {
}
@Override
public void onFail() {
}
}
3.异常崩溃处理类:当程序发生未处理异常时,该类将版本号,版本名,设备号,Android版本,生产信息进行记录日志并发送至服务器。
public class CrashHandler implements Thread.UncaughtExceptionHandler{
private Thread.UncaughtExceptionHandler exceptionHandler;
private MyApp myApp;
/** 错误日志保存名称 */
private Map<String, String> infos = new HashMap<>();
/** 错误日志文件名 */
private final String LOGFILE_NAME = FileUtils.getCacheDir() + "crash.txt";
public CrashHandler(MyApp myApp){
exceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
this.myApp = myApp;
}
/**
* 当未捕获的异常发生时会传入此方中处理
* @param thread
* @param ex
*/
@Override
public void uncaughtException(Thread thread, Throwable ex) {
if(!handException(ex) && exceptionHandler != null){
exceptionHandler.uncaughtException(thread,ex);
}else{
//异常处理并结束程序
android.os.Process.killProcess(android.os.Process.myPid());
}
}
/**
* 异常处理方法,处理了返回true,未处理返回false
* @param ex 异常
* @return
*/
private boolean handException(final Throwable ex){
if(ex == null) return true;
ex.printStackTrace();
Toast.makeText(myApp, "应用发生异常,即将退出!", Toast.LENGTH_LONG).show();
collectVersionInfo(myApp);
collectDeviceInfo();
saveCrashInfoToFile(ex);
return true;
}
/**
* 收集版本信息信息
* @param context
*/
private void collectVersionInfo(Context context) {
try {
PackageManager pm = context.getPackageManager();
PackageInfo pi = pm.getPackageInfo(context.getPackageName(), PackageManager.GET_ACTIVITIES);
if (pi != null) {
String versionName = pi.versionName == null ? "null" : pi.versionName;
String versionCode = pi.versionCode + "";
infos.put("versionName", versionName);
infos.put("versionCode", versionCode);
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
/**
* 保存错误日志到文件中
* @param ex
*/
private void saveCrashInfoToFile(Throwable ex) {
//换行符
String lineFeed = "\r\n";
StringBuffer sb = new StringBuffer();
for(Map.Entry<String,String> entry: infos.entrySet()){
String key = entry.getKey();
String value = entry.getValue();
sb.append(key + "=" + value + lineFeed);
}
StackTraceElement[] stack = ex.getStackTrace();
String message = ex.getMessage();
//准备错误日志文件
File logFile = new File(LOGFILE_NAME);
if(!logFile.getParentFile().exists()){
logFile.getParentFile().mkdirs();
}
//写入错误日志
FileWriter writer = null;
try {
//获取当前时间、异常message信息,异常栈跟踪信息写入日志文件
writer = new FileWriter(logFile);
writer.write("创建时间:" + StrUtils.currentTime("yy-MM-dd hh:mm:ss").toString()+lineFeed+lineFeed);
writer.write(message+lineFeed);
for(int i=0;i<stack.length;i++){
writer.write(stack[i].toString() + lineFeed);
}
writer.write(lineFeed);
writer.write(sb.toString());
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(null != writer){
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 根据Build类搜集设备信息
*/
private void collectDeviceInfo(){
Field[] fields = Build.class.getDeclaredFields();
for(Field field : fields){
try {
field.setAccessible(true);
infos.put(field.getName(),field.get(null).toString());
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
4.简单的下载工具类,也可以用封装的okhttp下载工具,亲测都好用。
public class DownLoadUtils {
/**
* 带最大值,进度值,结果的下载
* @param url
* @param maxLen
* @param progress
* @param result
*/
public static void downloadFile(final String url, final CallBackimpl maxLen, final CallBackimpl progress, final CallBackimpl result){
new Thread(){
@Override
public void run() {
try {
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
if(conn.getResponseCode() == 200){
InputStream inputStream = conn.getInputStream();
byte[] bytes = new byte[1024 * 500];
int len = -1;
maxLen.callBack(conn.getContentLength());
int currentLen = 0; //当前进度
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
while((len = inputStream.read(bytes)) != -1){
baos.write(bytes,0,len);
currentLen+=len;
progress.callBack(currentLen);
}
result.callBack(baos.toByteArray());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
/**
* 下载方法
* @param url 地址
* @param callBackimpl 下载完成回调
*/
public static void downloadFile(final String url, final String fileName, final CallBackimpl callBackimpl){
new Thread(){
@Override
public void run() {
try {
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
if(conn.getResponseCode() == 200){
InputStream inputStream = conn.getInputStream();
byte[] bytes = new byte[1024];
int len = -1;
File file = new File(fileName);
if(!file.getParentFile().exists()){
file.getParentFile().mkdirs();
}
FileOutputStream fos = new FileOutputStream(fileName);
while((len = inputStream.read(bytes)) != -1){
fos.write(bytes, 0, len);
}
fos.close();
callBackimpl.confirmHandle();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
}
5.文件操作工具类:包括判断sd卡可用;获取项目根目录;数据写文件;获取文件大小;删除文件;从raw资源文件读取到流;判断空间是否足够。
public class FileUtils {
/**
* 判断sd卡是否可用
* @return
*/
public static boolean isHaveSDcard(){
return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
}
/**
* 设置App缓存根目录
* @return
*/
public static String getCacheDir(){
String sdDir = null;
if(isHaveSDcard()){
sdDir = Environment.getExternalStorageDirectory().getPath() + "/AppName/";
}
return sdDir;
}
/**
* 将data数据写入指定文件里
* @param data
* @param fileName
* @throws IOException
*/
public static void saveFileToSDcard(byte[] data,String fileName){
String filePath = getCacheDir();
File dir = new File(filePath);
if(!dir.exists()){
dir.mkdirs();
}
File file = new File(filePath+"/"+fileName);
try {
if(!file.exists()){
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos);
bos.write(data);
bos.flush();
bos.close();
fos.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 递归累计获取文件/文件夹大小
* @param f
* @return
* @throws Exception
*/
public static long getFileSize(File f) throws Exception {
long size = 0;
File flist[] = f.listFiles();
for (int i = 0; i < flist.length; i++) {
if (flist[i].isDirectory()) {
size = size + getFileSize(flist[i]);
} else {
size = size + flist[i].length();
}
}
return size;
}
/**
* 递归删除文件/文件夹
* @param file
*/
public static void delFile(File file){
if(file.isFile()){
file.delete();
}else if(file.isDirectory()){
File file1s[] = file.listFiles();
for(int i=0;i<file1s.length;i++){
delFile(file1s[i]);
}
file.delete();
}
}
/**
* 从raw资源文件中获取
*
* @return
*/
private String getAddress(Context context,int rawRes) {
StringBuilder sb = new StringBuilder();
try {
InputStream inputStream = context.getResources().openRawResource(rawRes);
byte[] buffer = new byte[1024];
while (inputStream.read(buffer) != -1) {
sb.append(new String(buffer, "UTF-8"));
}
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
/**
* 是否有足够的空间
* @param size in B
* @return
*/
public boolean haveSpace(Context context, int size){
//判断sdcard存储空间是否满足文件的存储
File sdcard_filedir = Environment.getExternalStorageDirectory();//得到sdcard的目录作为一个文件对象
long usableSpace = sdcard_filedir.getUsableSpace();//获取文件目录对象剩余空间
long totalSpace = sdcard_filedir.getTotalSpace();
//将一个long类型的文件大小格式化成用户可以看懂的M,G字符串
String usableSpace_str = Formatter.formatFileSize(context, usableSpace);
String totalSpace_str = Formatter.formatFileSize(context, totalSpace);
if(usableSpace < size+20*1024*1024){//判断剩余空间是否小于size
Toast.makeText(context, "sdcard剩余空间不足,无法满足下载;剩余空间为:"+usableSpace_str,Toast.LENGTH_SHORT).show();
return false;
}else{
return true;
}
}
}
6.日志管理工具类:通过设置全局变量LOGLEVEL的值进行开启或关闭log,如-1开启,6关闭;
public class LogUtils {
private static int LOGLEVEL = 6;
private static int VERBOSE = 1;
private static int DEBUG = 2;
private static int INFO = 3;
private static int WARN = 4;
private static int ERROR = 5;
public static void v(String tag, String msg){
if(LOGLEVEL > VERBOSE) Log.v(tag,msg);
}
public static void d(String tag, String msg){
if(LOGLEVEL > DEBUG) Log.d(tag, msg);
}
public static void i(String tag, String msg){
if(LOGLEVEL > INFO) Log.i(tag, msg);
}
public static void w(String tag, String msg){
if(LOGLEVEL > WARN) Log.w(tag, msg);
}
public static void e(String tag, String msg){
if(LOGLEVEL > ERROR) Log.e(tag,msg);
}
}
7.网络判断工具类:包括网络是否可用;获取当前网络类型;
public class NetWorkUtils {
/**
* 判断网路是否可用
* @param context
* @return
*/
public static boolean isNetWorkAvailable(Context context){
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
//获取所有可用的网络连接信息
NetworkInfo[] infos = manager.getAllNetworkInfo();
if(null != infos){
for(NetworkInfo info : infos){
if(info.getState() == NetworkInfo.State.CONNECTED){
return true;
}
}
}
return false;
}
/**
* 返回网络类型
* @return
*/
public static NetWorkState getNetworkState(Context context){
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if(manager.getActiveNetworkInfo().getType() == ConnectivityManager.TYPE_WIFI){
return NetWorkState.WIFI;
}else if(manager.getActiveNetworkInfo().getType() == ConnectivityManager.TYPE_MOBILE){
return NetWorkState.MOBILE;
}else {
return NetWorkState.NONE;
}
}
public enum NetWorkState {
WIFI,MOBILE,NONE
}
}
8.尺寸工具类:包括获取屏幕宽高,密度,dp、px互转,px、sp互转。
public class ScreenUtils {
/**
* 获取屏幕宽度
* @param context
* @return
*/
public static int getScreenWidth(Context context){
return context.getResources().getDisplayMetrics().widthPixels;
}
/**
* 获取屏幕高度
* @param context
* @return
*/
public static int getScreenHeight(Context context){
return context.getResources().getDisplayMetrics().heightPixels;
}
/**
* 获取屏幕密度
* @param context
* @return
*/
public static float getScreenDensity(Context context){
return context.getResources().getDisplayMetrics().density;
}
/**
* dp转px
* @param context
* @param dpValue
* @return
*/
public static int dp2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
/**
* px转dp
* @param context
* @param pxVal
* @return
*/
public static float px2dp(Context context, float pxVal) {
final float scale = context.getResources().getDisplayMetrics().density;
return (pxVal / scale);
}
/**
* sp转px
* @param context
* @param spVal
* @return
*/
public static int sp2px(Context context, float spVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
spVal, context.getResources().getDisplayMetrics());
}
/**
* px转sp
* @param context
* @param pxVal
* @return
*/
public static float px2sp(Context context, float pxVal) {
return (pxVal / context.getResources().getDisplayMetrics().scaledDensity);
}
}
9.SharedPreferences存取操作类:传任意类型自动能存取数据。
public class SharedPrefUtils {
public static final String SHAREFRE_FILENAME = "sharefile";
/**
* 保存数据到共享参数中
* @param context
* @param key 键
* @param object 值
*/
public static void setParams(Context context, String key, Object object){
SharedPreferences sharedPreferences = context.getSharedPreferences(SHAREFRE_FILENAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
if(object instanceof String){
editor.putString(key, (String) object);
}else if(object instanceof Integer){
editor.putInt(key, (Integer) object);
}else if(object instanceof Boolean){
editor.putBoolean(key, (Boolean) object);
}else if(object instanceof Float){
editor.putFloat(key, (Float) object);
}else if(object instanceof Long){
editor.putLong(key, (Long) object);
}
editor.commit();
}
/**
* 获取共享参数,根据默认数据类型获取相对应key的值
* @param context
* @param key 键
* @param defaultObject 默认值
* @return
*/
public static Object getParams(Context context, String key, Object defaultObject){
SharedPreferences sharedPreferences = context.getSharedPreferences(SHAREFRE_FILENAME, Context.MODE_PRIVATE);
if(defaultObject instanceof String){
return sharedPreferences.getString(key, (String) defaultObject);
}else if(defaultObject instanceof Integer){
return sharedPreferences.getInt(key, (Integer) defaultObject);
}else if(defaultObject instanceof Boolean){
return sharedPreferences.getBoolean(key, (Boolean) defaultObject);
}else if(defaultObject instanceof Float){
return sharedPreferences.getFloat(key, (Float) defaultObject);
}else if(defaultObject instanceof Long){
return sharedPreferences.getLong(key, (Long) defaultObject);
}
return null;
}
}
10.字符串操作工具类:获取时间;时间戳转日期;保留指定位小数点;字符串判空等。
public class StrUtils {
private static String patternCoder = "(?<!\\d)\\d{6}(?!\\d)";
private static String phonePatter = "^1\\d{10}$";
/** 获得当前时间 */
public static CharSequence currentTime(CharSequence inFormat) {
return DateFormat.format(inFormat, System.currentTimeMillis());
}
/**
* 时间戳转 yyyy年MM月dd日 HH:mm
* @param longTime
* @return
*/
public static String getDateTime(String longTime){
long time = Long.valueOf(longTime)*1000;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm");
return sdf.format(new Date(time));
}
/**
* 时间戳转 yyy年MM月dd日 HH:mm:ss
* @param longTime
* @return
*/
public static String getDateSec(String longTime){
long time = Long.valueOf(longTime)*1000;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
return sdf.format(new Date(time));
}
/**
* 时间戳转 MM月dd日 HH:mm
* @param longTime
* @return
*/
public static String getDateMinite(String longTime){
long time = Long.valueOf(longTime)*1000;
SimpleDateFormat sdf = new SimpleDateFormat("MM月dd日 HH:mm");
return sdf.format(new Date(time));
}
/**
* 时间戳转 yyyy-MM-dd HH:mm
* @param longTime
* @return
*/
public static String getTime(String longTime){
long time = Long.valueOf(longTime)*1000;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
return sdf.format(new Date(time));
}
/**
* 时间戳转 yyyy-MM-dd
* @param longTime
* @return
*/
public static String getdate(String longTime){
long time = Long.valueOf(longTime)*1000;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(new Date(time));
}
/**
* 日期转时间戳
* @return
*/
public static String getTimeStamp(String dateTime, String format){
try {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
return String.valueOf(simpleDateFormat.parse(dateTime).getTime()/1000);
} catch (ParseException e) {
e.printStackTrace();
}
return "";
}
/**
* 从短信中截取验证码
* @param patternContent
* @return
*/
public static String patternCode(String patternContent) {
if (TextUtils.isEmpty(patternContent)) {
return null;
}
Pattern p = Pattern.compile(patternCoder);
Matcher matcher = p.matcher(patternContent);
if (matcher.find()) {
return matcher.group();
}
return null;
}
/**
* 检测手机号码
* @param patternContent
* @return
*/
public static boolean checkPhone(String patternContent){
Pattern pattern = Pattern.compile(phonePatter);
Matcher matcher = pattern.matcher(patternContent);
return matcher.matches();
}
/**
* 保留指定小数点位数,format传 "0.0" "0.00"形式分别保存一位,两位小数
* @param num
* @param format
* @return
*/
public static String doubleRound(double num, String format){
DecimalFormat df = new DecimalFormat(format);
return df.format(num);
}
/**
* 判断单个字符串是否为空
* @param str
* @return
*/
public static boolean isStr(String str){
if(null != str && str.length() != 0) return true;
return false;
}
/**
* 判断多个字符串是否为空
* @param str
* @return
*/
public static boolean isArrStr(String... str){
if(null == str) return false;
for(String s : str){
if(!isStr(s)) return false;
}
return true;
}
}
哇塞,你看完了,做做眼保健操放松放松眼睛吧。好啦,本期节目就到此为止了,下期节目再见!
网友评论