Android 工具類

前言

相信用過工具類的各位仁兄都覺得工具類好用览闰,小弟不才吨娜,今天斗膽拿出自己感覺比較順手的工具類麻顶。


1赦抖、Activity控制類

  public class ActivityCollector{
      //activity集合
     public static List<Activity> mActList = new ArrayList<Activity>();
    /**
      * 添加Activity
      * 
      * @param activity
      */
     public static void addActivity(Activity activity){
       mActList.add.add(activity);
     }
    }
    /**
      * 移除Activity
      */
      public static void removeActivity(Activity activity) {
       mActList.remove(activity);
     }
    /**
      * 退出
      */
     public static void finishAll() {
        for (Activity activity : mActList) {
          if (!activity.isFinishing()) {
              activity.finish();
       }
     }
   }
}

2、應(yīng)用市場管理類

  public class MarketUtils {
     // 360手機(jī)助手
    public static final String MARKET = "com.qihoo.appstore";
    // 淘寶手機(jī)助手
    public static final String MARKET_TAOBAO = "com.taobao.appcenter";
    // 應(yīng)用寶
    public static final String MARKET_QQDOWNLOADER = "com.tencent.Android.qqdownloader";
    // 安卓市場
    public static final String MARKET_HIAPK = "com.hiapk.marketpho";
    // 安智市場
    public static final String MARKET_GOAPK = "cn.goapk.market";
    // 包名
    public static final String APP_PACKAGE_NAME = "com.*.*";

   public MarketUtils() {
    throw new AssertionError();
}
  /**
    * 跳轉(zhuǎn)到應(yīng)用市場
    * 
    * @param appPkg
    *            :上傳到應(yīng)用市場上app的包名,不是本項(xiàng)目的包名
    * @param marketPkg
    *            :應(yīng)用市場的包名
    */
    public static void goToMarket(Context context, String packageName) {
    Uri uri = Uri.parse("market://details?id=" + packageName);
    Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri);
    try {
        context.startActivity(goToMarket);
    } catch (ActivityNotFoundException e) {
    }
}

   /**
     * 啟動App
     * 
     * @param context
     */
   public static void launchapp(Context context) {
    // 判斷是否安裝過App辅肾,否則去市場下載
    if (isAppInstalled(context, APP_PACKAGE_NAME)) {
        context.startActivity(context.getPackageManager()
            .getLaunchIntentForPackage(APP_PACKAGE_NAME));
    } else {
        goToMarket(context, APP_PACKAGE_NAME);
    }
}

     /**
       * 檢測某個應(yīng)用是否安裝
       * 
       * @param context
       * @param packageName
       * @return
       */
   public static boolean isAppInstalled(Context context, String packageName) {
    try {
        context.getPackageManager().getPackageInfo(packageName, 0);
        return true;
    } catch (NameNotFoundException e) {
        return false;
    }
}
    /**
       * 判斷市場是否存在的方法
       * 
       * @param context
       * @param packageName
       *            應(yīng)用市場包名
       * @return true or false
       */
  public static boolean isAvilible(Context context, String packageName) {
    final PackageManager packageManager = context.getPackageManager();// 獲取packagemanager
    List<PackageInfo> packageInfo = packageManager.getInstalledPackages(0);// 獲取所有已安裝程序的包信息
    List<String> NameList = new ArrayList<String>();// 用于存儲所有已安裝程序的包名
    // 從packageInfo中取出包名队萤,放入NameList中
    if (packageInfo != null) {
        for (int i = 0; i < packageInfo.size(); i++) {
            String pn = packageInfo.get(i).packageName;
            NameList.add(pn);
        }
    }
    return NameList.contains(packageName);// 判斷pName中是否有目標(biāo)程序的包名,有TRUE矫钓,沒有FALSE
}
 } 

3要尔、Toast工具類(不建議使用,請看另外一篇Android 自定義Toast新娜,并且勘誤Android工具類里面的ToastUtils

  public class ToastUtils {~
   public static Toast toast;
   public static boolean isShow = true;

   private ToastUtils() {
    // 不能被實(shí)例化
    throw new UnsupportedOperationException("cannot be instantiated");
}

    public static void showToast(Context context, String message) {
    if (toast == null) {
        toast = Toast.makeText(context, message, Toast.LENGTH_SHORT);
    } else {
        toast.setText(message);
    }
    toast.show();
}
/**
 * 屏幕中間位置顯示短時間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();
}
}

4赵辕、KeyBoardUtils

  public class KeyBoardUtils {

public KeyBoardUtils() {
    throw new AssertionError();
}

/**
 * 打卡軟鍵盤
 * 
 * @param mEditText
 *            輸入框
 * @param mContext
 *            上下文
 */
public static void openKeybord(EditText mEditText, Context mContext) {
    InputMethodManager imm = (InputMethodManager) mContext
            .getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.showSoftInput(mEditText, InputMethodManager.RESULT_SHOWN);
    imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,
            InputMethodManager.HIDE_IMPLICIT_ONLY);
}

/**
 * 關(guān)閉軟鍵盤
 * 
 * @param mEditText
 *            輸入框
 * @param mContext
 *            上下文
 */
public static void closeKeybord(EditText mEditText, Context mContext) {
    InputMethodManager imm = (InputMethodManager) mContext
            .getSystemService(Context.INPUT_METHOD_SERVICE);

    imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
}
}

