/* * Copyright (C) 2014 The AppCan Open Source Project. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ package org.zywx.wbpalmstar.base; import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.AssetFileDescriptor; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.Color; import android.graphics.Matrix; import android.net.Uri; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Environment; import android.support.annotation.Keep; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Xml; import org.xmlpull.v1.XmlPullParser; import org.zywx.wbpalmstar.acedes.ACEDes; import org.zywx.wbpalmstar.engine.EBrowserView; import org.zywx.wbpalmstar.engine.universalex.EUExUtil; import org.zywx.wbpalmstar.platform.encryption.PEncryption; import org.zywx.wbpalmstar.platform.push.report.PushReportConstants; import org.zywx.wbpalmstar.widgetone.dataservice.WDataManager; import org.zywx.wbpalmstar.widgetone.dataservice.WWidgetData; import org.zywx.wbpalmstar.widgetone.dataservice.WidgetPackageMgr; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class BUtility { public final static String F_SDCARD_PATH = "file:///sdcard/"; public final static String F_RES_PATH = "file:///res/"; public final static String F_DATA_PATH = "file:///data/"; public final static String F_HTTP_PATH = "http://"; public final static String F_RTSP_PATH = "rtsp://"; public final static String F_RES_ROOT_PATH = "file:///res/widget/"; public final static String F_ASSET_PATH = "file:///android_asset/"; public final static String F_RAW_PATH = "raw/"; public final static String F_FILE_SCHEMA = "file://"; public final static String F_APP_SCHEMA = "wgt://"; public final static String F_WIDGET_SCHEMA = "wgts://"; public final static String F_BASE_WGT_PATH = "widgetone/"; public final static String F_APP_PATH = "widgetone/apps/"; public final static String F_WIDGET_PATH = "widgetone/widgets/"; public final static String F_WIDGET_APP_PATH = "widgetone/widgetapp/"; public final static String F_APP_VIDEO = "video/"; public final static String F_APP_PHOTO = "photo/"; public final static String F_APP_AUDIO = "audio/"; public final static String F_APP_MYSPACE = "myspace/"; public final static String F_Widget_RES_path = "widget/wgtRes/"; public final static String F_WIDGET_PLUGIN_PATH = "widget/plugin/"; public final static String F_Widget_RES_SCHEMA = "res://"; public final static String F_SBOX_SCHEMA = "box://"; public final static String F_EXTERBOX_SCHEMA = "exterbox://"; public final static String m_loadingImageSp = "loadingImageSp"; public final static String m_loadingImagePath = "loadingImagePath"; public final static String m_loadingImageTime = "loadingImageTime"; public static boolean isDes = false; public static String g_desPath = ""; public static String widgetOneRootPath = ""; /** * 安装补丁包类型 1:网页包;2:插件包;3:网页和插件 */ public final static int INSTALL_PATCH_WIDGET = 1; public final static int INSTALL_PATCH_PLUGIN = 2; public final static int INSTALL_PATCH_ALL = 3; public final static int PATCH_WIDGET_FLAG = 1; public final static int PATCH_PLUGIN_FLAG = 2; // 缩放图片 public static Bitmap imageScale(Bitmap bitmap, int dst_w, int dst_h) { int src_w = bitmap.getWidth(); int src_h = bitmap.getHeight(); float scale_w = ((float) dst_w) / src_w; float scale_h = ((float) dst_h) / src_h; Matrix matrix = new Matrix(); matrix.postScale(scale_w, scale_h); Bitmap dstbmp = Bitmap.createBitmap(bitmap, 0, 0, src_w, src_h, matrix, true); return dstbmp; } public static InputStream compress(Context m_eContext, String path, int compress, float with) throws OutOfMemoryError, IOException { FileDescriptor fileDescriptor = null; boolean isRes = false; if (!path.startsWith("/")) { AssetFileDescriptor assetFileDescriptor = m_eContext.getAssets() .openFd(path); fileDescriptor = assetFileDescriptor.getFileDescriptor(); isRes = true; } else { FileInputStream fis = new FileInputStream(new File(path)); fileDescriptor = fis.getFD(); } BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; Bitmap source = BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options); if (options.outHeight <= 0 || options.outWidth <= 0) { if (isRes) { return m_eContext.getAssets().open(path); } else { return new FileInputStream(new File(path)); } } int quality = 0; if (compress == 1) { quality = 100; } else if (compress == 2) { quality = 75; } else if (compress == 3) { quality = 50; } else { quality = 25; } float max = with == -1 ? 640 : with; float src_w = options.outWidth; float src_h = options.outHeight; float scaleRate = 1; if (src_h > src_w) { scaleRate = src_h / max; } else { scaleRate = src_w / max; } scaleRate = scaleRate > 1 ? scaleRate : 1; if (scaleRate != 1) { Bitmap dstbmp = null; ByteArrayOutputStream baos = new ByteArrayOutputStream(4096); options.inSampleSize = (int) scaleRate; options.inJustDecodeBounds = false; options.inInputShareable = true; options.inPurgeable = true; options.inPreferredConfig = Config.RGB_565;// 会失真,缩略图失真没事^_^ source = BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options); if (source != null) { int srcWidth = source.getWidth(); int srcHeight = source.getHeight(); final float sacleRate = Math.min(max / (float) srcWidth, max / (float) srcHeight); final int destWidth = (int) (srcWidth * sacleRate); final int destHeight = (int) (srcHeight * sacleRate); dstbmp = Bitmap.createScaledBitmap(source, destWidth, destHeight, false); if (source != null && !source.isRecycled()) { source.recycle(); } if (dstbmp.compress(CompressFormat.JPEG, quality, baos)) { if (dstbmp != null && !dstbmp.isRecycled()) { dstbmp.recycle(); } return new ByteArrayInputStream(baos.toByteArray()); } else { baos.close(); if (isRes) { return m_eContext.getAssets().open(path); } else { return new FileInputStream(new File(path)); } } } else { if (isRes) { return m_eContext.getAssets().open(path); } else { return new FileInputStream(new File(path)); } } } else { if (isRes) { return m_eContext.getAssets().open(path); } else { return new FileInputStream(new File(path)); } } } /** * @return sdcard沙箱目录路径 */ public static String getExterBoxPath(Context context) { String exterBoxPath; File file = context.getExternalFilesDir(null); if (file != null) { exterBoxPath = file.getAbsolutePath() + "/"; } else { exterBoxPath = getSdCardRootPath() + "Android/data/" + context.getPackageName() + "/files/"; } return exterBoxPath; } /** * @return 沙箱目录路径 */ public static String getSBoxRootPath(Context context) { return context.getFilesDir().getAbsolutePath() + "/"; } /** * @return 增量更新开关 */ public static boolean getIsUpdateWidget() { return WDataManager.isUpdateWidget; } /** * @return widget目录是否拷贝完成到沙箱目录 */ public static boolean getIsCopyAssetsFinish() { return WDataManager.isCopyAssetsFinish; } /** * 得到widgetone的目录路径 * * @return ../widgetone/ */ public static String getWidgetOneRootPath() { return widgetOneRootPath; } // 初始化widget的文件夹 public static void initWidgetOneFile(Context context, String appId) { String root = null; appId += "/"; if (!WDataManager.isWidgetOneSBox && sdCardIsWork()) { root = getSdCardRootPath(); } else { root = getSBoxRootPath(context); } widgetOneRootPath = root + F_BASE_WGT_PATH; String[] fileDir = {root + F_APP_PATH + appId, root + F_WIDGET_PATH, root + F_APP_PATH + appId + F_APP_VIDEO, root + F_APP_PATH + appId + F_APP_PHOTO, root + F_APP_PATH + appId + F_APP_AUDIO, root + F_APP_PATH + appId + F_APP_MYSPACE}; int size = fileDir.length; for (int i = 0; i < size; i++) { File file = new File(fileDir[i]); if (!file.exists()) { file.mkdirs(); } } String noMediaStr = root + F_BASE_WGT_PATH + ".nomedia"; File noMedia = new File(noMediaStr); if (!noMedia.exists()) { try { noMedia.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } } public static int parseColor(String inColor) { int reColor = 0; try { if (inColor != null && inColor.length() != 0) { inColor = inColor.replace(" ", ""); if (inColor.charAt(0) == 'r') { //rgba int start = inColor.indexOf('(') + 1; int off = inColor.indexOf(')'); inColor = inColor.substring(start, off); String[] rgba = inColor.split(","); int r = Integer.parseInt(rgba[0]); int g = Integer.parseInt(rgba[1]); int b = Integer.parseInt(rgba[2]); int a = Integer.parseInt(rgba[3]); reColor = (a << 24) | (r << 16) | (g << 8) | b; } else if (inColor.startsWith("#")) { // # String tmpColor = inColor.substring(1); if (3 == tmpColor.length()) { char[] t = new char[6]; t[0] = tmpColor.charAt(0); t[1] = tmpColor.charAt(0); t[2] = tmpColor.charAt(1); t[3] = tmpColor.charAt(1); t[4] = tmpColor.charAt(2); t[5] = tmpColor.charAt(2); inColor = "#" + String.valueOf(t); } reColor = Color.parseColor(inColor); } } } catch (Exception e) { e.printStackTrace(); reColor = 0; } return reColor; } // 获得屏幕像素密度 public static int getDeviceDesity(Activity activity) { DisplayMetrics dm = new DisplayMetrics(); activity.getWindowManager().getDefaultDisplay().getMetrics(dm); return dm.densityDpi; } // 获得屏幕分辨率 public static int[] getDeviceResolution(Activity activity) { int[] args = new int[2]; DisplayMetrics dm = new DisplayMetrics(); activity.getWindowManager().getDefaultDisplay().getMetrics(dm); args[0] = dm.widthPixels; args[1] = dm.heightPixels; return args; } public static byte[] transStreamToBytes(InputStream is, int buffSize) { if (is == null) { return null; } if (buffSize <= 0) { throw new IllegalArgumentException( "buffSize can not less than zero....."); } byte[] data = null; byte[] buffer = new byte[buffSize]; int actualSize = 0; ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { while ((actualSize = is.read(buffer)) != -1) { baos.write(buffer, 0, actualSize); } data = baos.toByteArray(); } catch (IOException e) { e.printStackTrace(); } finally { try { baos.close(); } catch (IOException e) { e.printStackTrace(); } } return data; } /** * 判断是否是手机号码 * * @param phoneNum <br> * 移动:134、135、136、137、138、139、150、151、157(TD)、158、159、187、188 <br> * 联通:130、131、132、152、155、156、185、186 <br> * 电信:133、153、180、189、(1349卫通) */ public static boolean isPhoneNumber(String phoneNum) { String expression = "^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$"; CharSequence inputStr = phoneNum; Pattern pattern = Pattern.compile(expression); Matcher matcher = pattern.matcher(inputStr); if (matcher.matches()) { return true; } return false; } /** * sd 卡是否工作 */ public static boolean sdCardIsWork() { if (Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)) { return true; } return false; } /** * 判断路径是否含有协议头 * * @param uri * @return */ public static boolean uriHasSchema(String uri) { if (uri == null || uri.length() == 0) { return false; } String mUri = null; int i = uri.indexOf('?'); if (i > 0) { mUri = uri.substring(0, i); } else { mUri = uri; } final Uri path = Uri.parse(mUri); if (path != null && path.getScheme() != null) { return true; } else { return false; } } /** * 得到sdcard路径 * * @return */ public static String getSdCardRootPath() { return Environment.getExternalStorageDirectory().getAbsolutePath() .replace("/mnt", "") + File.separator; } /** * 得到去掉参数的路径 * * @return */ public static String makeSpecUrl(String inBaseUrl) { Uri path = Uri.parse(inBaseUrl); String port = path.getPort() != -1 ? ":" + String.valueOf(path.getPort()) : ""; return path.getScheme() + "://" + path.getHost() + port + path.getPath(); } public static String handleRelativePath(String inUrl) { try { int index = inUrl.indexOf("../"); while (index != -1) { String beforeStr = inUrl.substring(0, index - 1); String afterStr = inUrl.substring(index + 3, inUrl.length()); inUrl = beforeStr.substring(0, beforeStr.lastIndexOf("/") + 1).concat(afterStr); index = inUrl.indexOf("../"); } return inUrl; } catch (Exception e) { } return inUrl; } public static String makeUrl(String inBaseUrl, String inUrl) { if (null == inUrl || inUrl.length() == 0) { return null; } if (null == inBaseUrl || inBaseUrl.length() == 0) { return null; } inUrl = correctFilePath(inUrl); // inUrl = URLDecoder.decode(inUrl); if (uriHasSchema(inUrl) || inUrl.startsWith("/")) { return inUrl; } // String oldBaseUrl = inBaseUrl; // ../../ int index = inUrl.indexOf("../"); int layer = 0; while (index != -1) { layer++; inUrl = inUrl.substring(index + 3, inUrl.length()); index = inUrl.indexOf("../"); } // Uri path = Uri.parse(inBaseUrl); // String port = path.getPort() != -1 ? // ":"+String.valueOf(path.getPort()) : ""; // inBaseUrl = path.getScheme() // +"://"+path.getHost()+port+path.getPath(); int count = inBaseUrl.lastIndexOf(47); while (layer >= 0) { inBaseUrl = inBaseUrl.substring(0, count); count = inBaseUrl.lastIndexOf(47); layer--; if (count == -1) { break; } } inBaseUrl += "/" + inUrl; return inBaseUrl; } /** * 根据file://res/协议的路径获得AssetFileDescriptor对象用于设置DataSource * * @param context * @return */ public static AssetFileDescriptor getFileDescriptorByResPath( Context context, String fullResPath) { if (context != null && fullResPath.startsWith(BUtility.F_Widget_RES_SCHEMA)) { final String assetFileName = F_Widget_RES_path + fullResPath.substring(F_Widget_RES_SCHEMA.length()); AssetFileDescriptor descriptor = null; try { descriptor = context.getAssets().openFd(assetFileName); } catch (IOException e) { e.printStackTrace(); } return descriptor; } else { return null; } } /** * 根据res协议路径获得资源输入流 * * @param context * @param fullResPath * @return */ public static InputStream getInputStreamByResPath(Context context, String fullResPath) { if (context != null && fullResPath.startsWith(BUtility.F_Widget_RES_SCHEMA)) { final String assetFileName = F_Widget_RES_path + fullResPath.substring(F_Widget_RES_SCHEMA.length()); InputStream is = null; try { is = context.getAssets().open(assetFileName); } catch (IOException e) { e.printStackTrace(); } return is; } else { return null; } } /** * 根据file://data/协议的路径获得其真实路径 * * @param context * @param totalPath * @return */ public static String getRealPathByDataPath(Context context, String totalPath) { if (context == null) { throw new NullPointerException("context can not be null......."); } if (totalPath == null || totalPath.length() == 0) { return null; } if (totalPath.startsWith(BUtility.F_DATA_PATH)) { return totalPath.replace(BUtility.F_DATA_PATH, F_FILE_SCHEMA + context.getFilesDir().getAbsolutePath() + "/"); } else { return null; } } /** * 制造一个真实的路径 * * @param path * @return */ @Deprecated public static String makeRealPath(String path, String widgetPath, int wgtType) { // path = makeUrl(currentUrl, path); if (path == null || path.length() == 0) { return null; } path = correctFilePath(path); if (path.startsWith(F_ASSET_PATH)) { return path.substring(F_ASSET_PATH.length()); } else if (path.startsWith(F_SDCARD_PATH)) { return getSdCardRootPath() + path.substring(F_SDCARD_PATH.length()); } else if (path.startsWith(F_FILE_SCHEMA)) { return path.substring(F_FILE_SCHEMA.length()); } if (path.startsWith(F_APP_SCHEMA)) { return widgetPath + path.substring(F_APP_SCHEMA.length()); } else if (path.startsWith(F_WIDGET_SCHEMA)) { return WDataManager.m_wgtsPath + path.substring(F_WIDGET_SCHEMA.length()); } else if (path.startsWith(F_Widget_RES_SCHEMA)) { if (wgtType == 0) { if (WDataManager.isUpdateWidget && WDataManager.isCopyAssetsFinish) { return WDataManager.m_sboxPath + F_Widget_RES_path + path.substring(F_Widget_RES_SCHEMA.length()); } else { return F_Widget_RES_path + path.substring(F_Widget_RES_SCHEMA.length()); } } else { return widgetPath + "wgtRes/" + path.substring(F_Widget_RES_SCHEMA.length()); } } else if (path.startsWith(F_SBOX_SCHEMA)) { return WDataManager.m_sboxPath + path.substring(F_SBOX_SCHEMA.length()); } else if (path.startsWith(F_EXTERBOX_SCHEMA)) { return WDataManager.m_exterboxPath + path.substring(F_EXTERBOX_SCHEMA.length()); } else { return path; } } /** * 制造一个真实的路径 * * @return */ @Keep public static String makeRealPath(String path, EBrowserView browserView) { path = makeUrl(browserView.getCurrentUrl(), path); WWidgetData currentWidget = browserView.getCurrentWidget(); if (currentWidget == null) {//当前没有widget时,取rootWidget currentWidget = WDataManager.sRootWgt; } if (currentWidget == null) { BDebug.e("currentWidget is null"); return null; } int wgtType = currentWidget.m_wgtType; String widgetPath = currentWidget.getWidgetPath(); String appId = currentWidget.m_appId; if (path == null || path.length() == 0) { return null; } if (path.startsWith(F_ASSET_PATH)) { path = path.substring(F_ASSET_PATH.length()); } else if (path.startsWith(F_SDCARD_PATH)) { path = getSdCardRootPath() + path.substring(F_SDCARD_PATH.length()); } else if (path.startsWith(F_FILE_SCHEMA)) { path = path.substring(F_FILE_SCHEMA.length()); } if (path.startsWith(F_APP_SCHEMA)) { path = widgetPath + path.substring(F_APP_SCHEMA.length()); } else if (path.startsWith(F_WIDGET_SCHEMA)) { path = WDataManager.m_wgtsPath + path.substring(F_WIDGET_SCHEMA.length()); } else if (path.startsWith(F_Widget_RES_SCHEMA)) { if (wgtType == 0) { if (WDataManager.isUpdateWidget && WDataManager.isCopyAssetsFinish) { path = WDataManager.m_sboxPath + F_Widget_RES_path + path.substring(F_Widget_RES_SCHEMA.length()); } else { path = F_Widget_RES_path + path.substring(F_Widget_RES_SCHEMA.length()); } } else if (wgtType == 3) { if (WDataManager.isUpdateWidget && WDataManager.isCopyAssetsFinish) { path = WDataManager.m_sboxPath + F_WIDGET_PLUGIN_PATH + appId + "/wgtRes/" + path.substring(F_Widget_RES_SCHEMA.length()); } else { path = F_WIDGET_PLUGIN_PATH + appId + "/wgtRes/" + path.substring(F_Widget_RES_SCHEMA.length()); } } else { path = widgetPath + "wgtRes/" + path.substring(F_Widget_RES_SCHEMA.length()); } } else if (path.startsWith(F_SBOX_SCHEMA)) { path = WDataManager.m_sboxPath + path.substring(F_SBOX_SCHEMA.length()); } else if (path.startsWith(F_EXTERBOX_SCHEMA)) { path = WDataManager.m_exterboxPath + path.substring(F_EXTERBOX_SCHEMA.length()); } return handleRelativePath(path); } /** * 纠正文件路径,兼容css url()规范: * url(a.png)等价于url( a.png ),等价于url('a.png),等价于url("a.png"),等价于url( "a.png" )。 * * @param path * @return */ private static String correctFilePath(String path) { String correctPath = path.trim(); String[] errorChar = {"\'", "\""}; for (int i = 0; i < errorChar.length; i++) { if (correctPath.startsWith(errorChar[i])) { correctPath = correctPath.substring(1); } if (correctPath.endsWith(errorChar[i])) { correctPath = correctPath.substring(0, correctPath.length() - 1); } } return correctPath; } /** * 获得带协议的全路径 * * @param inBaseUrl * @param inUrl * @return */ public static String getFullPath(String inBaseUrl, String inUrl) { String path = makeUrl(inBaseUrl, inUrl); if (path == null || path.length() == 0) { return null; } if (path.startsWith("/")) { path = F_FILE_SCHEMA + path; } return path; } public static String getSDRealPath(String totalPath, String widgetPath, int wgtType) { String path = makeRealPath(totalPath, widgetPath, wgtType); if (path != null && path.startsWith("/")) { path = F_FILE_SCHEMA + path; } return path; } /** * 是否是存在于SD上的协议路径 * * @param fullPath * @return */ public static boolean isSDcardPath(String fullPath) { if (fullPath != null && fullPath.length() > 0 && (fullPath.startsWith(BUtility.F_FILE_SCHEMA) || fullPath.startsWith(BUtility.F_APP_SCHEMA) || fullPath.startsWith(BUtility.F_WIDGET_SCHEMA) || fullPath.startsWith(BUtility.F_Widget_RES_SCHEMA) || fullPath.startsWith(BUtility.F_SDCARD_PATH) || fullPath.startsWith(BUtility.F_EXTERBOX_SCHEMA))) { return true; } else { return false; } } /** * 获取租户标示 * * @param context * @return 租户标示 */ public static String getTenantAccount(Context context) { String tenantAccountEncryption = getTenantAccountFromRes(context); if (TextUtils.isEmpty(tenantAccountEncryption)) { tenantAccountEncryption = getTenantAccountFromCache(context); } return tenantAccountEncryption; } /** * 从资源文件中获取租户标示,打包服务器配置租户ID为“0”,也认为租户为空 * * @param context * @return 租户标示 */ private static String getTenantAccountFromRes(Context context) { String tenantAccountEncryption = ""; String tenantAccount = ""; try { tenantAccount = EUExUtil.getString("tenant_id"); } catch (Exception e) { e.printStackTrace(); } tenantAccountEncryption = decryptTenantAccount(context, tenantAccount); if ("0".equals(tenantAccountEncryption)) { tenantAccountEncryption = ""; } return tenantAccountEncryption; } /** * 从本地缓存中获取租户标示 * * @param context * @return 租户标示 */ private static String getTenantAccountFromCache(Context context) { String tenantAccountEncryption = ""; String tenantAccount = ""; tenantAccount = getString(context, "app", "tenantAccount", ""); tenantAccountEncryption = decryptTenantAccount(context, tenantAccount); return tenantAccountEncryption; } private static String decryptTenantAccount(Context context, String taEncryption) { String tenantAccount = ""; if (!TextUtils.isEmpty(taEncryption)) { String mainAppId = getString(context, "app", "appid", ""); byte[] tenantAccountByte = HexStringToBinary(taEncryption); tenantAccount = new String(PEncryption.os_decrypt( tenantAccountByte, tenantAccountByte.length, mainAppId)); } return tenantAccount; } /** * 从指定SharedPreferences(spName)中获取key对应的String * * @param context * @param spName * @param key * @param defValue * @return key对应的value */ public static String getString(Context context, String spName, String key, String defValue) { SharedPreferences sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE); return sp.getString(key, defValue); } /** * 转码 */ public static String transcoding(String text) { String regEx = "\n|\r|\"|\'|\\\\|&"; /** * & 38 \n 10 换行 \r 13 回车 \' 39 单引号 \" 34 双引号 \\ 92 反斜杠 */ Pattern p = Pattern.compile(regEx); Matcher m = p.matcher(text); StringBuffer sb = new StringBuffer(); while (m.find()) { if (m.group(0).equals("\n")) { m.appendReplacement(sb, "\\\\n"); } else if (m.group(0).equals("\r")) { m.appendReplacement(sb, "\\\\r"); } else if (m.group(0).equals("\"")) { m.appendReplacement(sb, "\\\\\""); } else if (m.group(0).equals("\'")) { m.appendReplacement(sb, "\\\\'"); } else if (m.group(0).equals("\\")) { m.appendReplacement(sb, "\\\\\\\\"); } else if (m.group(0).equals("&")) { m.appendReplacement(sb, "\\\\&"); } } m.appendTail(sb); // System.out.println(sb.toString()); return sb.toString(); } /** * 判断String是否是数字 */ public static boolean isNumeric(String str) { if (str == null || str.length() == 0) { return false; } Pattern pattern = Pattern.compile("[0-9]*"); return pattern.matcher(str).matches(); } public static void alertMessage(final Activity activity, String title, String message, final boolean exitOnClicked) { new AlertDialog.Builder(activity).setTitle(title).setMessage(message) .setCancelable(false) .setPositiveButton(EUExUtil.getString("confirm"), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (exitOnClicked) { activity.finish(); } } }).show(); } public static Bitmap getLocalImg(Context ctx, String imgUrl) { if (imgUrl == null || imgUrl.length() == 0) { return null; } Bitmap bitmap = null; InputStream is = null; try { if (imgUrl.startsWith(BUtility.F_Widget_RES_SCHEMA)) { is = BUtility.getInputStreamByResPath(ctx, imgUrl); bitmap = BitmapFactory.decodeStream(is); } else if (imgUrl.startsWith(BUtility.F_FILE_SCHEMA)) { imgUrl = imgUrl.replace(BUtility.F_FILE_SCHEMA, ""); bitmap = BitmapFactory.decodeFile(imgUrl); } else if (imgUrl.startsWith(BUtility.F_Widget_RES_path)) { try { is = ctx.getAssets().open(imgUrl); if (is != null) { bitmap = BitmapFactory.decodeStream(is); } } catch (IOException e) { e.printStackTrace(); } } else if (imgUrl.startsWith("/")) { bitmap = BitmapFactory.decodeFile(imgUrl); } } catch (OutOfMemoryError e) { e.printStackTrace(); } finally { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } return bitmap; } /** * 获取真实的路径,同时拷贝res协议文件到sd卡缓存目录 * * @param mBrwView * @param url AppCan协议路径 * @return */ @Keep public static String getRealPathWithCopyRes(EBrowserView mBrwView, String url) { String realPath = makeRealPath(url, mBrwView); if (realPath.startsWith("/") && !realPath.startsWith("/data")) { return realPath; } return getResLocalPath(mBrwView.getContext(), realPath); } /** * 根据res协议获取本地路径(将文件拷贝到sd卡缓存目录) * * @param context * @param url Android assets路径,或者开启增量更新时的/data 开头路径 * @return */ public static String getResLocalPath(Context context, String url) { String resPath = url;// 获取的为assets路径 InputStream inputStream = null; OutputStream out = null; String tempPath = url; try { if (resPath.startsWith("/data")) { inputStream = new FileInputStream(new File(resPath)); } else { inputStream = context.getResources().getAssets() .open(resPath); } File cacheDir = context.getExternalCacheDir(); if (cacheDir == null) { return null; } String cachePath = cacheDir.getAbsolutePath(); tempPath = cachePath + File.separator + resPath; File file = new File(tempPath); if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } if (file.exists()) { file.delete(); } out = new FileOutputStream(file); int count = 0; byte[] buff = new byte[1024]; while ((count = inputStream.read(buff)) != -1) { out.write(buff, 0, count); } out.flush(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (inputStream != null) inputStream.close(); if (out != null) out.close(); } catch (Exception e) { e.printStackTrace(); } } return tempPath; } public static String getFileNameWithNoSuffix(String path) { String name = null; int index = path.lastIndexOf('/'); if (index > 0) { name = path.substring(index + 1, path.length()); } int index1 = name.lastIndexOf('.'); if (index1 > 0) { name = name.substring(0, index1); } return name; } /** * 获取外置SD卡路径 * * @return 路径列表 */ public static List<String> getAllExtraSdcardPath() { List<String> sdList = new ArrayList<String>(); try { Runtime runtime = Runtime.getRuntime(); Process process = runtime.exec("mount"); InputStream is = process.getInputStream(); InputStreamReader isr = new InputStreamReader(is); String line; BufferedReader br = new BufferedReader(isr); while ((line = br.readLine()) != null) { // 将常见的linux分区过滤掉 if (line.contains("secure") || line.contains("asec") || line.contains("system") || line.contains("cache") || line.contains("sys") || line.contains("data") || line.contains("tmpfs") || line.contains("shell") || line.contains("root") || line.contains("acct") || line.contains("proc") || line.contains("misc") || line.contains("obb")) { continue; } if (line.contains("fat") || line.contains("fuse") || line.contains("ntfs") || line.contains("extSdCard")) { String columns[] = line.split(" "); if (columns != null && columns.length > 1) { String path = columns[1]; if (path != null && !sdList.contains(path) && path.toLowerCase().contains("sd")) { File file = new File(path); if (file.isDirectory()) { sdList.add(columns[1]); } } } } } } catch (Exception e) { e.printStackTrace(); } return sdList; } public static Bitmap createBitmapWithStream(InputStream inputStream, int reqWidth, int reqHeight) { Bitmap bm = null; if (inputStream != null) { bm = decodeSamplerBitmap(transStreamToBytes(inputStream, 64 * 1024), reqWidth, reqHeight); } return bm; } public static Bitmap decodeSamplerBitmap(byte[] data, int reqWidth, int reqHeight) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeByteArray(data, 0, data.length, options); options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); options.inJustDecodeBounds = false; return BitmapFactory.decodeByteArray(data, 0, data.length, options); } public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { final int halfHeight = height / 2; final int halfWidth = width / 2; // Calculate the largest inSampleSize value that is a power of 2 and // keeps both // height and width larger than the requested height and width. while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) { inSampleSize *= 2; } } return inSampleSize; } public static Bitmap createBitmapWithPath(String pathName, int reqWidth, int reqHeight) { BitmapFactory.Options opts = new BitmapFactory.Options(); opts.inJustDecodeBounds = true; BitmapFactory.decodeFile(pathName, opts); opts.inSampleSize = calculateInSampleSize(opts, reqWidth, reqHeight); opts.inTempStorage = new byte[64 * 1024]; opts.inJustDecodeBounds = false; Bitmap bm = BitmapFactory.decodeFile(pathName, opts); return bm; } public static Bitmap getLoadingBitmap(Context context) { SharedPreferences sp = context.getSharedPreferences( BUtility.m_loadingImageSp, Context.MODE_PRIVATE); String path = sp.getString(m_loadingImagePath, ""); InputStream input = null; if (TextUtils.isEmpty(path)) { input = context.getResources().openRawResource( EUExUtil.getResDrawableID("startup_bg_16_9")); } else { if (path.startsWith(F_Widget_RES_path)) { try { input = context.getResources().getAssets().open(path); } catch (Exception e) { input = context.getResources().openRawResource( EUExUtil.getResDrawableID("startup_bg_16_9")); e.printStackTrace(); } } else { File file = new File(path); if (!file.exists()) { input = context.getResources().openRawResource( EUExUtil.getResDrawableID("startup_bg_16_9")); BDebug.d("The loading path " + path + " does not exist"); } } } DisplayMetrics dm = new DisplayMetrics(); ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(dm); Bitmap bm = null; if (input != null) { bm = createBitmapWithStream(input, dm.widthPixels, dm.heightPixels); } else { bm = createBitmapWithPath(path, dm.widthPixels, dm.heightPixels); } return bm; } /** * @param encrypt 加密或解密的字符串 * @param pKey 加密解密的key * @return 加密或解密后的字符串 */ public static String decryptString(String encrypt, String pKey) { byte[] encryptToByte = HexStringToBinary(encrypt); String encryptDecrypt = new String(PEncryption.os_decrypt( encryptToByte, encryptToByte.length, pKey)); return encryptDecrypt; } /** * @param hexString * @return 将十六进制转换为字节数组 */ private static byte[] HexStringToBinary(String hexString) { // hexString的长度对2取整,作为bytes的长度 String hexStr = "0123456789ABCDEF"; int len = hexString.length() / 2; byte[] bytes = new byte[len]; byte high = 0;// 字节高四位 byte low = 0;// 字节低四位 for (int i = 0; i < len; i++) { // 右移四位得到高位 high = (byte) ((hexStr.indexOf(hexString.charAt(2 * i))) << 4); low = (byte) hexStr.indexOf(hexString.charAt(2 * i + 1)); bytes[i] = (byte) (high | low);// 高地位做或运算 } return bytes; } /** * @param inputStream xml文件输入流 * @param fileName xml文件名,不带后缀 * @param label 标签名 * @param attribute 属性名,获取标签时此值传空即可,获取属性时必须传值 * @return xml文件中指定标签或者标签中属性的值 */ public static String parserXmlLabel(InputStream inputStream, String fileName, String label, String attribute) { String value = ""; // 如果标签不为空并且输入流不为空 if (!TextUtils.isEmpty(label) && inputStream != null) { try { inputStream = decodeInputStream(inputStream, fileName); // 使用Xml的静态方法生成语法分析器 XmlPullParser parser = Xml.newPullParser(); parser.setInput(inputStream, "utf-8"); int eventType = XmlPullParser.START_DOCUMENT; boolean needContinue = true; // 循环直到找到符合的标签或者直到文档结束 while (needContinue) { eventType = parser.next(); switch (eventType) { case XmlPullParser.START_TAG: String localName = (parser.getName()) .toLowerCase(); // 如果该标签是传入的标签,获取该标签的值或者其属性的值 if (localName.equals(label.toLowerCase())) { if (!TextUtils.isEmpty(attribute)) { value = parser.getAttributeValue(null, attribute); } else { value = parser.nextText(); } needContinue = false; } break; case XmlPullParser.END_DOCUMENT: needContinue = false; break; default: break; } } } catch (Exception e) { e.printStackTrace(); } finally { // 如果inputStream不为空,释放掉 if (inputStream != null) { try { inputStream.close(); inputStream = null; } catch (IOException e) { e.printStackTrace(); } } } } return value; } /** * @param inputStream 文件输入流 * @param fileName 文件名,不带后缀 * @return 解密后的文件流 */ public static InputStream decodeInputStream(InputStream inputStream, String fileName) { try { // 先判断是否加密,如果是加密了才解密 ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len; while ((len = inputStream.read(buffer)) > -1) { baos.write(buffer, 0, len); } baos.flush(); InputStream is1 = new ByteArrayInputStream(baos.toByteArray()); InputStream is2 = new ByteArrayInputStream(baos.toByteArray()); boolean isV = ACEDes.isEncrypted(is1); if (isV) { InputStream resStream = null; byte[] data = null; String result = null; data = transStreamToBytes(is2, is2.available()); result = ACEDes.htmlDecode(data, fileName); resStream = new ByteArrayInputStream(result.getBytes()); return resStream; } else { return is2; } } catch (Exception e) { e.printStackTrace(); return inputStream; } } /** * 安装主应用补丁包 * * @param context * @param appId * @param installType:安装补丁包类型1:网页包;2:插件包;3:网页和插件 * @return 安装成功,返回版本号;失败,返回空。 */ public static String installWidgetPatch(Context context, String appId, int installType) { return WidgetPackageMgr.installWidgetPatch(context, appId, installType); } /** * 安装子应用(包括全量包、补丁包),子应用的安装、升级,不区分全量包、补丁包。 * * @param appId * @param filePath:压缩包位置 * @param desPath:安装位置 * @param encoding * @return 安装路径 */ public static String installSubWidget(String appId, String filePath, String desPath, String encoding) { return WidgetPackageMgr.installSubWidget(appId, filePath, desPath, encoding); } /** * 获取主应用的softToken * * @param context * @param appKey * @return */ public static String getSoftToken(Context context, String appKey) { SharedPreferences preferences = context.getSharedPreferences( PushReportConstants.SP_APP, Context.MODE_PRIVATE); String softToken = preferences.getString("softToken", null); if (softToken != null) { return softToken; } String[] val = new String[4]; try { val[0] = getMacAddress(context); TelephonyManager telephonyManager = (TelephonyManager) context .getSystemService(Context.TELEPHONY_SERVICE); val[1] = telephonyManager.getDeviceId(); val[2] = getCPUSerial(); val[3] = appKey; } catch (Exception e) { e.printStackTrace(); } softToken = getMD5Code(val); SharedPreferences.Editor editor = preferences.edit(); editor.putString("softToken", softToken); editor.commit(); return softToken; } /** * 获取Mac地址 * * @return Mac地址,带有':' */ public static String getMacAddress(Context context) { String macSerial = null; try { WifiManager wifi = (WifiManager) context .getSystemService(Context.WIFI_SERVICE); WifiInfo info = wifi.getConnectionInfo(); macSerial = info.getMacAddress(); } catch (Exception e) { } if (macSerial == null || "02:00:00:00:00:00".equals(macSerial)) { macSerial = readFileContent("/sys/class/net/wlan0/address").trim(); } return macSerial; } private static String readFileContent(String path) { String content = ""; try { if ((new File(path)).exists()) { FileInputStream fis = new FileInputStream(path); byte[] buffer = new byte[8192]; int byteCount = fis.read(buffer); if (byteCount > 0) { content = new String(buffer, 0, byteCount, "utf-8"); } fis.close(); } } catch (Exception e) { e.printStackTrace(); } return content; } public static String getMD5Code(String[] value) { if (value == null || value.length == 0) { return null; } try { MessageDigest md = MessageDigest.getInstance("MD5"); md.reset(); for (String va : value) { if (va == null) { va = ""; } md.update(va.getBytes()); } byte[] md5Bytes = md.digest(); StringBuffer hexValue = new StringBuffer(); for (int i = 0; i < md5Bytes.length; i++) { int val = ((int) md5Bytes[i]) & 0xff; if (val < 16) hexValue.append("0"); hexValue.append(Integer.toHexString(val)); } return hexValue.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return null; } /** * 获取CPU序列号 * * @return CPU序列号(16位) 读取失败为"0000000000000000" */ private static String getCPUSerial() { String str = "", cpuAddress = "0000000000000000"; try { // 读取CPU信息 str = readFileContent("/proc/cpuinfo"); if (str != null && str.length() > 0) { String[] strs = str.split("\n"); for (int i = 0; i < strs.length; i++) { // 提取到序列号所在行的内容 if (strs[i].startsWith("Serial")) { // 提取序列号 cpuAddress = strs[i].substring(strs[i].indexOf(":") + 1, strs[i].length()).trim(); break; } } } } catch (Exception ex) { // 赋予默认值 ex.printStackTrace(); } return cpuAddress; } public static String getAppIdAppKeyMD5(String appId, String appKey) { String[] value = new String[]{appId + ":" + appKey}; return getMD5Code(value); } public static String decodeStr(String key) { char map[] = {'d', 'b', 'e', 'a', 'f', 'c'}; char nmap[] = {'2', '4', '0', '9', '7', '1', '5', '8', '3', '6'}; String dest = ""; String swapstr = ""; String output = ""; for (int j = 0; j < key.length(); j++) { if (key.charAt(j) == '-') continue; swapstr = swapstr + key.charAt(j); } for (int j = 0; j < swapstr.length(); j++) { if (j == 8 || j == 12 || j == 16 || j == 20) dest = dest + "-"; dest = dest + swapstr.charAt(swapstr.length() - j - 1); } for (int i = 0; i < dest.length(); i++) { char t = dest.charAt(i); if (t >= 'a' && t <= 'f') { t = map[t - 'a']; } else if (t >= '0' && t <= '9') { t = nmap[t - '0']; } output = output + t; } return output; } /** * 添加验证头 * * @param appid * @param appkey * @param timeStamp 当前时间戳 * @return */ public static String getAppVerifyValue(String appid, String appkey, long timeStamp) { String value = null; String md5 = getMD5Code(appid + ":" + appkey + ":" + timeStamp); value = "md5=" + md5 + ";ts=" + timeStamp; return value; } public static String getMD5Code(String value) { if (value == null) { value = ""; } try { MessageDigest md = MessageDigest.getInstance("MD5"); md.reset(); md.update(value.getBytes()); byte[] md5Bytes = md.digest(); StringBuffer hexValue = new StringBuffer(); for (int i = 0; i < md5Bytes.length; i++) { int val = ((int) md5Bytes[i]) & 0xff; if (val < 16) hexValue.append("0"); hexValue.append(Integer.toHexString(val)); } return hexValue.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return null; } /** * 重启整个APP * * @param context * @param delayTime 延迟多少毫秒重新启动 */ public static void restartAPP(final Context context, final long delayTime) { /**开启一个新的服务,用来重启本APP*/ Intent intent = new Intent(context, killSelfService.class); intent.putExtra(killSelfService.KEY_STOP_PACKAGE_NAME, context.getPackageName()); intent.putExtra(killSelfService.KEY_STOP_DELAY, delayTime); context.startService(intent); /**杀死整个进程**/ android.os.Process.killProcess(android.os.Process.myPid()); } }