文/程序員男神
前言
今早起的還算早床绪,看了一場NBA,一想到工作還沒給答復(fù)客情,心里就有點著急了。中午定了份外賣癞己,心酸的吃著土豆絲膀斋,好心酸,這時女朋友發(fā)來微信痹雅,說今晚我們?nèi)タ次也皇桥私鹕彴裳龅#∵€記得在北京的時候這電影就一直在宣傳,聽到這個消息绩社,心情好了那么點摔蓝。把昨天整理的代碼寫篇文章平復(fù)一下糟糕的心情。今天帶來了基本每個項目中都會使用的工具類愉耙。前方代碼較多......
工具類
1项鬼、日志工具類
package com.example.dj.testdemo.Utils;
import com.example.dj.testdemo.BuildConfig;
/**
* 描述:日志工具類
* <p>
* 這個工具類主要在三處地方做了封裝。
* 第一是加入BuildConfig.DEBUG判斷劲阎,這樣發(fā)布時就不會打印log绘盟,如果不了解BuildConfig,可以參考這篇文章Android BuildConfig.DEBUG的妙用
* 第二是log工具類都常見的悯仙,預(yù)設(shè)置TAG龄毡,這樣不用每次都傳兩個參數(shù)
* 第三,通過StackTraceElement獲取當(dāng)前打印日志的類名和方法名锡垄,這個用來代替我們平時手寫的TAG值沦零。StackTrace用棧的形式保存了方法的調(diào)用信息。
* 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獲取當(dāng)前打印日志的類名和方法名货岭,這個用來代替我們平時手寫的TAG值路操。
// StackTrace用棧的形式保存了方法的調(diào)用信息
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判斷,這樣發(fā)布時就不會打印log屯仗,如果不了解BuildConfig搞坝,可以參考這篇文章Android BuildConfig.DEBUG的妙用
第二是log工具類都常見的,預(yù)設(shè)置TAG魁袜,這樣不用每次都傳兩個參數(shù)
第三是通過StackTraceElement獲取當(dāng)前打印日志的類名和方法名桩撮,這個用來代替我們平時手寫的TAG值。StackTrace用棧的形式保存了方法的調(diào)用信息峰弹。對StackTrace不了解的同學(xué)可以參考這篇文章StackTrace簡述以及StackTraceElement使用實例
2店量、Toast統(tǒng)一管理工具類
package com.example.dj.testdemo.Utils;
import android.content.Context;
import android.view.Gravity;
import android.widget.Toast;
/**
* 描述:統(tǒng)一管理類
* <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的實現(xiàn)。
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";
/**
* 保存數(shù)據(jù)的方法诬滩,我們需要拿到保存數(shù)據(jù)的具體類型,然后根據(jù)類型調(diào)用不同的保存方法
*
* @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);
}
/**
* 得到保存數(shù)據(jù)的方法,我們根據(jù)默認值得到保存的數(shù)據(jù)的具體類型捌朴,然后調(diào)用相對于的方法獲取值
*
* @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值已經(jīng)對應(yīng)的值
*
* @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);
}
/**
* 清除所有數(shù)據(jù)
*
* @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是否已經(jīng)存在
*
* @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();
}
/**
* 創(chuàng)建一個解決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執(zhí)行吴攒,否則使用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相當(dāng)于commit來說是new API呢败许,為了更好的兼容,我們做了適配淑蔚;
4市殷、單位轉(zhuǎn)換工具類
package com.example.dj.testdemo.Utils;
import android.content.Context;
import android.util.TypedValue;
/**
* 描述:單位轉(zhuǎn)換輔助類
* <p>
* Created by dj on 2016/11/17 0017.
*/
public class DensityUtils {
private DensityUtils() {
//不能被實例化
new UnsupportedOperationException("cannot be instantiated");
}
/**
* dp轉(zhuǎn)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轉(zhuǎn)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轉(zhuǎn)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轉(zhuǎn)sp
*
* @param context
* @param pxVal
* @return
*/
public static float px2sp(Context context, float pxVal) {
return (pxVal / context.getResources().getDisplayMetrics().scaledDensity);
}
}
5、SCard相關(guān)工具類
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());
// 獲取空閑的數(shù)據(jù)塊的數(shù)量
long availableBlocks = (long) stat.getAvailableBlocks() - 4;
// 獲取單個數(shù)據(jù)塊的大惺丁(byte)
long freeBlocks = stat.getAvailableBlocks();
return freeBlocks * availableBlocks;
}
return 0;
}
/**
* 獲取指定路徑所在空間的剩余可用容量字節(jié)數(shù)被丧,單位byte
*
* @param filePath
* @return 容量字節(jié) SDCard可用空間盟戏,內(nèi)部存儲可用空間
*/
public static long getFreeBytes(String filePath) {
// 如果是sd卡的下的路徑绪妹,則獲取sd卡可用容量
if (filePath.startsWith(getSDCardPath())) {
filePath = getSDCardPath();
} else {// 如果是內(nèi)部存儲的路徑,則獲取內(nèi)存存儲的可用容量
filePath = Environment.getDataDirectory().getAbsolutePath();
}
StatFs stat = new StatFs(filePath);
long availableBlocks = (long) stat.getAvailableBlocks() - 4;
return stat.getBlockSize() * availableBlocks;
}
/**
* 獲取系統(tǒng)存儲路徑
*
* @return
*/
public static String getRootDirectoryPath() {
return Environment.getRootDirectory().getAbsolutePath();
}
}
6柿究、屏幕相關(guān)工具類
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;
/**
* 描述:屏幕相關(guān)輔助類
* <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;
}
/**
* 獲得狀態(tài)欄的高度
*
* @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;
}
/**
* 獲取當(dāng)前屏幕截圖邮旷,包含狀態(tài)欄
*
* @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;
}
/**
* 獲取當(dāng)前屏幕截圖,不包含狀態(tài)欄
*
* @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 {
/**
* 獲取應(yīng)用程序名稱
* @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 當(dāng)前應(yīng)用的版本號
*/
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 服務(wù)器版本
* @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婶肩、網(wǎng)絡(luò)相關(guān)輔助類
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;
/**
* 描述:網(wǎng)絡(luò)輔助類
* <p>
* Created by dj on 2016/11/17 0017.
*/
public class NetUtils {
private NetUtils() {
/* cannot be instantiated */
throw new UnsupportedOperationException("cannot be instantiated");
}
/**
* 判斷網(wǎng)絡(luò)是否連接
*
* @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;
}
/**
* 打開網(wǎng)絡(luò)設(shè)置界面
*/
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("系統(tǒng)時間:").append(time).append("\n");
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String IMSI = tm.getSubscriberId();
//IMSI前面三位460是國家號碼貌夕,其次的兩位是運營商代號律歼,00、02是中國移動啡专,01是聯(lián)通险毁,03是電信。
String providerName = null;
if (IMSI != null) {
if (IMSI.startsWith("46000") || IMSI.startsWith("46002")) {
providerName = "中國移動";
} else if (IMSI.startsWith("46001")) {
providerName = "中國聯(lián)通";
} else if (IMSI.startsWith("46003")) {
providerName = "中國電信";
}
}
sb.append(providerName).append("\n").append(getNativePhoneNumber(context)).append("\n網(wǎng)絡(luò)模式:").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();
}
/**
* 打印系統(tǒng)信息
*
* @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("_______ 系統(tǒng)信息 ").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();
}
/****
* 獲取網(wǎng)絡(luò)類型
*
* @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 "";
}
}
/**
* 獲取當(dāng)前設(shè)置的電話號碼
*/
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位们童,其結(jié)構(gòu)如下:
* MCC+MNC+MIN
* MCC:Mobile Country Code畔况,移動國家碼,共3位慧库,中國為460;
* MNC:Mobile NetworkCode跷跪,移動網(wǎng)絡(luò)碼,共2位
* 在中國齐板,移動的代碼為電00和02吵瞻,聯(lián)通的代碼為01,電信的代碼為03
* 合起來就是(也是Android手機中APN配置文件中的代碼):
* 中國移動:46000 46002
* 中國聯(lián)通: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 (國際移動設(shè)備標(biāo)識)的簡稱
* IMEI由15位數(shù)字組成的”電子串號”听皿,它與每臺手機一一對應(yīng),而且該碼是全世界唯一的
* 其組成為:
* 1. 前6位數(shù)(TAC)是”型號核準(zhǔn)號碼”宽档,一般代表機型
* 2. 接著的2位數(shù)(FAC)是”最后裝配號”尉姨,一般代表產(chǎn)地
* 3. 之后的6位數(shù)(SNR)是”串號”,一般代表生產(chǎn)順序號
* 4. 最后1位數(shù)(SP)通常是”0″吗冤,為檢驗碼又厉,目前暫備用
*/
public static String getIMEI(Context context) {
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String IMEI = telephonyManager.getDeviceId();
return IMEI;
}
/////_________________ 雙卡雙待系統(tǒng)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當(dāng)前app版本號:" + VersionUtil.getVersion(context)
+ "\n############################errorMessage end##############################";
}
}
11、Snackbar的工具類
使用方法:
使用Snackbar要導(dǎo)入com.android.support:design庫璧诵。
bug:設(shè)置的位置為什么沒有效果汰蜘??之宿?
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色难,可選預(yù)設(shè)類型
*
* @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,可選預(yù)設(shè)類型
*
* @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等缀,可選預(yù)設(shè)類型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;
}
//選擇預(yù)設(shè)類型
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;
}
}
/**
* 設(shè)置SnackBar背景顏色
*
* @param snackbar
* @param backgroundColor
*/
public static void setSnackbarColor(Snackbar snackbar, int backgroundColor) {
View view = snackbar.getView();
if (view != null) {
view.setBackgroundColor(backgroundColor);
}
}
/**
* 設(shè)置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);
}
}