5、AES工具類

  public class AESUtils {

// 密鑰算法
private static final String KEY_ALGORITHM = "AES";
// AES/CBC/PKCS7Padding 分別對應(yīng) 加密||解密算法概龄、工作模式还惠、填充方式
private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS7Padding";
// 定義自己的秘鑰
public final static String SECRETKEY = "A9e4/vnQTrKF6otAGbM6zGsulKEL7b3x";
// 位移量
public final static String DISPLACEMENT = "9mg+!7ed8b36*w`X";

/**
 * 獲取KEY
 * 
 * @return
 * @throws Exception
 */
private static byte[] getKey() throws Exception {
    return SECRETKEY.getBytes(Charset.forName("UTF-8"));
}

/**
 * 加密
 * 
 * @param toEncrypt
 *            文本
 * @return
 * 
 *         加密返回數(shù)組
 * @throws Exception
 */
@SuppressLint("TrulyRandom")
public static byte[] Encrypt(String toEncrypt) throws Exception {
    // 秘鑰
    Key secretKey = new SecretKeySpec(getKey(), KEY_ALGORITHM);
    // libs中bcprov的支持,bouncycastle支持 64 位密鑰
    Security.addProvider(new BouncyCastleProvider());
    Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
    // 獲取位移,并初始化
    final byte[] data = DISPLACEMENT.getBytes();
    IvParameterSpec mIvParameterSpec = new IvParameterSpec(data);
    // 用 iv 初始化
    cipher.init(Cipher.ENCRYPT_MODE, secretKey, mIvParameterSpec);

    final byte[] mEncrypted = cipher.doFinal(toEncrypt.getBytes(Charset
            .forName("UTF-8")));

    final byte[] mSpecEncrypted = new byte[data.length + mEncrypted.length];
    System.arraycopy(data, 0, mSpecEncrypted, 0, data.length);
    System.arraycopy(mEncrypted, 0, mSpecEncrypted, data.length,
            mEncrypted.length);
    return mSpecEncrypted;
}

/**
 * 加密數(shù)據(jù)
 * 
 * @param encryption
 * 
 *            文本
 * @return
 * 
 *         返回字符串
 * @throws Exception
 */
public static String Encryption(String encryption) throws Exception {
    byte[] entroyResult = Encrypt(encryption);
    String result = new String(Base64.encode(entroyResult, 0), "UTF-8");
    return result;
}

/**
 * 解密數(shù)據(jù)
 * 
 * @param toDecrypt
 *            文本
 * @return <br>
 *         返回字符串
 * @throws Exception
 */
public static String Decrypt(String decrypt) throws Exception {
    byte[] data = Base64.decode(decrypt, 0);
    // 秘鑰
    Key secretKey = new SecretKeySpec(getKey(), KEY_ALGORITHM);
    Security.addProvider(new BouncyCastleProvider());
    Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
    final byte[] mData = DISPLACEMENT.getBytes();
    IvParameterSpec mIvParameterSpec = new IvParameterSpec(mData);
    cipher.init(Cipher.DECRYPT_MODE, secretKey, mIvParameterSpec);
    final byte[] mEncrypted = cipher.doFinal(data);
    // 結(jié)果
    final byte[] result = new byte[mEncrypted.length - mData.length];
    System.arraycopy(mEncrypted, mData.length, result, 0, result.length);
    return new String(result);
}
}

6旁钧、APP版本工具類

  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;
}
}

7、GlideUtils

話說用開源庫的時候應(yīng)該自行封裝一下互拾,為了后面修改方便歪今。
public class GlideUtils {

public GlideUtils(){
    throw new AssertionError();
}

/**
 * 顯示照片
 * @param context
 * @param imageView
 * @param url
 */
public static void displays(Context context, ImageView imageView, Object url) {
    Glide.with(context).load(url).skipMemoryCache(true)  //跳過內(nèi)存緩存
            .diskCacheStrategy(DiskCacheStrategy.ALL) //硬盤緩存全部
           .into(imageView);
}

/**
 * 顯示圖片
 * @param context
 * @param imageView
 * @param url
 * @param tag
 */
public static void display(Context context, ImageView imageView, String url, Object tag) {
    Glide.with(context).load(url).
            error(R.drawable.ic_error).placeholder(R.drawable.ic_progress).into(imageView);
}

public static void display(Context context, ImageView imageView, String url, int progressId) {
    RequestManager manager = Glide.with(context);
    DrawableTypeRequest<String> load = manager.load(url);
    load.error(R.drawable.ic_error).placeholder(new ColorDrawable(Color.GRAY)).into
            (imageView);
    if (progressId != -1) {
        load.placeholder(progressId);
    }
}

public static void display(Context context, ImageView imageView, String url) {
    display(context, imageView, url, -1);
}

public static void cancel(Context context) {
}
/**
 * 設(shè)置磁盤緩存大小和位置,這里設(shè)置150M
 */
public static void setInnerCacheDir(Context context){
    GlideBuilder builder = new GlideBuilder(context);
    builder.setDiskCache(new InternalCacheDiskCacheFactory(context, "ImgCache", 150 * 1024 * 1024));
}

/**
 * 可以用ExternalCacheDiskCacheFactory來把你的磁盤緩存放到sd卡的公共緩存目錄上,這里默認(rèn)設(shè)置150M
 */
public static void setDiskCacheDir(Context context){
    GlideBuilder builder = new GlideBuilder(context);
    builder.setDiskCache( new ExternalCacheDiskCacheFactory(context, "ImgCache", 150 * 1024 * 1024));
}

/**
 * 清除緩存
 */
public static  void clearCache(final Context context){
    Glide.get(context).clearMemory(); //清理內(nèi)存緩存
    new Thread(new Runnable() {
        @Override
        public void run() {
            Glide.get(context).clearDiskCache(); //清理磁盤緩存
        }
    }).start();
}
}

