文/程序员男神
前言
今早起的还算早,看了一场NBA,一想到工作还没给答复,心里就有点着急了。中午定了份外卖,心酸的吃着土豆丝,好心酸,这时女朋友发来微信,说今晚我们去看我不是潘金莲吧!还记得在北京的时候这电影就一直在宣传,听到这个消息,心情好了那么点。把昨天整理的代码写篇文章平复一下糟糕的心情。今天带来了基本每个项目中都会使用的工具类。前方代码较多......
工具类
1、日志工具类
package com.example.dj.testdemo.Utils;
import com.example.dj.testdemo.BuildConfig;
/**
* 描述:日志工具类
* <p>
* 这个工具类主要在三处地方做了封装。
* 第一是加入BuildConfig.DEBUG判断,这样发布时就不会打印log,如果不了解BuildConfig,可以参考这篇文章Android BuildConfig.DEBUG的妙用
* 第二是log工具类都常见的,预设置TAG,这样不用每次都传两个参数
* 第三,通过StackTraceElement获取当前打印日志的类名和方法名,这个用来代替我们平时手写的TAG值。StackTrace用栈的形式保存了方法的调用信息。
* Created by dj on 2016/11/16 0016.
*/
public class MyLogger {
protected static final String TAG = "DSBBM";
public MyLogger() {
}
/**
* Send a VERBOSE log message.
*
* @param msg The message you would like logged.
*/
public static void v(String msg) {
if (BuildConfig.DEBUG)
android.util.Log.v(TAG, buildMessage(msg));
}
/**
* Send a VERBOSE log message and log the exception.
*
* @param msg The message you would like logged.
* @param tr An exception to log
*/
public static void v(String msg, Throwable tr) {
if (BuildConfig.DEBUG)
android.util.Log.v(TAG, buildMessage(msg), tr);
}
/**
* Send a DEBUG log message.
*
* @param msg
*/
public static void d(String msg) {
if (BuildConfig.DEBUG)
android.util.Log.d(TAG, buildMessage(msg));
}
/**
* Send a DEBUG log message and log the exception.
*
* @param msg The message you would like logged.
* @param tr An exception to log
*/
public static void d(String msg, Throwable tr) {
if (BuildConfig.DEBUG)
android.util.Log.d(TAG, buildMessage(msg), tr);
}
/**
* Send an INFO log message.
*
* @param msg The message you would like logged.
*/
public static void i(String msg) {
if (BuildConfig.DEBUG)
android.util.Log.i(TAG, buildMessage(msg));
}
/**
* Send a INFO log message and log the exception.
*
* @param msg The message you would like logged.
* @param tr An exception to log
*/
public static void i(String msg, Throwable tr) {
if (BuildConfig.DEBUG)
android.util.Log.i(TAG, buildMessage(msg), tr);
}
/**
* Send an ERROR log message.
*
* @param msg The message you would like logged.
*/
public static void e(String msg) {
if (BuildConfig.DEBUG)
android.util.Log.e(TAG, buildMessage(msg));
}
/**
* Send an ERROR log message and log the exception.
*
* @param msg The message you would like logged.
* @param tr An exception to log
*/
public static void e(String msg, Throwable tr) {
if (BuildConfig.DEBUG)
android.util.Log.e(TAG, buildMessage(msg), tr);
}
/**
* Send a WARN log message
*
* @param msg The message you would like logged.
*/
public static void w(String msg) {
if (BuildConfig.DEBUG)
android.util.Log.w(TAG, buildMessage(msg));
}
/**
* Send a WARN log message and log the exception.
*
* @param msg The message you would like logged.
* @param thr An exception to log
*/
public static void w(String msg, Throwable thr) {
if (BuildConfig.DEBUG)
android.util.Log.w(TAG, buildMessage(msg), thr);
}
/**
* Send an empty WARN log message and log the exception.
*
* @param thr An exception to log
*/
public static void w(Throwable thr) {
if (BuildConfig.DEBUG)
android.util.Log.w(TAG, buildMessage(""), thr);
}
protected static String buildMessage(String msg) {
//通过StackTraceElement获取当前打印日志的类名和方法名,这个用来代替我们平时手写的TAG值。
// StackTrace用栈的形式保存了方法的调用信息
StackTraceElement caller = new Throwable().fillInStackTrace().getStackTrace()[2];
return new StringBuilder().append(caller.getClassName()).append(".").append(caller.getMethodName()).append("(): ").append(msg).toString();
}
}
打印格式:I/DSBBM: com.example.dj.testdemo.MainActivity.onClick(): msg
这个工具类主要在三处地方做了封装。
第一是加入BuildConfig.DEBUG判断,这样发布时就不会打印log,如果不了解BuildConfig,可以参考这篇文章Android BuildConfig.DEBUG的妙用
第二是log工具类都常见的,预设置TAG,这样不用每次都传两个参数
第三是通过StackTraceElement获取当前打印日志的类名和方法名,这个用来代替我们平时手写的TAG值。StackTrace用栈的形式保存了方法的调用信息。对StackTrace不了解的同学可以参考这篇文章StackTrace简述以及StackTraceElement使用实例
2、Toast统一管理工具类
package com.example.dj.testdemo.Utils;
import android.content.Context;
import android.view.Gravity;
import android.widget.Toast;
/**
* 描述:统一管理类
* <p>
* Created by dj on 2016/11/17 0017.
*/
public class MyToast {
private MyToast() {
//不能被实例化
throw new UnsupportedOperationException("cannot be instantiated");
}
public static boolean isShow = true;
/**
* 屏幕中间位置显示短时间Toast
*
* @param context
* @param msg
*/
public static void ToastShortCenter(Context context, String msg) {
if (isShow) {
if (context != null) {
Toast toast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
}
}
/**
* 屏幕中心位置长时间显示Toast
*
* @param context
* @param message
*/
public static void ToastLongCenter(Context context, String message) {
if (isShow) {
if (context != null) {
Toast toast = Toast.makeText(context, message, Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
}
}
/**
* 自定义显示Toast时间
*
* @param context
* @param message
* @param duration
*/
public static void ToastShow(Context context, String message, int duration) {
if (isShow)
Toast.makeText(context, message, duration).show();
}
}
非常简单的一个封装类,短Toast、长Toast、自定义Toast的实现。
3、SharedPreferences封装工具类
package com.example.dj.testdemo.Utils;
import android.content.Context;
import android.content.SharedPreferences;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
/**
* 描述:SharedPreferences封装类
* <p>
* Created by dj on 2016/11/17 0017.
*/
public class SPUtils {
/**
* 保存在手机里面的文件名
*/
public static final String FILE_NAME = "share_data";
/**
* 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法
*
* @param context
* @param key
* @param object
*/
public static void put(Context context, String key, Object object) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.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);
} else {
editor.putString(key, object.toString());
}
/**
* commit操作使用了SharedPreferencesCompat.apply进行了替代,目的是尽可能的使用apply代替commit
* 因为commit方法是同步的,并且我们很多时候的commit操作都是UI线程中,毕竟是IO操作,尽可能异步;
*/
SharedPreferencesCompat.apply(editor);
}
/**
* 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值
*
* @param context
* @param key
* @param defaultObject
* @return
*/
public static Object get(Context context, String key, Object defaultObject) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
if (defaultObject instanceof String) {
return sp.getString(key, (String) defaultObject);
} else if (defaultObject instanceof Integer) {
return sp.getInt(key, (Integer) defaultObject);
} else if (defaultObject instanceof Boolean) {
return sp.getBoolean(key, (Boolean) defaultObject);
} else if (defaultObject instanceof Float) {
return sp.getFloat(key, (Float) defaultObject);
} else if (defaultObject instanceof Long) {
return sp.getLong(key, (Long) defaultObject);
}
return null;
}
/**
* 移除某个key值已经对应的值
*
* @param context
* @param key
*/
public static void remove(Context context, String key) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.remove(key);
SharedPreferencesCompat.apply(editor);
}
/**
* 清除所有数据
*
* @param context
*/
public static void clear(Context context) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.clear();
SharedPreferencesCompat.apply(editor);
}
/**
* 查询某个key是否已经存在
*
* @param context
* @param key
* @return
*/
public static boolean contains(Context context, String key) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
return sp.contains(key);
}
/**
* 返回所有的键值对
*
* @param context
* @return
*/
public static Map<String, ?> getAll(Context context) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
return sp.getAll();
}
/**
* 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类
*
* @author dj
*/
private static class SharedPreferencesCompat {
private static final Method sApplyMethod = findApplyMethod();
/**
* 反射查找apply的方法
*
* @return
*/
@SuppressWarnings({"unchecked", "rawtypes"})
private static Method findApplyMethod() {
try {
Class clz = SharedPreferences.Editor.class;
return clz.getMethod("apply");
} catch (NoSuchMethodException e) {
}
return null;
}
/**
* 如果找到则使用apply执行,否则使用commit
*
* @param editor
*/
public static void apply(SharedPreferences.Editor editor) {
try {
if (sApplyMethod != null) {
sApplyMethod.invoke(editor);
return;
}
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
e.printStackTrace();
}
editor.commit();
}
}
}
对SharedPreference的使用做了建议的封装,对外公布出put,get,remove,clear等等方法;
注意一点,里面所有的commit操作使用了SharedPreferencesCompat.apply进行了替代,目的是尽可能的使用apply代替commit;
首先说下为什么,因为commit方法是同步的,并且我们很多时候的commit操作都是UI线程中,毕竟是IO操作,尽可能异步;
所以我们使用apply进行替代,apply异步的进行写入;
但是apply相当于commit来说是new API呢,为了更好的兼容,我们做了适配;
4、单位转换工具类
package com.example.dj.testdemo.Utils;
import android.content.Context;
import android.util.TypedValue;
/**
* 描述:单位转换辅助类
* <p>
* Created by dj on 2016/11/17 0017.
*/
public class DensityUtils {
private DensityUtils() {
//不能被实例化
new UnsupportedOperationException("cannot be instantiated");
}
/**
* dp转px
*
* @param context
* @param dpVal
* @return
*/
public static int dp2px(Context context, float dpVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal, context.getResources().getDisplayMetrics());
}
/**
* 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转dp
*
* @param context
* @param pxVal
* @return
*/
public static float px2dp(Context context, float pxVal) {
final float scale = context.getResources().getDisplayMetrics().density;
return (pxVal / scale);
}
/**
* px转sp
*
* @param context
* @param pxVal
* @return
*/
public static float px2sp(Context context, float pxVal) {
return (pxVal / context.getResources().getDisplayMetrics().scaledDensity);
}
}
5、SCard相关工具类
package com.example.dj.testdemo.Utils;
import android.os.Environment;
import android.os.StatFs;
import java.io.File;
/**
* 描述:SDCard辅助类
* <p>
* Created by dj on 2016/11/17 0017.
*/
public class SDCardUtils {
private SDCardUtils() {
/* cannot be instantiated */
throw new UnsupportedOperationException("cannot be instantiated");
}
/**
* 判断SDCard是否可用
*
* @return
*/
public static boolean isSDCardEnable() {
return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
}
/**
* 获取SD卡路径
*
* @return
*/
public static String getSDCardPath() {
return Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator;
}
/**
* 获取SD卡的剩余容量 单位byte
*
* @return
*/
public static long getSDCardAllSize() {
if (isSDCardEnable()) {
StatFs stat = new StatFs(getSDCardPath());
// 获取空闲的数据块的数量
long availableBlocks = (long) stat.getAvailableBlocks() - 4;
// 获取单个数据块的大小(byte)
long freeBlocks = stat.getAvailableBlocks();
return freeBlocks * availableBlocks;
}
return 0;
}
/**
* 获取指定路径所在空间的剩余可用容量字节数,单位byte
*
* @param filePath
* @return 容量字节 SDCard可用空间,内部存储可用空间
*/
public static long getFreeBytes(String filePath) {
// 如果是sd卡的下的路径,则获取sd卡可用容量
if (filePath.startsWith(getSDCardPath())) {
filePath = getSDCardPath();
} else {// 如果是内部存储的路径,则获取内存存储的可用容量
filePath = Environment.getDataDirectory().getAbsolutePath();
}
StatFs stat = new StatFs(filePath);
long availableBlocks = (long) stat.getAvailableBlocks() - 4;
return stat.getBlockSize() * availableBlocks;
}
/**
* 获取系统存储路径
*
* @return
*/
public static String getRootDirectoryPath() {
return Environment.getRootDirectory().getAbsolutePath();
}
}
6、屏幕相关工具类
package com.example.dj.testdemo.Utils;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.WindowManager;
/**
* 描述:屏幕相关辅助类
* <p>
* Created by dj on 2016/11/17 0017.
*/
public class ScreenUtils {
private ScreenUtils() {
/* cannot be instantiated */
throw new UnsupportedOperationException("cannot be instantiated");
}
/**
* 获得屏幕高度
*
* @param context
* @return
*/
public static int getScreenWidth(Context context) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
return outMetrics.widthPixels;
}
/**
* 获得屏幕宽度
*
* @param context
* @return
*/
public static int getScreenHeight(Context context) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
return outMetrics.heightPixels;
}
/**
* 获得状态栏的高度
*
* @param context
* @return
*/
public static int getStatusHeight(Context context) {
int statusHeight = -1;
try {
Class<?> clazz = Class.forName("com.android.internal.R$dimen");
Object object = clazz.newInstance();
int height = Integer.parseInt(clazz.getField("status_bar_height")
.get(object).toString());
statusHeight = context.getResources().getDimensionPixelSize(height);
} catch (Exception e) {
e.printStackTrace();
}
return statusHeight;
}
/**
* 获取当前屏幕截图,包含状态栏
*
* @param activity
* @return
*/
public static Bitmap snapShotWithStatusBar(Activity activity) {
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap bmp = view.getDrawingCache();
int width = getScreenWidth(activity);
int height = getScreenHeight(activity);
Bitmap bp = null;
bp = Bitmap.createBitmap(bmp, 0, 0, width, height);
view.destroyDrawingCache();
return bp;
}
/**
* 获取当前屏幕截图,不包含状态栏
*
* @param activity
* @return
*/
public static Bitmap snapShotWithoutStatusBar(Activity activity) {
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap bmp = view.getDrawingCache();
Rect frame = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.top;
int width = getScreenWidth(activity);
int height = getScreenHeight(activity);
Bitmap bp = null;
bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, width, height - statusBarHeight);
view.destroyDrawingCache();
return bp;
}
}
7、版本检测工具类
package com.example.dj.testdemo.Utils;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
/**
* 基本功能:app版本工具
* <p>
* Created by dj on 2016/11/17 0017.
*/
public class VersionUtil {
/**
* 获取应用程序名称
* @param context
* @return
*/
public static String getAppName(Context context) {
try {
PackageManager packageManager = context.getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
int labelRes = packageInfo.applicationInfo.labelRes;
return context.getResources().getString(labelRes);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return null;
}
/**
* 获取版本号
*
* @param context
* @return 当前应用的版本号
*/
public static String getVersion(Context context) {
try {
PackageManager manager = context.getPackageManager();
PackageInfo info = manager.getPackageInfo(context.getPackageName(), 0);
String version = info.versionName;
return version;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return "";
}
}
/**
* 版本比较
*
* @param nowVersion app版本
* @param serverVersion 服务器版本
* @return
*/
public static boolean compareVersion(String nowVersion, String serverVersion) {
if (nowVersion != null && serverVersion != null) {
String[] nowVersions = nowVersion.split("\\.");
String[] serverVersions = serverVersion.split("\\.");
if (nowVersion != null && serverVersion != null && nowVersions.length > 1 && serverVersions.length > 1) {
int nowVersionFirst = Integer.parseInt(nowVersions[0]);
int serverVersionFirst = Integer.parseInt(serverVersions[0]);
int nowVersionSecond = Integer.parseInt(nowVersions[1]);
int serverVersionSecond = Integer.parseInt(serverVersions[1]);
if (nowVersionFirst < serverVersionFirst) {
return true;
} else if (nowVersionFirst == serverVersionFirst && nowVersionSecond < serverVersionSecond) {
return true;
}
}
}
return false;
}
}
8、网络相关辅助类
package com.example.dj.testdemo.Utils;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
/**
* 描述:网络辅助类
* <p>
* Created by dj on 2016/11/17 0017.
*/
public class NetUtils {
private NetUtils() {
/* cannot be instantiated */
throw new UnsupportedOperationException("cannot be instantiated");
}
/**
* 判断网络是否连接
*
* @param context
* @return
*/
public static boolean isConnected(Context context) {
ConnectivityManager connectivity = (ConnectivityManager) context.
getSystemService(Context.CONNECTIVITY_SERVICE);
if (null != connectivity) {
NetworkInfo info = connectivity.getActiveNetworkInfo();
if (null != info && info.isConnected()) {
if (info.getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
}
return false;
}
/**
* 判断是否是wifi连接
*/
public static boolean isWifi(Context context) {
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm == null)
return false;
return cm.getActiveNetworkInfo().getType() == ConnectivityManager.TYPE_WIFI;
}
/**
* 打开网络设置界面
*/
public static void openSetting(Activity activity) {
Intent intent = new Intent("/");
ComponentName cm = new ComponentName("com.android.settings",
"com.android.settings.WirelessSettings");
intent.setComponent(cm);
intent.setAction("android.intent.action.VIEW");
activity.startActivityForResult(intent, 0);
}
}
9、手机信息采集工具类
package com.example.dj.testdemo.Utils;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.SystemClock;
import android.telephony.TelephonyManager;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 基本功能:手机信息采集工具
* <p>
* Created by dj on 2016/11/17 0017.
*/
public class MobileUtil {
/**
* Print telephone info.
*/
public static String printMobileInfo(Context context) {
Date date = new Date(System.currentTimeMillis());
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time = dateFormat.format(date);
StringBuilder sb = new StringBuilder();
sb.append("系统时间:").append(time).append("\n");
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String IMSI = tm.getSubscriberId();
//IMSI前面三位460是国家号码,其次的两位是运营商代号,00、02是中国移动,01是联通,03是电信。
String providerName = null;
if (IMSI != null) {
if (IMSI.startsWith("46000") || IMSI.startsWith("46002")) {
providerName = "中国移动";
} else if (IMSI.startsWith("46001")) {
providerName = "中国联通";
} else if (IMSI.startsWith("46003")) {
providerName = "中国电信";
}
}
sb.append(providerName).append("\n").append(getNativePhoneNumber(context)).append("\n网络模式:").append(getNetType(context)).append("\nIMSI是:").append(IMSI);
sb.append("\nDeviceID(IMEI) :").append(tm.getDeviceId());
sb.append("\nDeviceSoftwareVersion:").append(tm.getDeviceSoftwareVersion());
sb.append("\ngetLine1Number :").append(tm.getLine1Number());
sb.append("\nNetworkCountryIso :").append(tm.getNetworkCountryIso());
sb.append("\nNetworkOperator :").append(tm.getNetworkOperator());
sb.append("\nNetworkOperatorName :").append(tm.getNetworkOperatorName());
sb.append("\nNetworkType :").append(tm.getNetworkType());
sb.append("\nPhoneType :").append(tm.getPhoneType());
sb.append("\nSimCountryIso :").append(tm.getSimCountryIso());
sb.append("\nSimOperator :").append(tm.getSimOperator());
sb.append("\nSimOperatorName :").append(tm.getSimOperatorName());
sb.append("\nSimSerialNumber :").append(tm.getSimSerialNumber());
sb.append("\ngetSimState :").append(tm.getSimState());
sb.append("\nSubscriberId :").append(tm.getSubscriberId());
sb.append("\nVoiceMailNumber :").append(tm.getVoiceMailNumber());
return sb.toString();
}
/**
* 打印系统信息
*
* @return
*/
public static String printSystemInfo() {
Date date = new Date(System.currentTimeMillis());
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time = dateFormat.format(date);
StringBuilder sb = new StringBuilder();
sb.append("_______ 系统信息 ").append(time).append(" ______________");
sb.append("\nID :").append(Build.ID);
sb.append("\nBRAND :").append(Build.BRAND);
sb.append("\nMODEL :").append(Build.MODEL);
sb.append("\nRELEASE :").append(Build.VERSION.RELEASE);
sb.append("\nSDK :").append(Build.VERSION.SDK);
sb.append("\n_______ OTHER _______");
sb.append("\nBOARD :").append(Build.BOARD);
sb.append("\nPRODUCT :").append(Build.PRODUCT);
sb.append("\nDEVICE :").append(Build.DEVICE);
sb.append("\nFINGERPRINT :").append(Build.FINGERPRINT);
sb.append("\nHOST :").append(Build.HOST);
sb.append("\nTAGS :").append(Build.TAGS);
sb.append("\nTYPE :").append(Build.TYPE);
sb.append("\nTIME :").append(Build.TIME);
sb.append("\nINCREMENTAL :").append(Build.VERSION.INCREMENTAL);
sb.append("\n_______ CUPCAKE-3 _______");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) {
sb.append("\nDISPLAY :").append(Build.DISPLAY);
}
sb.append("\n_______ DONUT-4 _______");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.DONUT) {
sb.append("\nSDK_INT :").append(Build.VERSION.SDK_INT);
sb.append("\nMANUFACTURER :").append(Build.MANUFACTURER);
sb.append("\nBOOTLOADER :").append(Build.BOOTLOADER);
sb.append("\nCPU_ABI :").append(Build.CPU_ABI);
sb.append("\nCPU_ABI2 :").append(Build.CPU_ABI2);
sb.append("\nHARDWARE :").append(Build.HARDWARE);
sb.append("\nUNKNOWN :").append(Build.UNKNOWN);
sb.append("\nCODENAME :").append(Build.VERSION.CODENAME);
}
sb.append("\n_______ GINGERBREAD-9 _______");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
sb.append("\nSERIAL :").append(Build.SERIAL);
}
return sb.toString();
}
/****
* 获取网络类型
*
* @param context
* @return
*/
public static String getNetType(Context context) {
try {
ConnectivityManager connectMgr = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = connectMgr.getActiveNetworkInfo();
if (info == null) {
return "";
}
if (info.getType() == ConnectivityManager.TYPE_WIFI) {
return "WIFI";
} else if (info.getType() == ConnectivityManager.TYPE_MOBILE) {
if (info.getSubtype() == TelephonyManager.NETWORK_TYPE_CDMA) {
return "CDMA";
} else if (info.getSubtype() == TelephonyManager.NETWORK_TYPE_EDGE) {
return "EDGE";
} else if (info.getSubtype() == TelephonyManager.NETWORK_TYPE_EVDO_0) {
return "EVDO0";
} else if (info.getSubtype() == TelephonyManager.NETWORK_TYPE_EVDO_A) {
return "EVDOA";
} else if (info.getSubtype() == TelephonyManager.NETWORK_TYPE_GPRS) {
return "GPRS";
}
/*
* else if(info.getSubtype() ==
* TelephonyManager.NETWORK_TYPE_HSDPA){ return "HSDPA"; }else
* if(info.getSubtype() == TelephonyManager.NETWORK_TYPE_HSPA){
* return "HSPA"; }else if(info.getSubtype() ==
* TelephonyManager.NETWORK_TYPE_HSUPA){ return "HSUPA"; }
*/
else if (info.getSubtype() == TelephonyManager.NETWORK_TYPE_UMTS) {
return "UMTS";
} else {
return "3G";
}
} else {
return "";
}
} catch (Exception e) {
return "";
}
}
/**
* 获取当前设置的电话号码
*/
public static String getNativePhoneNumber(Context context) {
TelephonyManager telephonyManager = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
String NativePhoneNumber = null;
NativePhoneNumber = telephonyManager.getLine1Number();
return String.format("手机号: %s", NativePhoneNumber);
}
/**
* IMSI是国际移动用户识别码的简称(International Mobile Subscriber Identity)
* IMSI共有15位,其结构如下:
* MCC+MNC+MIN
* MCC:Mobile Country Code,移动国家码,共3位,中国为460;
* MNC:Mobile NetworkCode,移动网络码,共2位
* 在中国,移动的代码为电00和02,联通的代码为01,电信的代码为03
* 合起来就是(也是Android手机中APN配置文件中的代码):
* 中国移动:46000 46002
* 中国联通:46001
* 中国电信:46003
* 举例,一个典型的IMSI号码为460030912121001
*/
public static String getIMSI(Context context) {
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String IMSI = telephonyManager.getSubscriberId();
return IMSI;
}
/**
* IMEI是International Mobile Equipment Identity (国际移动设备标识)的简称
* IMEI由15位数字组成的”电子串号”,它与每台手机一一对应,而且该码是全世界唯一的
* 其组成为:
* 1. 前6位数(TAC)是”型号核准号码”,一般代表机型
* 2. 接着的2位数(FAC)是”最后装配号”,一般代表产地
* 3. 之后的6位数(SNR)是”串号”,一般代表生产顺序号
* 4. 最后1位数(SP)通常是”0″,为检验码,目前暂备用
*/
public static String getIMEI(Context context) {
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String IMEI = telephonyManager.getDeviceId();
return IMEI;
}
/////_________________ 双卡双待系统IMEI和IMSI方案(see more on http://benson37.iteye.com/blog/1923946)
/**
* 双卡双待神机IMSI、IMSI、PhoneType信息
* <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
*/
public static class TeleInfo {
public String imsi_1;
public String imsi_2;
public String imei_1;
public String imei_2;
public int phoneType_1;
public int phoneType_2;
@Override
public String toString() {
return "TeleInfo{" +
"imsi_1='" + imsi_1 + '\'' +
", imsi_2='" + imsi_2 + '\'' +
", imei_1='" + imei_1 + '\'' +
", imei_2='" + imei_2 + '\'' +
", phoneType_1=" + phoneType_1 +
", phoneType_2=" + phoneType_2 +
'}';
}
}
/**
* MTK Phone.
* <p>
* 获取 MTK 神机的双卡 IMSI、IMSI 信息
*/
public static TeleInfo getMtkTeleInfo(Context context) {
TeleInfo teleInfo = new TeleInfo();
try {
Class<?> phone = Class.forName("com.android.internal.telephony.Phone");
Field fields1 = phone.getField("GEMINI_SIM_1");
fields1.setAccessible(true);
int simId_1 = (Integer) fields1.get(null);
Field fields2 = phone.getField("GEMINI_SIM_2");
fields2.setAccessible(true);
int simId_2 = (Integer) fields2.get(null);
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
Method getSubscriberIdGemini = TelephonyManager.class.getDeclaredMethod("getSubscriberIdGemini", int.class);
String imsi_1 = (String) getSubscriberIdGemini.invoke(tm, simId_1);
String imsi_2 = (String) getSubscriberIdGemini.invoke(tm, simId_2);
teleInfo.imsi_1 = imsi_1;
teleInfo.imsi_2 = imsi_2;
Method getDeviceIdGemini = TelephonyManager.class.getDeclaredMethod("getDeviceIdGemini", int.class);
String imei_1 = (String) getDeviceIdGemini.invoke(tm, simId_1);
String imei_2 = (String) getDeviceIdGemini.invoke(tm, simId_2);
teleInfo.imei_1 = imei_1;
teleInfo.imei_2 = imei_2;
Method getPhoneTypeGemini = TelephonyManager.class.getDeclaredMethod("getPhoneTypeGemini", int.class);
int phoneType_1 = (Integer) getPhoneTypeGemini.invoke(tm, simId_1);
int phoneType_2 = (Integer) getPhoneTypeGemini.invoke(tm, simId_2);
teleInfo.phoneType_1 = phoneType_1;
teleInfo.phoneType_2 = phoneType_2;
} catch (Exception e) {
e.printStackTrace();
}
return teleInfo;
}
/**
* MTK Phone.
* <p>
* 获取 MTK 神机的双卡 IMSI、IMSI 信息
*/
public static TeleInfo getMtkTeleInfo2(Context context) {
TeleInfo teleInfo = new TeleInfo();
try {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
Class<?> phone = Class.forName("com.android.internal.telephony.Phone");
Field fields1 = phone.getField("GEMINI_SIM_1");
fields1.setAccessible(true);
int simId_1 = (Integer) fields1.get(null);
Field fields2 = phone.getField("GEMINI_SIM_2");
fields2.setAccessible(true);
int simId_2 = (Integer) fields2.get(null);
Method getDefault = TelephonyManager.class.getMethod("getDefault", int.class);
TelephonyManager tm1 = (TelephonyManager) getDefault.invoke(tm, simId_1);
TelephonyManager tm2 = (TelephonyManager) getDefault.invoke(tm, simId_2);
String imsi_1 = tm1.getSubscriberId();
String imsi_2 = tm2.getSubscriberId();
teleInfo.imsi_1 = imsi_1;
teleInfo.imsi_2 = imsi_2;
String imei_1 = tm1.getDeviceId();
String imei_2 = tm2.getDeviceId();
teleInfo.imei_1 = imei_1;
teleInfo.imei_2 = imei_2;
int phoneType_1 = tm1.getPhoneType();
int phoneType_2 = tm2.getPhoneType();
teleInfo.phoneType_1 = phoneType_1;
teleInfo.phoneType_2 = phoneType_2;
} catch (Exception e) {
e.printStackTrace();
}
return teleInfo;
}
/**
* Qualcomm Phone.
* 获取 高通 神机的双卡 IMSI、IMSI 信息
*/
public static TeleInfo getQualcommTeleInfo(Context context) {
TeleInfo teleInfo = new TeleInfo();
try {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
Class<?> simTMclass = Class.forName("android.telephony.MSimTelephonyManager");
// Object sim = context.getSystemService("phone_msim");
Object sim = context.getSystemService(Context.TELEPHONY_SERVICE);
int simId_1 = 0;
int simId_2 = 1;
Method getSubscriberId = simTMclass.getMethod("getSubscriberId", int.class);
String imsi_1 = (String) getSubscriberId.invoke(sim, simId_1);
String imsi_2 = (String) getSubscriberId.invoke(sim, simId_2);
teleInfo.imsi_1 = imsi_1;
teleInfo.imsi_2 = imsi_2;
Method getDeviceId = simTMclass.getMethod("getDeviceId", int.class);
String imei_1 = (String) getDeviceId.invoke(sim, simId_1);
String imei_2 = (String) getDeviceId.invoke(sim, simId_2);
teleInfo.imei_1 = imei_1;
teleInfo.imei_2 = imei_2;
Method getDataState = simTMclass.getMethod("getDataState");
int phoneType_1 = tm.getDataState();
int phoneType_2 = (Integer) getDataState.invoke(sim);
teleInfo.phoneType_1 = phoneType_1;
teleInfo.phoneType_2 = phoneType_2;
} catch (Exception e) {
e.printStackTrace();
}
return teleInfo;
}
/**
* Spreadtrum Phone.
* <p>
* 获取 展讯 神机的双卡 IMSI、IMSI 信息
*/
public static TeleInfo getSpreadtrumTeleInfo(Context context) {
TeleInfo teleInfo = new TeleInfo();
try {
TelephonyManager tm1 = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String imsi_1 = tm1.getSubscriberId();
String imei_1 = tm1.getDeviceId();
int phoneType_1 = tm1.getPhoneType();
teleInfo.imsi_1 = imsi_1;
teleInfo.imei_1 = imei_1;
teleInfo.phoneType_1 = phoneType_1;
Class<?> phoneFactory = Class.forName("com.android.internal.telephony.PhoneFactory");
Method getServiceName = phoneFactory.getMethod("getServiceName", String.class, int.class);
getServiceName.setAccessible(true);
TelephonyManager tm2 = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String imsi_2 = tm2.getSubscriberId();
String imei_2 = tm2.getDeviceId();
int phoneType_2 = tm2.getPhoneType();
teleInfo.imsi_2 = imsi_2;
teleInfo.imei_2 = imei_2;
teleInfo.phoneType_2 = phoneType_2;
} catch (Exception e) {
e.printStackTrace();
}
return teleInfo;
}
/**
* 获取 MAC 地址
* <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
*/
public static String getMacAddress(Context context) {
//wifi mac地址
WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo info = wifi.getConnectionInfo();
String mac = info.getMacAddress();
return mac;
}
/**
* 获取 开机时间
*/
public static String getBootTimeString() {
long ut = SystemClock.elapsedRealtime() / 1000;
int h = (int) ((ut / 3600));
int m = (int) ((ut / 60) % 60);
return h + ":" + m;
}
}
10、错误信息反馈工具类
package com.example.dj.testdemo.Utils;
import android.content.Context;
/**
* 基本功能:错误信息反馈信息
* <p>
* Created by dj on 2016/11/17 0017.
*/
public class ErrorMessageUtil {
public static String printErrorMessage(Context context, String methodName, String errorMessage) {
return "\n############################errorMessage start ##############################\n"
+ MobileUtil.printMobileInfo(context) + MobileUtil.printSystemInfo() + "\n错误信息:" + errorMessage + "\n方法名:" + methodName + "\n当前app版本号:" + VersionUtil.getVersion(context)
+ "\n############################errorMessage end##############################";
}
}
11、Snackbar的工具类
使用方法:
使用Snackbar要导入com.android.support:design库。
bug:设置的位置为什么没有效果???
SnackbarUtil.ShortSnackbar(linearLayout, "登录成功", getResources().getColor(R.color.white),
Gravity.CENTER_HORIZONTAL, getResources().getColor(R.color.green)).show();
/**
* desc: SnackBar的工具类
* author: dj
* date: 2017/2/16 13:19
*/
public class SnackbarUtil {
public static final int Success = 1;
public static final int Error = 2;
public static final int Warning = 3;
public static int red = 0xfff44336;
public static int blue = 0xff2195f3;
public static int orange = 0xffffc107;
/**
* 短显示SnackBar,自定义颜色
*
* @param view
* @param message
* @param messageColor
* @param backgroundColor
* @return
*/
public static Snackbar ShortSnackbar(View view, String message, int messageColor, int gravity, int backgroundColor) {
Snackbar snackbar = Snackbar.make(view, message, Snackbar.LENGTH_SHORT);
setSnackbarColor(snackbar, messageColor, gravity, backgroundColor);
return snackbar;
}
/**
* 长显示SnackBar,自定义颜色
*
* @param view
* @param message
* @param messageColor
* @param backgroundColor
* @return
*/
public static Snackbar LongSnackbar(View view, String message, int messageColor, int gravity, int backgroundColor) {
Snackbar snackbar = Snackbar.make(view, message, Snackbar.LENGTH_LONG);
setSnackbarColor(snackbar, messageColor, gravity, backgroundColor);
return snackbar;
}
/**
* 自定义时常显示SnackBar,自定义颜色
*
* @param view
* @param message
* @param messageColor
* @param backgroundColor
* @return
*/
public static Snackbar IndefiniteSnackbar(View view, String message, int duration, int messageColor, int gravity, int backgroundColor) {
Snackbar snackbar = Snackbar.make(view, message, Snackbar.LENGTH_INDEFINITE).setDuration(duration);
setSnackbarColor(snackbar, messageColor, gravity, backgroundColor);
return snackbar;
}
/**
* 短显示SnackBar,可选预设类型
*
* @param view
* @param message
* @param type
* @return
*/
public static Snackbar ShortSnackbar(View view, String message, int type) {
Snackbar snackbar = Snackbar.make(view, message, Snackbar.LENGTH_SHORT);
switchType(snackbar, type);
return snackbar;
}
/**
* 长显示SnackBar,可选预设类型
*
* @param view
* @param message
* @param type
* @return
*/
public static Snackbar LongSnackbar(View view, String message, int type) {
Snackbar snackbar = Snackbar.make(view, message, Snackbar.LENGTH_LONG);
switchType(snackbar, type);
return snackbar;
}
/**
* 自定义时常显示SnackBar,可选预设类型B
*
* @param view
* @param message
* @param type
* @return
*/
public static Snackbar IndefiniteSnackbar(View view, String message, int duration, int type) {
Snackbar snackbar = Snackbar.make(view, message, Snackbar.LENGTH_INDEFINITE).setDuration(duration);
switchType(snackbar, type);
return snackbar;
}
//选择预设类型
private static void switchType(Snackbar snackbar, int type) {
switch (type) {
case Success:
setSnackbarColor(snackbar, blue);
break;
case Error:
setSnackbarColor(snackbar, red);
break;
case Warning:
setSnackbarColor(snackbar, orange);
break;
}
}
/**
* 设置SnackBar背景颜色
*
* @param snackbar
* @param backgroundColor
*/
public static void setSnackbarColor(Snackbar snackbar, int backgroundColor) {
View view = snackbar.getView();
if (view != null) {
view.setBackgroundColor(backgroundColor);
}
}
/**
* 设置SnackBar文字和背景颜色
*
* @param snackbar
* @param messageColor
* @param backgroundColor
*/
public static void setSnackbarColor(Snackbar snackbar, int messageColor, int gravity, int backgroundColor) {
View view = snackbar.getView();
if (view != null) {
view.setBackgroundColor(backgroundColor);
((TextView) view.findViewById(R.id.snackbar_text)).setTextColor(messageColor);
((TextView) view.findViewById(R.id.snackbar_text)).setGravity(gravity);
}
}
/**
* 向SnackBar中添加view
*
* @param snackbar
* @param layoutId
* @param index 新加布局在SnackBar中的位置
*/
public static void SnackbarAddView(Snackbar snackbar, int layoutId, int index) {
View snackbarview = snackbar.getView();
Snackbar.SnackbarLayout snackbarLayout = (Snackbar.SnackbarLayout) snackbarview;
View add_view = LayoutInflater.from(snackbarview.getContext()).inflate(layoutId, null);
LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
p.gravity = Gravity.CENTER_VERTICAL;
snackbarLayout.addView(add_view, index, p);
}
}