8、緩存工具類

  public class CacheUtil {

public CacheUtil() {
    throw new UnsupportedOperationException("cannot be instantiated");
}

/**
 * 得到緩存大小
 *
 * @param context 上下文
 * @return
 * @throws IOException
 */
public static String getTotalCacheSize(Context context) throws IOException {
    //緩存大小
    long cacheSize = getFolderSize(context.getCacheDir());
    // 如果SD卡正常掛載才可以創(chuàng)建文件或者寫入文件等
    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
        cacheSize += getFolderSize(context.getCacheDir());
    }
     return  getFormatSize(cacheSize);
}

/**
 * 得到臨時緩存數(shù)據(jù)
 *
 * @param file
 * @return
 * @throws IOException
 */
public static long getFolderSize(File file) throws IOException {
    long size = 0;
    //文件
    File[] fileList = file.listFiles();
    for (int i = 0; i < fileList.length; i++) {
        if (fileList[i].isDirectory()) {
            size = size + getFolderSize(fileList[i]);
        } else {
            size = size + fileList[i].length();
        }
    }
    return size;
}

/**
 * 清除所有緩存
 */
public static void clearAllCache(Context context) {
    //刪除緩存
    deleteDir(context.getCacheDir());
    //如果存在SD卡則刪除本地緩存
    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
        deleteDir(context.getExternalCacheDir());
    }

}

/**
 * 是否刪除文件
 *
 * @return
 */
public static boolean deleteDir(File dir) {
    // 文件不為空并且是一個文件夾時
    if (dir != null && dir.isDirectory()) {
        //得到文件集合
        String[] child = dir.list();
        for (int i = 0; i < child.length; i++) {
            //是否刪除成功
            boolean isSuccess = deleteDir(new File(dir, child[i]));
            if (!isSuccess) {
                return false;
            }
        }
    }
    return dir.delete();
}

/**
 * 格式化
 *
 * @return
 */
public static String getFormatSize(double size) {
    //KB
    double kiloByte = size / 1024;
    if (kiloByte<1){
        return size+"Byte";
    }
    //MB
    double megaByte=kiloByte/1024;
    if (megaByte<1){
        //高精度計算結(jié)果
        BigDecimal result1=new BigDecimal(Double.toString(kiloByte));
        //四舍五入
        return result1.setScale(2,BigDecimal.ROUND_HALF_UP).toPlainString()+"KB";
    }
    //GB
    double gigaByte = megaByte/1024;
    if (gigaByte<1){
        BigDecimal result2= new BigDecimal(Double.toString(megaByte));
        return  result2.setScale(2,BigDecimal.ROUND_HALF_UP).toPlainString()+"MB";
    }
    //TB
    double teraByte =gigaByte/1024;
    if (teraByte<1){
        BigDecimal result3= new BigDecimal(Double.toString(gigaByte));
        return  result3.setScale(2,BigDecimal.ROUND_HALF_UP).toPlainString()+"GB";
    }
    BigDecimal result4= new BigDecimal(teraByte);
    return result4.setScale(2,BigDecimal.ROUND_HALF_UP).toPlainString()+"TB";
}
}

9颜矿、SharedPreferences封裝類

  public class SPUtils {
/**
 * 保存在手機(jī)里面的文件名
 */
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進(jìn)行了替代骑疆,目的是盡可能的使用apply代替commit
     * 因?yàn)閏ommit方法是同步的田篇,并且我們很多時候的commit操作都是UI線程中,畢竟是IO操作箍铭,盡可能異步泊柬;
     */
    SharedPreferencesCompat.apply(editor);
}

/**
 * 得到保存數(shù)據(jù)的方法,我們根據(jù)默認(rèn)值得到保存的數(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();
    }
}
}

10、手機(jī)信息采集工具類

  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是國家號碼,其次的兩位是運(yùn)營商代號刀崖,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("手機(jī)號: %s", NativePhoneNumber);
}

/**
 * IMSI是國際移動用戶識別碼的簡稱(International Mobile Subscriber Identity)
 * IMSI共有15位,其結(jié)構(gòu)如下: <br>
 * MCC+MNC+MIN <br>
 * MCC:Mobile Country Code蜂莉,移動國家碼蜡娶,共3位,中國為460;<br>
 * MNC:Mobile NetworkCode巡语,移動網(wǎng)絡(luò)碼翎蹈,共2位 <br>
 * 在中國,移動的代碼為電00和02男公,聯(lián)通的代碼為01荤堪,電信的代碼為03<br>
 * 合起來就是(也是Android手機(jī)中APN配置文件中的代碼): <br>
 * 中國移動:46000 46002 <br>
 * 中國聯(lián)通:46001 <br>
 * 中國電信:46003 <br>
 * 舉例,一個典型的IMSI號碼為460030912121001 <br>
 */
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ù)字組成的”電子串號”枢赔,它與每臺手機(jī)一一對應(yīng)澄阳,而且該碼是全世界唯一的 其組成為:
 * 1.前6位數(shù)(TAC)是”型號核準(zhǔn)號碼”,一般代表機(jī)型 <br>
 * 2. 接著的2位數(shù)(FAC)是”最后裝配號”踏拜,一般代表產(chǎn)地 <br>
 * 3.之后的6位數(shù)(SNR)是”串號”碎赢,一般代表生產(chǎn)順序號 <br>
 * 4. 最后1位數(shù)(SP)通常是”0″,為檢驗(yàn)碼速梗,目前暫備用<br>
 */
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)

/**
 * 雙卡雙待神機(jī)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 神機(jī)的雙卡 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 神機(jī)的雙卡 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. 獲取 高通 神機(jī)的雙卡 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>
 * 獲取 展訊 神機(jī)的雙卡 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;
}

/**
 * 獲取 開機(jī)時間
 */
public static String getBootTimeString() {
    long ut = SystemClock.elapsedRealtime() / 1000;
    int h = (int) ((ut / 3600));
    int m = (int) ((ut / 60) % 60);

    return h + ":" + m;
}
}

11拷窜、CommonUtils

  public class CommonUtils {

static Context context;
// 手機(jī)網(wǎng)絡(luò)類型
public static final int NETTYPE_WIFI = 0x01;
public static final int NETTYPE_CMWAP = 0x02;
public static final int NETTYPE_CMNET = 0x03;

public static boolean GTE_HC;
public static boolean GTE_ICS;
public static boolean PRE_HC;
private static Boolean _hasBigScreen = null;
private static Boolean _hasCamera = null;
private static Boolean _isTablet = null;
private static Integer _loadFactor = null;

private static int _pageSize = -1;
public static float displayDensity = 0.0F;
public static final String TAG = context.getClass().getSimpleName();

static {
    GTE_ICS = Build.VERSION.SDK_INT >= 14;
    GTE_HC = Build.VERSION.SDK_INT >= 11;
    PRE_HC = Build.VERSION.SDK_INT >= 11 ? false : true;
}

public CommonUtils() {
    throw new AssertionError();
}

/**
 * 獲取系統(tǒng)當(dāng)前當(dāng)前時間戳
 */

public static String getTimesTamp() {
    long timestamp = System.currentTimeMillis() / 1000;
    return String.valueOf(timestamp);
}

public static int[] getRealScreenSize(Activity activity) {
    int[] size = new int[2];
    int screenWidth = 0, screenHeight = 0;
    WindowManager w = activity.getWindowManager();
    Display d = w.getDefaultDisplay();
    DisplayMetrics metrics = new DisplayMetrics();
    d.getMetrics(metrics);
    // since SDK_INT = 1;
    screenWidth = metrics.widthPixels;
    screenHeight = metrics.heightPixels;
    // includes window decorations (statusbar bar/menu bar)
    if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17)
        try {
            screenWidth = (Integer) Display.class.getMethod("getRawWidth")
                    .invoke(d);
            screenHeight = (Integer) Display.class
                    .getMethod("getRawHeight").invoke(d);
        } catch (Exception ignored) {
        }
    // includes window decorations (statusbar bar/menu bar)
    if (Build.VERSION.SDK_INT >= 17)
        try {
            Point realSize = new Point();
            Display.class.getMethod("getRealSize", Point.class).invoke(d,
                    realSize);
            screenWidth = realSize.x;
            screenHeight = realSize.y;
        } catch (Exception ignored) {
        }
    size[0] = screenWidth;
    size[1] = screenHeight;
    return size;
}

/**
 * 是否存在相機(jī)
 * 
 * @return
 */
public static final boolean hasCamera(Context context) {
    if (_hasCamera == null) {
        PackageManager pckMgr = context.getPackageManager();
        boolean flag = pckMgr
                .hasSystemFeature("android.hardware.camera.front");
        boolean flag1 = pckMgr.hasSystemFeature("android.hardware.camera");
        boolean flag2;
        if (flag || flag1)
            flag2 = true;
        else
            flag2 = false;
        _hasCamera = Boolean.valueOf(flag2);
    }
    return _hasCamera.booleanValue();
}

/**
 * 判斷是否有物理的menu鍵
 * 
 * @param context
 * @return
 */
public static boolean hasHardwareMenuKey(Context context) {
    boolean flag = false;
    if (PRE_HC)
        flag = true;
    else if (GTE_ICS) {
        flag = ViewConfiguration.get(context).hasPermanentMenuKey();
    } else
        flag = false;
    return flag;
}

/**
 * 是否有g(shù)oogle商店
 * 
 * @param activity
 * @param pck
 * @return
 */
public static boolean gotoGoogleMarket(Activity activity, String pck) {
    try {
        Intent intent = new Intent();
        intent.setPackage("com.android.vending");
        intent.setAction(Intent.ACTION_VIEW);
        intent.setData(Uri.parse("market://details?id=" + pck));
        activity.startActivity(intent);
        return true;
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

/**
 * 隱藏動畫視圖
 * 
 * @param view
 */
public static void hideAnimatedView(View view) {
    if (PRE_HC && view != null)
        view.setPadding(view.getWidth(), 0, 0, 0);
}

/**
 * 顯示動畫視圖
 * 
 * @param view
 */
public static void showAnimatedView(View view) {
    if (PRE_HC && view != null)
        view.setPadding(0, 0, 0, 0);
}

/**
 * 顯示鍵盤dialog
 * 
 * @param dialog
 */
public static void showSoftKeyboard(Dialog dialog) {
    dialog.getWindow().setSoftInputMode(4);
}

/**
 * 切換鍵盤
 * 
 * @param view
 */

public static void toogleSoftKeyboard(Context context, View view) {
    ((InputMethodManager) context
            .getSystemService(Context.INPUT_METHOD_SERVICE))
            .toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
}

/**
 * 判斷是否橫屏
 * 
 * @return
 */
public static boolean isLandscape(Context context) {
    boolean flag;
    if (context.getResources().getConfiguration().orientation == 2)
        flag = true;
    else
        flag = false;
    return flag;
}

/**
 * 判斷是否豎屏
 * 
 * @return
 */

public static boolean isPortrait(Context context) {
    boolean flag = true;
    if (context.getResources().getConfiguration().orientation != 1)
        flag = false;
    return flag;
}

/**
 * 判斷是否平板
 * 
 * @return
 */

public static boolean isTablet(Context context) {
    if (_isTablet == null) {
        boolean flag;
        if ((0xf & context.getResources().getConfiguration().screenLayout) >= 3)
            flag = true;
        else
            flag = false;
        _isTablet = Boolean.valueOf(flag);
    }
    return _isTablet.booleanValue();
}

/**
 * 判斷是否有sd卡
 * 
 * @return
 */

public static boolean isSdcardReady() {
    return Environment.MEDIA_MOUNTED.equals(Environment
            .getExternalStorageState());
}

/**
 * 判斷系統(tǒng)語言國家
 * 
 * @return
 */
public static String getCurCountryLan(Context context) {
    return context.getResources().getConfiguration().locale.getLanguage()
            + "-"
            + context.getResources().getConfiguration().locale.getCountry();
}

/**
 * 判斷是否中文簡體(CN)國家中國
 * 
 * @return
 */

public static boolean isZhCN(Context context) {
    String lang = context.getResources().getConfiguration().locale
            .getCountry();
    if (lang.equalsIgnoreCase("CN")) {
        return true;
    }
    return false;
}

/**
 * 獲取兩個數(shù)的百分比
 * 
 * @param p1
 * @param p2
 * @return
 */
public static String percent(double p1, double p2) {
    String str;
    double p3 = p1 / p2;
    NumberFormat nf = NumberFormat.getPercentInstance();
    nf.setMinimumFractionDigits(5);// 保留的小數(shù)位數(shù)(精度)
    str = nf.format(p3);
    return str;
}

public static String percent2(double p1, double p2) {
    String str;
    double p3 = p1 / p2;
    NumberFormat nf = NumberFormat.getPercentInstance();
    nf.setMinimumFractionDigits(0);
    str = nf.format(p3);
    return str;
}

/**
 * 打開本app在應(yīng)用商店的頁面
 * 
 * @param context
 */
public static void openAppInMarket(Context context) {

    if (context != null) {
        String pckName = context.getPackageName();
        try {
            String str = "market://details?id=" + pckName;
            Intent localIntent = new Intent("android.intent.action.VIEW");
            localIntent.setData(Uri.parse(str));
            context.startActivity(localIntent);

        } catch (Exception ex) {

        }
    }
}

/**
 * 全屏顯示,去掉頂部狀態(tài)欄
 * 
 * @param activity
 */
public static void setFullScreen(Activity activity) {
    WindowManager.LayoutParams params = activity.getWindow()
            .getAttributes();
    params.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
    activity.getWindow().setAttributes(params);
    activity.getWindow().addFlags(
            WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}

/**
 * 關(guān)閉全屏顯示
 * 
 * @param activity
 */
public static void cancelFullScreen(Activity activity) {
    WindowManager.LayoutParams params = activity.getWindow()
            .getAttributes();
    params.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
    activity.getWindow().setAttributes(params);
    activity.getWindow().clearFlags(
            WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}

/**
 * 得到應(yīng)用包名
 * 
 * @param pckName
 * @return
 */
public static PackageInfo getPackageInfo(Context context, String pckName) {
    try {
        return context.getPackageManager().getPackageInfo(pckName, 0);
    } catch (PackageManager.NameNotFoundException e) {
        Log.e("", e.getMessage());
    }
    return null;
}

/**
 * 獲取版本名稱
 * 
 * @return
 */
public static String getVersionName(Context context) {
    String name = "";
    try {
        name = context.getPackageManager().getPackageInfo(
                context.getPackageName(), 0).versionName;
    } catch (PackageManager.NameNotFoundException ex) {
        name = "";
    }
    return name;
}

/**
 * 安裝apk
 * 
 * @param context
 * @param file
 */
public static void installAPK(Context context, File file) {
    if (file == null || !file.exists())
        return;
    Intent intent = new Intent();
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setAction(Intent.ACTION_VIEW);
    intent.setDataAndType(Uri.fromFile(file),
            "application/vnd.android.package-archive");
    context.startActivity(intent);
}

/**
 * 獲得安轉(zhuǎn)的apk
 * 
 * @param file
 * @return
 */
public static Intent getInstallApkIntent(File file) {
    Intent intent = new Intent();
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setAction(Intent.ACTION_VIEW);
    intent.setDataAndType(Uri.fromFile(file),
            "application/vnd.android.package-archive");
    return intent;
}

/**
 * 打電話
 * 
 * @param context
 * @param number
 */
public static void openDial(Context context, String number) {
    Uri uri = Uri.parse("tel:" + number);
    Intent it = new Intent(Intent.ACTION_DIAL, uri);
    context.startActivity(it);
}

/**
 * 發(fā)短信
 * 
 * @param context
 * @param smsBody
 * @param tel
 */

public static void openSMS(Context context, String smsBody, String tel) {
    Uri uri = Uri.parse("smsto:" + tel);
    Intent it = new Intent(Intent.ACTION_SENDTO, uri);
    it.putExtra("sms_body", smsBody);
    context.startActivity(it);
}

public static void openDail(Context context) {
    Intent intent = new Intent(Intent.ACTION_DIAL);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(intent);
}

public static void openSendMsg(Context context) {
    Uri uri = Uri.parse("smsto:");
    Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(intent);
}

/**
 * 調(diào)用系統(tǒng)相機(jī)
 * 
 * @param context
 */
public static void openCamera(Context context) {
    Intent intent = new Intent(); // 調(diào)用照相機(jī)
    intent.setAction("android.media.action.STILL_IMAGE_CAMERA");
    intent.setFlags(0x34c40000);
    context.startActivity(intent);
}

/**
 * 獲取移動設(shè)備標(biāo)識碼 需要權(quán)限android.permission.READ_PHONE_STATE
 * 
 * @return
 */
public static String getIMEI(Context context) {
    TelephonyManager tel = (TelephonyManager) context
            .getSystemService(Context.TELEPHONY_SERVICE);
    return tel.getDeviceId();
}

/**
 * 獲得手機(jī)型號
 * 
 * @return
 */
public static String getPhoneType() {
    return Build.MODEL;
}

/**
 * 打開手機(jī)上安裝的指定包名的app
 * 
 * @param context
 * @param packageName
 */
public static void openApp(Context context, String packageName) {
    Intent mainIntent = context.getPackageManager()
            .getLaunchIntentForPackage(packageName);
    if (mainIntent == null) {
        mainIntent = new Intent(packageName);
    } else {
        Log.i(TAG, "Action:" + mainIntent.getAction());
    }
    context.startActivity(mainIntent);
}

public static boolean openAppActivity(Context context, String packageName,
        String activityName) {
    Intent intent = new Intent(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_LAUNCHER);
    ComponentName cn = new ComponentName(packageName, activityName);
    intent.setComponent(cn);
    try {
        context.startActivity(intent);
        return true;
    } catch (Exception e) {
        return false;
    }
}

/**
 * 發(fā)送郵件
 * 
 * @param context
 * @param subject
 *            主題
 * @param content
 *            內(nèi)容
 * @param emails
 *            郵件地址
 */
public static void sendEmail(Context context, String subject,
        String content, String... emails) {
    try {
        Intent intent = new Intent(Intent.ACTION_SEND);
        // 模擬器
        // intent.setType("text/plain");
        intent.setType("message/rfc822"); // 真機(jī)
        intent.putExtra(Intent.EXTRA_EMAIL, emails);
        intent.putExtra(Intent.EXTRA_SUBJECT, subject);
        intent.putExtra(Intent.EXTRA_TEXT, content);
        context.startActivity(intent);
    } catch (ActivityNotFoundException e) {
        e.printStackTrace();
    }
}

public static boolean hasStatusBar(Activity activity) {
    WindowManager.LayoutParams attrs = activity.getWindow().getAttributes();
    if ((attrs.flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) == WindowManager.LayoutParams.FLAG_FULLSCREEN) {
        return false;
    } else {
        return true;
    }
}

/**
 * 調(diào)用系統(tǒng)安裝了的應(yīng)用分享
 * 
 * @param context
 * @param title
 * @param url
 */
public static void showSystemShareOption(Activity context,
        final String title, final String url) {
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setType("text/plain");
    intent.putExtra(Intent.EXTRA_SUBJECT, "分享:" + title);
    intent.putExtra(Intent.EXTRA_TEXT, title + " " + url);
    context.startActivity(Intent.createChooser(intent, "選擇分享"));
}

/**
 * 獲取當(dāng)前網(wǎng)絡(luò)類型
 * 
 * @return 0:沒有網(wǎng)絡(luò) 1:WIFI網(wǎng)絡(luò) 2:WAP網(wǎng)絡(luò) 3:NET網(wǎng)絡(luò)
 */
public static int getNetworkType(Context context) {
    int netType = 0;
    ConnectivityManager connectivityManager = (ConnectivityManager) context
            .getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
    if (networkInfo == null) {
        return netType;
    }
    int nType = networkInfo.getType();
    if (nType == ConnectivityManager.TYPE_MOBILE) {
        String extraInfo = networkInfo.getExtraInfo();
        if (!TextUtils.isEmpty(extraInfo)) {
            if (extraInfo.toLowerCase().equals("cmnet")) {
                netType = NETTYPE_CMNET;
            } else {
                netType = NETTYPE_CMWAP;
            }
        }
    } else if (nType == ConnectivityManager.TYPE_WIFI) {
        netType = NETTYPE_WIFI;
    }
    return netType;
}
 }

12涧黄、打開地圖工具類

  public class OpenLocalMapUtil {

public OpenLocalMapUtil() {
    throw new AssertionError();
}

/**
 * 高德地圖應(yīng)用是否安裝
 * 
 * @return
 */
public static boolean isGdMapInstalled() {
    return isInstallPackage("com.autonavi.minimap");
}

/**
 * 百度地圖應(yīng)用是否安裝
 * 
 * @return
 */
public static boolean isBaiduMapInstalled() {
    return isInstallPackage("com.baidu.BaiduMap");
}

private static boolean isInstallPackage(String packageName) {
    return new File("/data/data/" + packageName).exists();
}

/**
 * 獲取打開百度地圖應(yīng)用uri [http://lbsyun.baidu.com/index.php?title=uri/api/android]
 * 
 * @param originLat
 * @param originLon
 * @param desLat
 * @param desLon
 * @return
 */
public static String getBaiduMapUri(String originLat, String originLon,
        String originName, String desLat, String desLon,
        String destination, String region, String src) {
    String uri = "intent://map/direction?origin=latlng:%1$s,%2$s|name:%3$s"
            + "&destination=latlng:%4$s,%5$s|name:%6$s&mode=driving&region=%7$s&src=%8$s#Intent;"
            + "scheme=bdapp;package=com.baidu.BaiduMap;end";

    return String.format(uri, originLat, originLon, originName, desLat,
            desLon, destination, region, src);
}

/**
 * 獲取打開高德地圖應(yīng)用uri
 */
public static String getGdMapUri(String appName, String slat, String slon,
        String sname, String dlat, String dlon, String dname) {
    String uri = "androidamap://route?sourceApplication=%1$s&slat=%2$s&slon=%3$s&sname=%4$s&dlat=%5$s&dlon=%6$s&dname=%7$s&dev=0&m=0&t=2";
    return String
            .format(uri, appName, slat, slon, sname, dlat, dlon, dname);
}

/**
 * 網(wǎng)頁版百度地圖 有經(jīng)緯度
 * 
 * @param originLat
 * @param originLon
 * @param originName
 *            ->注:必填
 * @param desLat
 * @param desLon
 * @param destination
 * @param region
 *            : 當(dāng)給定region時篮昧,認(rèn)為起點(diǎn)和終點(diǎn)都在同一城市,除非單獨(dú)給定起點(diǎn)或終點(diǎn)的城市笋妥。-->注:必填懊昨,不填不會顯示導(dǎo)航路線
 * @param appName
 * @return
 */
public static String getWebBaiduMapUri(String originLat, String originLon,
        String originName, String desLat, String desLon,
        String destination, String region, String appName) {
    String uri = "http://api.map.baidu.com/direction?origin=latlng:%1$s,%2$s|name:%3$s"
            + "&destination=latlng:%4$s,%5$s|name:%6$s&mode=driving&region=%7$s&output=html"
            + "&src=%8$s";
    return String.format(uri, originLat, originLon, originName, desLat,
            desLon, destination, region, appName);
}

/**
 * 百度地圖定位經(jīng)緯度轉(zhuǎn)高德經(jīng)緯度
 * 
 * @param bd_lat
 * @param bd_lon
 * @return
 */
public static double[] bdToGaoDe(double bd_lat, double bd_lon) {
    double[] gd_lat_lon = new double[2];
    double PI = 3.14159265358979324 * 3000.0 / 180.0;
    double x = bd_lon - 0.0065, y = bd_lat - 0.006;
    double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * PI);
    double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * PI);
    gd_lat_lon[0] = z * Math.cos(theta);
    gd_lat_lon[1] = z * Math.sin(theta);
    return gd_lat_lon;
}

/**
 * 高德地圖定位經(jīng)緯度轉(zhuǎn)百度經(jīng)緯度
 * 
 * @param gd_lon
 * @param gd_lat
 * @return
 */
public static double[] gaoDeToBaidu(double gd_lon, double gd_lat) {
    double[] bd_lat_lon = new double[2];
    double PI = 3.14159265358979324 * 3000.0 / 180.0;
    double x = gd_lon, y = gd_lat;
    double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * PI);
    double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * PI);
    bd_lat_lon[0] = z * Math.cos(theta) + 0.0065;
    bd_lat_lon[1] = z * Math.sin(theta) + 0.006;
    return bd_lat_lon;
}
}

13、SDCard工具類

  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();
}
}

14均抽、TimeUtils

  public class TimeUtils {

public static final SimpleDateFormat DEFAULT_DATE_FORMAT = new SimpleDateFormat(
        "yyyy-MM-dd HH:mm:ss");
public static final SimpleDateFormat DATE_FORMAT_DATE = new SimpleDateFormat(
        "yyyy-MM-dd");

private TimeUtils() {
    throw new AssertionError();
}

/**
 * long time to string
 * 
 * @param timeInMillis
 * @param dateFormat
 * @return
 */
public static String getTime(long timeInMillis, SimpleDateFormat dateFormat) {
    return dateFormat.format(new Date(timeInMillis));
}

/**
 * long time to string, format is {@link #DEFAULT_DATE_FORMAT}
 * 
 * @param timeInMillis
 * @return
 */
public static String getTime(long timeInMillis) {
    return getTime(timeInMillis, DEFAULT_DATE_FORMAT);
}

/**
 * get current time in milliseconds
 * 
 * @return
 */
public static long getCurrentTimeInLong() {
    return System.currentTimeMillis();
}

/**
 * get current time in milliseconds, format is {@link #DEFAULT_DATE_FORMAT}
 * 
 * @return
 */
public static String getCurrentTimeInString() {
    return getTime(getCurrentTimeInLong());
}

/**
 * get current time in milliseconds
 * 
 * @return
 */
public static String getCurrentTimeInString(SimpleDateFormat dateFormat) {
    return getTime(getCurrentTimeInLong(), dateFormat);
}

/**
 * UTC轉(zhuǎn)換為本地時間
 * 
 * @param pattern
 * @param dateTime
 * @return
 */
public static String utc2Local(String dateTime) {
    dateTime = DEFAULT_DATE_FORMAT.format(new Date(
            (Long.valueOf(dateTime)) * 1000));
    return dateTime;
}
}

15、SnackbarUtil

  public class SnackbarUtil {

public static final   int Info = 1;
public static final  int Confirm = 2;
public static final  int Warning = 3;
public static final  int Alert = 4;


public static  int red = 0xfff44336;
public static  int green = 0xff4caf50;
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 backgroundColor){
    Snackbar snackbar = Snackbar.make(view,message, Snackbar.LENGTH_SHORT);
    setSnackbarColor(snackbar,messageColor,backgroundColor);
    return snackbar;
}

/**
 * 長顯示Snackbar油挥,自定義顏色
 * @param view
 * @param message
 * @param messageColor
 * @param backgroundColor
 * @return
 */
public static Snackbar LongSnackbar(View view, String message, int messageColor, int backgroundColor){
    Snackbar snackbar = Snackbar.make(view,message, Snackbar.LENGTH_LONG);
    setSnackbarColor(snackbar,messageColor,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 backgroundColor){
    Snackbar snackbar = Snackbar.make(view,message, Snackbar.LENGTH_INDEFINITE).setDuration(duration);
    setSnackbarColor(snackbar,messageColor,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è)類型
 * @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 Info:
            setSnackbarColor(snackbar,blue);
            break;
        case Confirm:
            setSnackbarColor(snackbar,green);
            break;
        case Warning:
            setSnackbarColor(snackbar,orange);
            break;
        case Alert:
            setSnackbarColor(snackbar, Color.YELLOW,red);
            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 backgroundColor) {
    View view = snackbar.getView();
    if(view!=null){
        view.setBackgroundColor(backgroundColor);
        ((TextView) view.findViewById(R.id.snackbar_text)).setTextColor(messageColor);
    }
}

/**
 * 向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);
}
 }

感謝

[https://github.com/Trinea/android-common/tree/master/src/cn/trinea/android/common]
[http://www.reibang.com/p/cd1e80e64311]:Android Snackbar花式使用指南

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末贤牛,一起剝皮案震驚了整個濱河市惋鹅,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌殉簸,老刑警劉巖闰集,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異般卑,居然都是意外死亡武鲁,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進(jìn)店門蝠检,熙熙樓的掌柜王于貴愁眉苦臉地迎上來沐鼠,“玉大人,你說我怎么就攤上這事叹谁∷撬螅” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵焰檩,是天一觀的道長憔涉。 經(jīng)常有香客問我,道長锅尘,這世上最難降的妖魔是什么监氢? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任布蔗,我火速辦了婚禮藤违,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘纵揍。我一直安慰自己顿乒,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布泽谨。 她就那樣靜靜地躺著璧榄,像睡著了一般特漩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上骨杂,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天涂身,我揣著相機(jī)與錄音,去河邊找鬼搓蚪。 笑死蛤售,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的妒潭。 我是一名探鬼主播悴能,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼雳灾!你這毒婦竟也來了漠酿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤谎亩,失蹤者是張志新(化名)和其女友劉穎炒嘲,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體团驱,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡摸吠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了嚎花。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片寸痢。...
    茶點(diǎn)故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖紊选,靈堂內(nèi)的尸體忽然破棺而出啼止,到底是詐尸還是另有隱情,我是刑警寧澤兵罢,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布献烦,位于F島的核電站,受9級特大地震影響卖词,放射性物質(zhì)發(fā)生泄漏巩那。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一此蜈、第九天 我趴在偏房一處隱蔽的房頂上張望即横。 院中可真熱鬧,春花似錦裆赵、人聲如沸东囚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽页藻。三九已至桨嫁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間份帐,已是汗流浹背璃吧。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留废境,地道東北人肚逸。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像彬坏,于是被迫代替她去往敵國和親朦促。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容