android 離線下載
==========================離線下載
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Stack;
import java.util.Timer;
import java.util.TimerTask;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.json.JSONException;
import org.json.JSONObject;
import com.rytong.tools.crypto.AESCipher;
import com.rytong.tools.crypto.Base64;
import com.rytong.tools.crypto.HMac;
import com.rytong.tools.httpconnect.HttpManager;
import com.rytong.tools.utils.Utils;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.os.Looper;
import android.util.DisplayMetrics;
public class OffStoreDownload {
private final String PLUGRESOURCES = "plug_in_resources.db";
private final String OFFLINERESOURCES = "offline_resources.db";
private Activity activity_;
// 是否必須更新(-1:不更新,0:不強制更新,1:強制更新)
private String mustupate_;
// 離線資源資料庫
public static OffStoreDB offLineDB_;
// 外掛資料庫
public static OffStoreDB plugDB_;
static public String FILEROOT;
final static public String PLUGROOT = "plug-in-resources/";
final static public String OFFLINEROOT = "offline-resources/";
final static public String WRITEROOT = "write/";
// 需要更新資源列表
private HashMap<String, String> resourceMap_;
// 列表path和rev(SHA1的hash)
private HashMap<String, HashMap<String, String>> serverMap_;
private HashMap<String, Boolean> alreadyDownload_;
private String serverString_;
// 離線更新介面
public final String RESOURCE_UPDATE = "/ota/resource_update?";
private int downloadNum_;
public OffStoreDownload(Activity activity) {
activity_ = activity;
alreadyDownload_ = new HashMap<String, Boolean>();
downloadNum_ = 1;// 重複下載一次即可。
offLineDB_ = new OffStoreDB(activity, OFFLINERESOURCES);
plugDB_ = new OffStoreDB(activity, PLUGRESOURCES);
}
// 步驟1:傳送請求:平臺型別、螢幕解析度、server.desc(不存在則為空)
public void downloadOfflineResource() {
// 手機平臺
final String platform = Utils.getConfigStringFormAsset(activity_, "offstoreplatform");
// 解析度
DisplayMetrics dm = new DisplayMetrics();
activity_.getWindowManager().getDefaultDisplay().getMetrics(dm);
final String screenResolution = String.valueOf(dm.widthPixels) + "*" + String.valueOf(dm.heightPixels);
// 本地離線檔案client.desc(不為空則傳送)
final String client_desc = (String) offLineDB_.find("client.desc");
Timer timer_ = new Timer();
timer_.schedule(new TimerTask() {
@Override
public void run() {
HttpManager hm = new HttpManager(activity_);
String uri = Utils.getConfigStringFormAsset(activity_, "SERVER_URI").concat(RESOURCE_UPDATE);// http://192.168.85.69:4002/ota/resource_update?
StringBuffer buf = new StringBuffer();
buf.append("desc=");
if (client_desc != null)
buf.append(client_desc).append("&");
else
buf.append("&");
buf.append("platform=").append(platform).append("&");
buf.append("resolution=").append(screenResolution);
String body = buf.toString();
Object server_update = hm.sendPostRequest(uri, body, HttpManager.MIME_JSON, null);
// 步驟2:讀取返回的download.desc和server.desc。
parseResponse(server_update);
}
}, 0);
}
public void saveToDb(OffStoreDB db, String key, Object value) {
db.insert(key, value);
}
// 解析返回來的資料
protected void parseResponse(Object serverUpdate) {
if (null == serverUpdate)
return;
if (serverUpdate instanceof String)
parseJSON((String) serverUpdate);
}
// 先判斷是否需要強制更新,如果不是強制更新,則提醒使用者。
private void parseJSON(String serverResponse) {
try {
// {"mustupdate":0,"server":{"yybk.zip":{"rev":"0b08d0c498e0eb5e2d19abc6dda695cc7f462473","path":"android/480-320/zip","desc":{"html/showCard.html":"0afd92a6b7fa6070a3610ffad94d24c0137538d1","imgs/back_03.png":"91e81ea8d58fcca77f4e43699e3cc8186691cdb2","imgs/card1.png":"f4598e2ea5d5fee387cb906506a424e1e842aac7","imgs/card2.png":"c42659dd3ab85894685ea7b10bcd2755b6d7b2cc","imgs/card3.png":"debe586a42d9b3536574bcd1daaaafb67332e99a","imgs/photo1.png":"14fbab85d86ce08593b67153a86daa8085fec61f","imgs/title_02.png":"63f7b712014402807f35d37b34acfc557228e7d2","js/jquery-1.7.1.js":"62922be0191a2cc4d13ef3abe4a62d1ebc17492d"}}},"download":{"yybk.zip":"http://192.168.65.82:4004/ebank/resources/android/480-320/zip/yybk.zip"}};
// {"mustupdate":0,"server":{"colorful.png":{"rev":"7915a251510c265826a1ee14c5a7c1ac31459890","path":"android/320*480/png"},"background_cao.png":{"rev":"da39a3ee5e6b4b0d3255bfef95601890afd80709","path":"android/320*480/png"}},"download":{"background_cao.png":"http://192.168.63.68:4002/ebank/resources/android/320*480/png/background_cao.png","colorful.png":"http://192.168.63.68:4002/ebank/resources/android/320*480/png/colorful.png"}}
Utils.printOutToConsole("offstore data: " + serverResponse);
final JSONObject obj = new JSONObject(serverResponse);
// 是否必須更新
mustupate_ = obj.getString("mustupdate");
if (null == mustupate_)
return;
if (mustupate_.equalsIgnoreCase("0")) {
final Builder ad = new AlertDialog.Builder(activity_);
ad.setTitle("提示").setMessage("您有新的離線資源需要下載,是否更新?").setCancelable(false)
.setNegativeButton("確定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
parseJSONIndeed(obj);
if (checkAllDownload()) {
// 下載10:下載完畢後儲存server.desc檔案。
saveToDb(offLineDB_, "client.desc", serverString_);
return;
}
downloadResourceByPath();// 根據路徑下載每一個resource
}
}).setPositiveButton("取消", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
});
if (!activity_.isFinishing()) {
activity_.runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
ad.show();
}
});
}
} else {
parseJSONIndeed(obj);
if (checkAllDownload()) {
// 下載10:下載完畢後儲存server.desc檔案。
saveToDb(offLineDB_, "client.desc", serverString_);
return;
}
downloadResourceByPath();// 根據路徑下載每一個resource
}
} catch (JSONException e) {
Utils.printException(e);
}
}
// 解析JSON---步驟3:解析download.desc。
private void parseJSONIndeed(JSONObject obj) {
// TODO Auto-generated method stub
// download.desc
try {
resourceMap_ = new HashMap<String, String>();
serverMap_ = new HashMap<String, HashMap<String, String>>();
JSONObject downObject;
downObject = obj.getJSONObject("download");
Iterator itDown = downObject.keys();
String key = "";
String value = "";
while (itDown.hasNext()) {
key = itDown.next().toString();
value = downObject.getString(key);
// 未下載時,更新標誌為false;更新後修改標誌位
alreadyDownload_.put(key, false);
resourceMap_.put(key, value);
}
// server.desc
JSONObject serverObject = obj.getJSONObject("server");
serverString_ = serverObject.toString();
Iterator itServer = serverObject.keys();
key = "";
JSONObject jsonValue;
String path;
String rev;
while (itServer.hasNext()) {
key = itServer.next().toString();
jsonValue = serverObject.getJSONObject(key);
HashMap<String, String> params = new HashMap<String, String>();
path = jsonValue.getString("path");
rev = jsonValue.getString("rev");
params.put("path", path);
params.put("rev", rev);
serverMap_.put(key, params);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
Utils.printException(e);
}
}
// 步驟5:根據download.desc下載列表建立任務佇列task-list。
public void downloadResourceByPath() {
try {
String fileName = null, filePath = null, shaFile = null, serverFileName = null, serverPath = null, serverRev = null;
byte[] fileString = null;
if (resourceMap_ == null)
return;
Iterator it = resourceMap_.keySet().iterator();
HashMap<String, String> params;
while (it.hasNext()) {
fileName = it.next().toString();
filePath = resourceMap_.get(fileName);
if (checkDownload(fileName)) {
// 已經下載過,返回
return;
} else {
// 下載每個檔案
fileString = downloadPerResource(filePath);
File file = Utils.getFileFromBytes(fileString, fileName);
if (Utils.getMIMEType(file).equalsIgnoreCase("zip")) {
// 如果資料是壓縮的則應進行解壓操作
unZip(new ByteArrayInputStream(fileString));
// fileString = Utils.gunzip(fileString);
}
file = null;
// 計算檔案SHA1值
if (fileString != null) {
byte[] temp = HMac.SHA1(fileString);
shaFile = HMac.byteArrayToHexString(temp);
}
}
// 查詢第二個Map中含有第一個Map的key
if (serverMap_.containsKey(fileName)) {
params = serverMap_.get(fileName);
serverPath = params.get("path");
serverRev = params.get("rev");
}
// 步驟6:每一個資原始檔下載完畢後計算資原始檔的SHA1值,並與server.desc記錄的SHA1值進行比較。(遞迴)
comparedRedownload(fileName, shaFile, filePath, fileString, serverRev);
}
} catch (Exception e) {
// TODO Auto-generated catch block
Utils.printException(e);
}
}
private void unZip(InputStream input) {
// TODO Auto-generated method stub
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(input));
try {
ZipEntry ze;
while ((ze = zis.getNextEntry()) != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int count;
while ((count = zis.read(buffer)) != -1) {
baos.write(buffer, 0, count);
}
String filename = ze.getName();
byte[] bytes = baos.toByteArray();
// do something with 'filename' and 'bytes'...
saveToDb(plugDB_, filename, bytes);
}
} catch (IOException e) {
// TODO Auto-generated catch block
Utils.printException(e);
} finally {
try {
if (null != zis)
zis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
Utils.printException(e);
}
}
}
/**
* @param fileName
* 客戶端檔名
* @param shaFile
* 客戶端計算出的SHA1
* @param filePath
* 客戶端下載檔案的路徑
* @param fileString
* 客戶端下載檔案後的位元組陣列
* @param serverFileName
* 伺服器端檔名
* @param serverRev
* 伺服器端SHA1
*/
private void comparedRedownload(String fileName, String shaFile, String filePath, byte[] fileString,
String serverRev) {
try {
boolean noModify = comparedSHA1(fileName, shaFile, serverRev);
if (noModify) {
// 步驟7:驗證資原始檔的正確性後,以name為key儲存資原始檔。
// 下載完的檔案儲存到資料庫
offLineDB_.deleteToDB(fileName);
if (fileName.contains(".png"))
saveToDb(offLineDB_, fileName, fileString);
else
saveToDb(offLineDB_, fileName, new String(fileString, "UTF-8"));
// 步驟8:更新download.desc的下載狀態標記,標記為已下載。
// 儲存到資料庫後修改"已下載"的標誌位
alreadyDownload_.put(fileName, true);
} else {
if (downloadNum_-- > 0) {
// 重新下載每個檔案
fileString = downloadPerResource(filePath);
File file = Utils.getFileFromBytes(fileString, fileName);
if (Utils.getMIMEType(file).equalsIgnoreCase("zip")) {
// 如果資料是壓縮的則應進行解壓操作
fileString = Utils.gunzip(fileString);
}
file = null;
// 重新計算檔案SHA1值
byte[] disg = HMac.SHA1(fileString);
if (disg != null) {
shaFile = disg.toString();
}
comparedRedownload(fileName, shaFile, filePath, fileString, serverRev);
}
}
} catch (UnsupportedEncodingException e) {
Utils.printException(e);
} catch (IOException e) {
// TODO Auto-generated catch block
Utils.printException(e);
} catch (Exception e) {
// TODO Auto-generated catch block
Utils.printException(e);
}
}
// 判斷檔名為fileName的檔案是否下載過
private boolean checkDownload(String fileName) {
if (alreadyDownload_ != null) {
return alreadyDownload_.get(fileName);
}
return false;
}
// 判斷所有的檔案是否下載完
private boolean checkAllDownload() {
if (alreadyDownload_ != null) {
for (Map.Entry<String, Boolean> entry : alreadyDownload_.entrySet()) {
boolean entryDownload = entry.getValue();
// 如果有值為false,即為沒有下載完,所有的都為true,才為全部下載完成
if (!entryDownload)
return false;
}
// 全部下載完成
return true;
}
return false;
}
// 比較下栽檔案的SHA1和server.desc
private boolean comparedSHA1(String fileName, String shaFile, String serverSHA1) {
if (fileName != null && shaFile != null & serverSHA1 != null) {
if (shaFile.equalsIgnoreCase(serverSHA1)) {
return true;
}
}
return false;
}
// 下載檔案列表中的每一個檔案
private byte[] downloadPerResource(String filePath) {
ByteArrayOutputStream fileBuffer = new ByteArrayOutputStream(1024);
byte[] fileBytes = null;
try {
HttpManager hm = new HttpManager(activity_);
hm.read(filePath, fileBuffer, null);
fileBytes = fileBuffer.toByteArray();
} catch (Exception e) {
Utils.printException(e);
} catch (OutOfMemoryError oe) {
Utils.printOutToConsole(oe);
} finally {
if (null != fileBuffer)
try {
fileBuffer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
Utils.printException(e);
}
fileBuffer = null;
}
return fileBytes;
}
public boolean getFirstLogin() {
File file = new File(activity_.getFilesDir(), offLineDB_.DATABASE_NAME);
return file.exists();
}
/**
* 不聯網情況下個別頁面讀取本地資料庫XML
*
* @param itemValue
* @param currentView_
* @return
*/
public Object readOfflineResource(OffStoreDB db, String itemValue) {
return db.find(itemValue);
}
public static void setRootPath() {
FILEROOT = Utils.getActivity().getFilesDir().getPath().concat("/");
}
}
===============================================================================
//資料庫操作
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class OffStoreDB extends SQLiteOpenHelper {
public static String DATABASE_NAME = "emp.db";
private static int DATABASE_VERSION = 1;
private static String TABLE_NAME = "emp_table";
private static String COLUMN_ID = "_id";
private static String COLUMN_NAME = "name";
private static String COLUMN_VALUE = "value";
public OffStoreDB(Context context, String name) {
super(context, name, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table ".concat(TABLE_NAME).concat("(").concat(COLUMN_ID)
.concat(" integer primary key autoincrement,").concat(COLUMN_NAME).concat(" varchar(20),")
.concat(COLUMN_VALUE).concat(" varchar(100))"));
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS ".concat(TABLE_NAME));
onCreate(db);
}
public long insert(String column_name, Object column_value) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(COLUMN_NAME, column_name);
if (column_value instanceof String)
cv.put(COLUMN_VALUE, (String) column_value);
else if (column_value instanceof byte[])
cv.put(COLUMN_VALUE, (byte[]) column_value);
long row = db.insert(TABLE_NAME, null, cv);
return row;
}
public Object find(String name) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("select value from emp_table where name = ?", new String[] { name });
// select value from emp_table where name = "fwzx.xml";
if (cursor.moveToNext()) {
Object value = null;
try {
// 如果是圖片將會被儲存為位元組陣列形式
if (name.contains(".png"))
value = cursor.getBlob(cursor.getColumnIndex(COLUMN_VALUE));
else
value = cursor.getString(cursor.getColumnIndex(COLUMN_VALUE));
cursor.close();
} catch (Exception e) {
Utils.printException(e);
}
return value;
} else {
cursor.close();
return null;
}
}
public int deleteToDB(String fileName) {
SQLiteDatabase db = this.getWritableDatabase();
// ContentValues cv = new ContentValues();
// cv.put(COLUMN_NAME, fileName);
return db.delete(TABLE_NAME, COLUMN_NAME + "=?", new String[] { fileName });
}
}
-----------------------------------------------utils
//#define Android2.2
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Vector;
import java.util.UUID;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.json.JSONArray;
import org.json.JSONObject;
import com.rytong.tools.clienthello.ClientHello;
import com.rytong.tools.crypto.AESCipher;
import com.rytong.tools.crypto.HMac;
import com.rytong.tools.crypto.MD5;
import com.rytong.tools.crypto.RSACipher;
import com.rytong.tools.httpconnect.HttpManager;
import com.rytong.tools.offstore.OffStoreDownload;
import com.rytong.tools.ui.Component;
import com.rytong.tools.ui.LPLayout;
import android.R.color;
import android.R.integer;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.telephony.CellLocation;
import android.telephony.TelephonyManager;
// #ifdef Android2.2
import android.telephony.cdma.CdmaCellLocation;
// #endif
import android.telephony.gsm.GsmCellLocation;
import android.text.TextPaint;
import android.util.DisplayMetrics;
import android.view.View;
/**
* Utility class.
*/
public final class Utils {
private static int BRHEIGHT;
private static Activity activity_;
// 是否列印標誌
private static boolean isPrintMessage_;
// 字型縮放引數,如果手機解析度和密度同比增長,則該引數?,表示不需縮放,如果不匹配,則需校正該引數設?
public static float SCALEDFONT;
// 基準螢幕的寬,該值應和服務端定義xml的基準螢幕保持?????
public static int BenchmarkresolutionW_;
// 基準螢幕的高,該值應和服務端定義xml的基????幕保持一?
public static int BenchmarkresolutionH_;
/**
* Used for gzip. Re. rfc1951.
*/
static int gIndex = 0;
static int bitByte = 0;
static int bitIndex = 0;
private final static int MAX_BITS = 16;
private final static int[] EXTRA_L_BITS = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4,
5, 5, 5, 5, 0 };
private final static int[] EXTRA_L_VALUES = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51,
59, 67, 83, 99, 115, 131, 163, 195, 227, 258 };
private final static int[] EXTRA_D_BITS = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10,
10, 11, 11, 12, 12, 13, 13 };
private final static int[] EXTRA_D_VALUES = { 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385,
513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 };
private final static int[] DYNAMIC_L_ORDER = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
// 介面X方向參考縮放參?此引數為控制元件寬或者字型大小的參考??
public static float SCALEDATEX;
// 介面Y方向參考縮放參?此引數為控制元件高的參考??
public static float SCALEDATEY;
/** Default alpha value used to draw menu panels and status bars. */
public final static int DEFAULT_TRANSPARENCY = 0xa0000000;
final static int OK_KEY = -5;
final static int LEFT_SOFTKEY = -6;
final static int RIGHT_SOFTKEY = -7;
// if it is sony ericsson, SONY_ERICSSON is true.
public final static boolean SONY_ERICSSON = false;
// 日誌名稱
public static final String LOGNAME = "LPC";
/**
* Used as indices in text parser's return result of a line break in a string.
*/
public final static int LBI_BREAK = 0; // Break position (this char is in current
// line)
public final static int LBI_NEXT = 1; // Next char position to resume scanning (to
// skip tags)
public final static int LBI_TYPE = 2; // Line break type: newline, paragraph, ...,
// defined below.
public final static int LBI_START = 3; // Starting position of this line.
public final static int LBI_SIZE = 4; // Number of linebreak indices.
/**
* Types of line breaks.
*/
final static int LB_NEWLINE = 0;
final static int LB_PARAGRAPH = 1;
final static int LB_SKIP = 2; // Skip characters within [LBI_BREAK,
// LBI_NEXT)
final static int LB_HYPHEN = 3;
/**
* The number of alpha transparency levels。will be reset by numAlphaLevels() in LPMid.java. The minimum
* numAlphaLevel_ is 2, which indicates only support for full transparency and full opacity.
*/
final static int numAlphaLevel_ = 256;
final static int BLUE = 0xFF0000FF;
final static int WHITE = 0xFFFFFFFF;
final static int BLACK = 0xFF000000;
final static int GREY = 0xFF808080;
final static int SELECTED_LINK_COLOR = 0xFF808080;
public final static int TABBARBACKGROUNDCOLOR = 0xFF294B78;
public final static char MATCH = '\"';
/** True if the user selects item Map */
public static boolean toMapView_;
final static String SPLIT_CHARACTERS = " ,.";
// 呼叫系統相機的請求碼
public final static int CAMERA_REQUEST_CODE = 1001;
// 解讀並儲存assets資料夾下的Config.txt檔案資訊
private static HashMap<String, String> configHm_;
// 連點事件一時間間隔
public static int jat_lag = 0;
/**
* @return
*/
public final static byte[] getClientGMTUnixTime() {
// get local time.4 bytes.
Calendar cal = Calendar.getInstance();
Date date = cal.getTime();
int hours = date.getHours();
byte[] clientGmtUnixTime = new byte[4];
clientGmtUnixTime[0] = (byte) ((hours & 0x0000FF00) >> 8);
clientGmtUnixTime[1] = (byte) ((hours & 0x000000FF));
int minutes = date.getMinutes();
clientGmtUnixTime[2] = (byte) ((minutes & 0x0000FF00) >> 8);
clientGmtUnixTime[3] = (byte) ((minutes & 0x000000FF));
return clientGmtUnixTime;
}
// /**
// * 從資源圖片裡面獲取指定檔名的圖片,如果沒有就返回空
// *
// * @param 指定的要查詢的檔名
// * @param 介面物件
// * @return
// */
// public final final static Bitmap getBitmapFromDrawable(Activity bv, String bitmapName) {
// bitmapName = bitmapName.trim();
// if (bitmapName.endsWith(".png")) {
// // 服務端傳送過來的圖片名稱有可能帶?png字尾,先去掉字尾再進行相關操作比?
// bitmapName = bitmapName.substring(0, bitmapName.lastIndexOf(".png"));
// }
// // 利用反射機制獲取物件域名
// Object obj = null;
// String varName = null;
// Field[] fields = R.drawable.class.getDeclaredFields();
// int size = fields.length;
// for (int i = 0, len = size; i < len; i++) {
// // 對於每個屬性,獲取屬性名
// varName = fields[i].getName();
// if (varName.equalsIgnoreCase(bitmapName)) {
// try {
// // 獲取原來的訪問控制權?
// boolean accessFlag = fields[i].isAccessible();
// // 修改訪問控制許可權
// fields[i].setAccessible(true);
// // 獲取在物件f中屬性fields[i]對應的物件中的變?
// obj = fields[i].get(varName);
// // ????訪問控制許可權
// fields[i].setAccessible(accessFlag);
// int id = Integer.parseInt(obj.toString());
// Bitmap bm = getBitmap(id, bv);
// return bm;
// } catch (IllegalArgumentException ex) {
// printException(ex);
// } catch (IllegalAccessException ex) {
// printException(ex);
// }
// }
// }
// return null;
// }
/**
* 傳送端?
*
* @param phoneNum
* @param content
*/
public final static void sendSms(int phoneNum, String content) {
Intent intent = new Intent();
// 系統預設的action,用來開啟預設的簡訊界?
intent.setAction(Intent.ACTION_SENDTO);
// 需要發短息的號?
intent.setData(Uri.parse("smsto:" + phoneNum));
intent.putExtra("sms_body", content);
activity_.startActivity(intent);
}
/**
* 獲取資源圖片
*
* @param context
* @param resourcesName
* @return
*/
public final static Bitmap getBitmapFromResources(Context context, String resourcesName) {
Bitmap bitmap = null;
if (resourcesName == null)
return bitmap;
Object img = null;
// 先補?png字尾名從sql中取出對應的圖片
resourcesName = getPNGName(resourcesName);
img = OffStoreDownload.plugDB_.find(resourcesName);
if (null != img && img instanceof byte[]) {
byte[] temp = (byte[]) img;
bitmap = BitmapFactory.decodeByteArray(temp, 0, temp.length);
return bitmap;
}
img = OffStoreDownload.offLineDB_.find(resourcesName);
if (null != img && img instanceof byte[]) {
byte[] temp = (byte[]) img;
bitmap = BitmapFactory.decodeByteArray(temp, 0, temp.length);
return bitmap;
}
// 如果sql中沒有儲存對應的圖片,則將字尾去掉,在資原始檔裡面搜尋
if (resourcesName.endsWith(".png")) {
resourcesName = resourcesName.substring(0, resourcesName.lastIndexOf(".png"));
}
resourcesName = resourcesName.toLowerCase();
int resourcesId = getResourcesId(context, resourcesName, "drawable");
if (resourcesId != 0) {
bitmap = getBitmap(resourcesId, (Activity) context);
}
return bitmap;
}
/**
* 獲取資源id
*
* @param context
* @param resourcesName
* @param resourcesType
* @param packageName
* @return
*/
public final static int getResourcesId(Context context, String resourcesName, String resourcesType) {
int resourcesId = 0;
resourcesId = context.getResources().getIdentifier(resourcesName, resourcesType, context.getPackageName());
return resourcesId;
}
/**
* 獲取專案Config中的app名稱,用於聯網後臺區別報?
*
* @param activity
*/
public final static void getAppName(Activity activity) {
HttpManager.APPNAME = getConfigStringFormAsset(activity, "app");
}
public final static void getPlatform(Activity activity) {
HttpManager.OPLATFORM = getConfigStringFormAsset(activity, "oPlatform");
}
public final static String getClientType(Activity activity) {
return getConfigStringFormAsset(activity, "clientType");
}
/**
* 判斷字串是否以.png結尾,如果不是則加上該字尾
*/
public final static String getPNGName(String name) {
name = name.trim();
if (!name.endsWith(".png")) {
if (name.indexOf(".") != -1)
name = name.substring(0, name.indexOf("."));
name = name.concat(".png");
}
return name;
}
public final static Bitmap getBitmap(int rdoing, Activity bv) {
// TODO Auto-generated method stub
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;
InputStream is = bv.getResources().openRawResource(rdoing);
Bitmap img = BitmapFactory.decodeStream(is, null, opt);
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
Utils.printException(e);
}
return img;
}
public final static int getColorValue(String value) {
String colorstr = "";
try {
colorstr = getValidColorString(value);
if (colorstr.length() > 6) {
int color = Integer.parseInt(colorstr, 16);
color |= 0x00000000;
return color;
} else {
int color = Integer.parseInt(colorstr, 16);
color |= 0xFF000000;
return color;
}
} catch (Exception e) {
// TODO Auto-generated catch block
Utils.printException(e);
return 0xFFFFFFFF;
}
}
/**
* The valid color string is a 6 bit hex number. e.g., FFFFFF.
*
* @param srcColorstr
* @return
*/
public final static String getValidColorString(final String srcColorstr) throws Exception {
String colorstr = srcColorstr;
if (colorstr.startsWith("#")) {
colorstr = colorstr.substring(1);
}
return colorstr;
}
// 將字串陣列中的內???轉換成????????方便字元陣列檢?
public final static String getArrayString(String[] sa) {
if (null == sa)
return "";
return Arrays.toString(sa);
}
final static boolean isLeftSoftKey(int key) {
return (key == LEFT_SOFTKEY);
}
final static boolean isRightSoftKey(int key) {
// Motorola some phones's right key is -22, and other is 22.
// return (key == RIGHT_SOFTKEY || key == -RIGHT_SOFTKEY);
return (key == RIGHT_SOFTKEY);
}
final static int getLeftSoftKey() {
return LEFT_SOFTKEY;
}
final static int getRightSoftKey() {
return RIGHT_SOFTKEY;
}
/**
*
* 把位元組陣列儲存為一個文?
*
*/
public final static File getFileFromBytes(byte[] b, String outputFile) {
String pathString = activity_.getFilesDir().getPath().concat("/");
BufferedOutputStream stream = null;
File file = null;
try {
file = new File(pathString.concat(outputFile));
file.createNewFile();
FileOutputStream fstream = new FileOutputStream(file);
stream = new BufferedOutputStream(fstream);
stream.write(b);
} catch (Exception e) {
printException(e);
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e1) {
printException(e1);
}
}
}
return file;
}
/**
* 根據檔案字尾名返回檔案類?
*
* @param fileTemp
* @return
*/
public final static String getMIMEType(File fileTemp) {
// TODO Auto-generated method stub
String type = "";
String fName = fileTemp.getName();
String end = fName.substring(fName.lastIndexOf(".") + 1, fName.length()).toLowerCase();
if (end.equals("m4a") || end.equals("mp3") || end.equals("mid") || end.equals("xmf") || end.equals("ogg")
|| end.equals("wav")) {
type = "audio";
} else if (end.equals("3gp") || end.equals("mp4")) {
type = "video";
} else if (end.equals("jpg") || end.equals("gif") || end.equals("png") || end.equals("jpeg")
|| end.equals("bmp")) {
type = "image";
} else if (end.equals("apk")) {
type = "application/vnd.android.package-archive";
} else if (end.equals("zip")) {
type = "zip";
} else if (end.equals("apk")) {
} else {
type += "/*";
}
return type;
}
/**
* Graphics.drawRegion() has a bug in 4.2.1 and we have to use a replacement function.
*/
public final static void drawRegion(Canvas g, Bitmap img, int srcX, int srcY, int width, int height, int dstX,
int dstY) {
g.drawBitmap(img, new Rect(srcX, srcY, srcX + width, srcY + height), new Rect(dstX, dstY, dstX + width, dstY
+ height), new Paint());
}
public final static int fixTransparentPixel(int pixel) {
// We don't use semitransparent pixel if the phone only support for full
// transparency and full opacity.
if (numAlphaLevel_ > 2 && (pixel & 0xff000000) != 0)
return (pixel & 0x00ffffff) + DEFAULT_TRANSPARENCY;
else
return pixel;
}
/**
* Given an image, assign transparency value to its non-background pixels (background pixels are pixels that are
* completely transparent).
*
* @param transparency
* 255 == totally opaque.
*/
public final static Bitmap fixTransparentImage(Bitmap img) throws Exception {
if (null == img)
return null;
int width = img.getWidth();
int height = img.getHeight();
int sz = width * height;
int[] rgb = new int[sz];
// Params: (rgb, offset, scanlength, x, y, width, height)
// rgbData[offset + (a - x) + (b - y) * scanlength] = P(a, b);
img.getPixels(rgb, 0, width, 0, 0, width, height);
for (int i = 0; i < sz; ++i) {
rgb[i] = fixTransparentPixel(rgb[i]);
}
img = Bitmap.createBitmap(rgb, width, height, Bitmap.Config.RGB_565);
return img;
}
/*
* Check if the image is over 4kB or not.
*
* @param name the full name with a path of an image file.
*
* @return
*/
// private final final static final boolean isImgBelow4KB(String name) {
// boolean isNotOver = ConfigManager.IMAGE_TRANSPARENCY;
// try {
// int imgSize = 0;
// InputStream is = null;
// is = new Object().getClass().getResourceAsStream(name);
// imgSize = is.available();
// if (imgSize < 1024 * 4){
// isNotOver = true;
// }
// } catch (Exception e) {
// printOutToConsole("LPUtils.isImgOver4KB(): " + e.toString());
// }
// return isNotOver;
// }
public final static String abbrevString(String title, Paint font, int maxWidth) {
if (title == null)
return "";
if (font.measureText(title) > maxWidth) {
int pos = nextLinePosition(title.toCharArray(), 0, font, maxWidth,
font.getTextWidths(ELLIPSIS, 0, ELLIPSIS.length, new float[ELLIPSIS.length]));
if (pos == -1)
return title;
else
return title.substring(0, pos) + "...";
} else
return title;
}
final static String appendDots(String src, Paint font, int maxWidth) {
if (src == null || font == null || maxWidth < 0) {
return null;
}
String dest = null;
dest = src + "...";
while (font.measureText(dest) > maxWidth) {
dest = src.substring(0, src.length() - 2) + "...";
}
return dest;
}
private final static char ELLIPSIS[] = { '.', '.', '.' };
public final static int getEllipsisWidth(Paint f) {
return f.getTextWidths(ELLIPSIS, 0, ELLIPSIS.length, new float[ELLIPSIS.length]);
}
/**
* Is this character whitespace?
*/
public final static boolean isWhitespace(char ch) {
return (ch == ' ' || ch == '\r' || ch == '\n' || ch == '\t');
}
/**
* Case insensitive string match
*
* @param ignoreCase
* if true, ignore case
* @param s1
* @param s2
*/
public final static boolean stringMatch(boolean ignoreCase, String s1, String s2) {
int cmplen = Math.max(s1.length(), s2.length());
if ((s1 == null) || (s2 == null)) {
return false;
}
return s1.regionMatches(true, 0, s2, 0, cmplen);
}
/**
* Given a starting position in a string, return the next position that this string should be split if it cannot fit
* within the given width. If it does not fit, we will include an ellipsis at the end to indicate broken line. If it
* does fit, we return -1.
*/
public final static int nextLinePosition(char[] str, int pos, Paint f, int maxWidth, int ellWidth) {
int strWidth = 0;
while (pos < str.length) {
if (str[pos] == '\n') {
return pos;
}
strWidth += f.measureText(String.valueOf(str[pos]));
if (strWidth + ellWidth > maxWidth) {
// If the rest of string can fit instead of the ellipsis, put it
// there.
// int tmp = f.getTextWidths(str, pos + 1, str.length - pos - 1,
// new float[str.length - pos - 1]);
int tmp = (int) f.measureText(str, pos + 1, str.length - pos - 1);
if (strWidth + tmp <= maxWidth) {
return -1;
} else {
return pos;
}
}
++pos;
}
return -1;
}
/**
* Starting from pos in str, find the longest string that fits in maxLineWidth. If doesn't fit, break the line by
* hyphenation or at a line break point.
*
* If newLine is true, we are starting from a new line and should get rid of initial white spaces.
*
* Returns the position of the next character to be scanned in str after this line break.
*/
public final static int nextLineLayout(char[] str, int pos, Paint f, int maxLineWidth, int hyphenWidth,
int[] linebreak, boolean newLine) {
int strWidth = 0;
int startPos = pos;
int lastBreakPoint = pos;
// Filter out initial white spaces at start of a line.
if (newLine) {
while (pos < str.length && (str[pos] == ' ' || str[pos] == '\t'))
++pos;
}
linebreak[LBI_START] = pos;
while (pos < str.length) {
boolean punct = false;
switch (str[pos]) {
// NOTE: don't recognize CR because in XML, only <br> or <p> should
// matter.
case '\n':
// Insert a newline.
linebreak[LBI_BREAK] = pos - 1;
linebreak[LBI_NEXT] = pos + 1;
linebreak[LBI_TYPE] = LB_SKIP;
return pos + 1;
case '<': {
// Look ahead to see if we have a <p>, <br>, <p/>, <br/>, </p>,
// </br>, <b> <tr> <td>
// XXX We ignore complex cases, such as newlines are inserted
// into tags.
// NOTE: the 32 limit is an arbitrary one
int endPos = pos;
while (endPos < (str.length - 1) && endPos - pos < 8) {
++endPos;
if (str[endPos] == '>') {
int pp1 = pos + 1;
int pp2 = pos + 2;
int pp3 = pos + 3;
char ch_pp1 = Character.toLowerCase(str[pp1]);
if (ch_pp1 == 'p' && (pp2 == endPos || str[pp2] == '/' || str[pp2] == ' ')) {
linebreak[LBI_BREAK] = pos - 1;
linebreak[LBI_NEXT] = endPos + 1;
linebreak[LBI_TYPE] = LB_PARAGRAPH; // Paragraph
return endPos + 1;
} else if (ch_pp1 == 'b'
&& (pp2 == endPos || (Character.toLowerCase(str[pp2]) == 'r' && (pp3 == endPos
|| str[pp3] == '/' || str[pp3] == ' ')))) {
linebreak[LBI_BREAK] = pos - 1;
linebreak[LBI_NEXT] = endPos + 1;
// Only add newline if this is a br.
linebreak[LBI_TYPE] = (pp2 == endPos) ? LB_SKIP : LB_NEWLINE;
return endPos + 1;
} else if (ch_pp1 == '/' || ch_pp1 == 'i' || ch_pp1 == 'e' || ch_pp1 == 's' || ch_pp1 == 'c'
|| ch_pp1 == 't' || ch_pp1 == 'h') {
// Ignore <em>, <strong>, <center>
// Ignore all kinds of end tags.
linebreak[LBI_BREAK] = pos - 1;
linebreak[LBI_NEXT] = endPos + 1;
linebreak[LBI_TYPE] = LB_SKIP;
return endPos + 1;
}
}
}
// XXX FIXME: Ignore <a href=...> and <font ...>, <a target...>,
// <a title...>, <a rel...> here. We will capture the hyper link
// and tie it to the link body later.
char ch_pp1 = Character.toLowerCase(str[pos + 1]);
if (str.length - pos >= 5 && (ch_pp1 == 'a' || ch_pp1 == 'f')) {
if (ch_pp1 == 'a') {
// Skip spaces between a and href
endPos = pos + 2;
while (endPos < str.length && str[endPos] == ' ')
++endPos;
} else {
endPos = pos + 1;
}
if (str.length - endPos > 3) {
ch_pp1 = Character.toLowerCase(str[endPos]);
char ch_pp2 = Character.toLowerCase(str[endPos + 1]);
char ch_pp3 = Character.toLowerCase(str[endPos + 2]);
char ch_pp4 = Character.toLowerCase(str[endPos + 3]);
if ((ch_pp1 == 'h' && ch_pp2 == 'r' && ch_pp3 == 'e' && ch_pp4 == 'f')
|| (ch_pp1 == 'f' && ch_pp2 == 'o' && ch_pp3 == 'n' && ch_pp4 == 't')
|| (ch_pp1 == 't' && ch_pp2 == 'a' && ch_pp3 == 'r' && ch_pp4 == 'g')
|| (ch_pp1 == 't' && ch_pp2 == 'i' && ch_pp3 == 't' && ch_pp4 == 'l')
|| (ch_pp1 == 'r' && ch_pp2 == 'e' && ch_pp3 == 'l')) {
// Ignore everything, including newline, till next
// '>'
while (endPos < str.length && str[endPos] != '>')
++endPos;
}
}
linebreak[LBI_BREAK] = pos - 1;
if (endPos + 1 < str.length)
linebreak[LBI_NEXT] = endPos + 1;
else
linebreak[LBI_NEXT] = str.length - 1;
linebreak[LBI_TYPE] = LB_SKIP;
return endPos + 1;
}
// XXX FIXME: Ignore <p class=...> & <img src=...>,<span ...>
// <lp...> , </lp:...>, <table > <div>here. We will capture the
// hyper link
// and tie it to the link body later.
if (str.length - pos >= 8
&& (ch_pp1 == 'p' || ch_pp1 == 'i' || ch_pp1 == 'l' || ch_pp1 == 's' || ch_pp1 == 't' || ch_pp1 == 'd')
|| ch_pp1 == '/') {
endPos = pos + 2;
// Ignore everything, including newline, till next '>'
while (endPos < str.length && str[endPos] != '>')
++endPos;
linebreak[LBI_BREAK] = pos - 1;
linebreak[LBI_NEXT] = endPos + 1;
linebreak[LBI_TYPE] = LB_SKIP;
return endPos + 1;
}
// For tags that we do not recognize, fall through.
}
case ' ':
case '\t':
lastBreakPoint = pos;
// fall through
default:
// Check one more character to see if it fits current string. If
// not,
// try to break at the last line break point. If that is too far
// away,
// add a hyphen at this place.
strWidth += f.measureText(String.valueOf(str[pos]));
if (strWidth >= maxLineWidth) {
// This was meant for hyphenation. When we insert a newline,
// can do that right at the starting point.
if (lastBreakPoint == startPos) {
lastBreakPoint = (pos == startPos) ? pos : (pos - 1);
}
linebreak[LBI_BREAK] = lastBreakPoint - 1;
linebreak[LBI_NEXT] = lastBreakPoint;
linebreak[LBI_TYPE] = LB_NEWLINE;
return lastBreakPoint;
}
}
++pos;
}
return -1;
}
/**
* Starting from pos in str, find the longest string that fits in maxLineWidth.
*
* Don't need to check
* <p>
* , <br>
* ,
* <p/>
* , <br/>
* ,
* </p>
* , </br>, <b>
* <tr>
* <td>again. They should be parsed by HTML.
*/
public final static int getLineEndIndex(char[] chars, int pos, Paint f, int LineWidth, int[] linebreak,
boolean newLine, boolean isTrimHeadBlank, boolean isBreakWord) {
if (chars == null || f == null)
return -1;
int strWidth = 0;
int startPos = pos;
int lastBreakPoint = pos;
// Filter out initial white spaces at start of a line.
if (newLine) {
if (isTrimHeadBlank) {
while (pos < chars.length && (chars[pos] == ' ' || chars[pos] == '\t'))
++pos;
} else {
while (pos < chars.length && chars[pos] == '\t')
++pos;
}
}
linebreak[LBI_START] = pos;
while (pos < chars.length) {
switch (chars[pos]) {
// NOTE: don't recognize CR because in XML, only <br> or <p> should
// matter.
case '\n':
chars[pos] = ' ';
return pos;
case ' ':
case '.':
case '/':
case '\t':
lastBreakPoint = pos + 1;
default:
// Check one more character to see if it fits current string. If
// not,
// try to break at the last line break point.
strWidth += f.measureText(String.valueOf(chars[pos]));
if (strWidth > LineWidth) {
if (isBreakWord) {
return pos - 1;
} else {
// It is possible that a word's width bigger than line
// width.
if (lastBreakPoint == startPos && pos > startPos && newLine) {
return pos - 1;
} else {
return lastBreakPoint;
}
}
}
}
++pos;
}
return chars.length;
}
public final static boolean isPunct(char ch) {
switch (ch) {
case '.':
case ',':
case '?':
case '!':
case '\'':
case '"':
case ':':
case ';':
case '-':
return true;
}
return false;
}
public final static String escapeHTML(String str) {
if (str == null)
return null;
StringBuffer sb = new StringBuffer();
int num = str.length();
for (int i = 0; i < num; i++) {
char ch = str.charAt(i);
switch (ch) {
case '<':
sb.append("<");
break;
case '>':
sb.append(">");
break;
case '&':
sb.append("&");
break;
case '"':
sb.append(""");
break;
case ' ':
sb.append(" ");
break;
default:
sb.append(ch);
break;
}
}
return sb.toString();
}
/**
* Unescape a HTML string by filtering out &...; sequences, including &#<numbers>;. We do not consider the case
* where one sequence is broken into multiple lines.
*/
public final static String unescapeHTML(String str) {
char[] src = str.toCharArray();
char[] dest = new char[src.length];
boolean foundAmber = false;
int escapeIdx = -1;
int dstIdx = 0;
int j;
int ch;
for (int i = 0; i < src.length; i++) {
switch (src[i]) {
case '&':
// we should not miss the case &aaa&.
while (escapeIdx > 0 && escapeIdx < i) {
dest[dstIdx++] = src[escapeIdx++];
}
escapeIdx = i;
break;
case ';':
if (escapeIdx >= 0) {
if (src[escapeIdx + 1] == '#') {
ch = 0;
for (j = escapeIdx + 2; j < i; ++j) {
if (src[j] < '0' || src[j] > '9') {
ch = -1;
break;
} else {
ch *= 10;
ch += src[j] - '0';
}
}
} else {
int pp1 = escapeIdx + 1;
int pp2 = escapeIdx + 2;
int pp3 = escapeIdx + 3;
int pp4 = escapeIdx + 4;
int pp5 = escapeIdx + 5;
if (src[pp1] == 'q' && src[pp2] == 'u' && src[pp3] == 'o' && src[pp4] == 't' && pp5 == i)
ch = '"';
else if (src[pp1] == 'a' && src[pp2] == 'm' && src[pp3] == 'p' && pp4 == i)
ch = '&';
else if (src[pp1] == 'l' && src[pp2] == 't' && pp3 == i)
ch = '<';
else if (src[pp1] == 'g' && src[pp2] == 't' && pp3 == i)
ch = '>';
else if (src[pp1] == 'n' && src[pp2] == 'b' && src[pp3] == 's' && src[pp4] == 'p' && pp5 == i)
ch = ' ';
else
ch = -1;
if (ch != -1) {
dest[dstIdx++] = (char) ch;
escapeIdx = -1;
break;
}
}
} else
ch = -1;
// Replace the Html Special Characters likes &#<numbers>.
if (ch >= 0) {
switch (ch) {
case 123:
ch = '{';
break;
case 125:
ch = '}';
break;
case 133:
for (int k = 0; k < 3; k++)
dest[dstIdx++] = '.';
ch = -1;
break;
case 146:
ch = '\'';
break;
case 147:
case 148:
ch = '"';
break;
case 151:
ch = '-';
break;
default:
ch = ' ';
break;
}
if (ch != -1)
dest[dstIdx++] = (char) ch;
} else {
// If current charactor is only a characters ";" ,
// not a Html Special Characters, we copy it in dest.
if (escapeIdx < 0)
dest[dstIdx++] = src[i];
else {
for (j = escapeIdx; j <= i; ++j)
dest[dstIdx++] = src[j];
}
}
escapeIdx = -1;
break;
default:
if (escapeIdx < 0)
dest[dstIdx++] = src[i];
else if (escapeIdx > 0 && ((i - escapeIdx) > 5)) {
for (int k = escapeIdx; k <= i; k++) {
dest[dstIdx++] = src[k];
}
escapeIdx = -1;
}
break;
}
}
return String.valueOf(dest, 0, dstIdx);
}
/**
* non-ASCII characters are encoded as: first using the UTF-8 algorithm to encode to a sequence of 2 or 3 bytes,
* then each of these bytes is encoded as "%xx".
*/
public final static String escapeURIComponent(String str) {
printOutToConsole("escapeURIComponent " + str);
if (str == null)
return null;
StringBuffer sbuf = new StringBuffer();
int ch;
int len = str.length();
for (int i = 0; i < len; i++) {
ch = str.charAt(i);
if ('A' <= ch && ch <= 'Z') {
sbuf.append((char) ch);
} else if ('a' <= ch && ch <= 'z') {
sbuf.append((char) ch);
} else if ('0' <= ch && ch <= '9') {
sbuf.append((char) ch);
} else if (ch == '-' || ch == '_' || ch == '.' || ch == '!' || ch == '~' || ch == '*' || ch == '\''
|| ch == '(' || ch == ')') {
sbuf.append((char) ch);
} else if (ch < 0x0F) {
sbuf.append('%');
sbuf.append('0');
sbuf.append(Integer.toHexString(ch));
} else if (ch < 0x7F) {
sbuf.append('%');
sbuf.append(Integer.toHexString(ch));
} else if (ch <= 0x07FF) { // non-ASCII characters and value <=
// 0x7FF
sbuf.append('%');
sbuf.append(Integer.toHexString(0xc0 | (ch >> 6)));
sbuf.append('%');
sbuf.append(Integer.toHexString(0x80 | (ch & 0x3F)));
} else { // non-ASCII characters and value <= 0xFFFF
sbuf.append('%');
sbuf.append(Integer.toHexString(0xe0 | (ch >> 12)));
sbuf.append('%');
sbuf.append(Integer.toHexString(0x80 | ((ch >> 6) & 0x3F)));
sbuf.append('%');
sbuf.append(Integer.toHexString(0x80 | (ch & 0x3F)));
}
}
return sbuf.toString();
}
public final static String unescapeURIComponent(String url) {
if (url == null)
return null;
StringBuffer sbuf = new StringBuffer();
int len = url.length();
int ch;
int b;
int total = 0;
int more = -1;
int hb;
int lb;
for (int i = 0; i < len; i++) {
switch (ch = url.charAt(i)) {
case '%':
ch = url.charAt(++i);
hb = (Character.isDigit((char) ch) ? ch - '0' : 10 + Character.toLowerCase((char) ch) - 'a') & 0xF;
ch = url.charAt(++i);
lb = (Character.isDigit((char) ch) ? ch - '0' : 10 + Character.toLowerCase((char) ch) - 'a') & 0xF;
b = (hb << 4) | lb;
break;
default:
b = ch;
}
// Decode byte b as UTF-8, sumb collects incomplete chars
if ((b & 0xc0) == 0x80) {
total = (total << 6) | (b & 0x3f);
if (--more == 0)
sbuf.append((char) total);
} else if ((b & 0x80) == 0x00) {
sbuf.append((char) b);
} else if ((b & 0xe0) == 0xc0) {
total = b & 0x1f;
more = 1;
} else if ((b & 0xf0) == 0xe0) {
total = b & 0x0f;
more = 2;
} else if ((b & 0xf8) == 0xf0) {
total = b & 0x07;
more = 3;
} else if ((b & 0xfc) == 0xf8) {
total = b & 0x03;
more = 4;
} else {
total = b & 0x01;
more = 5;
}
}
return sbuf.toString();
}
/**
* Convert a string of double number to an integer, assuming the number is a coordinate.
*/
public final static int strCoordToInt(String strDouble) {
char[] src = strDouble.toCharArray();
StringBuffer dst = new StringBuffer();
int digitsAfterDot = 0;
boolean dotFound = false;
for (int i = 0; i < src.length && digitsAfterDot < 6; i++) {
if (src[i] != '.') {
dst.append(src[i]);
if (dotFound) {
++digitsAfterDot;
}
} else {
dotFound = true;
}
}
// multiply by 1000000
for (int i = digitsAfterDot; i < 6; i++) {
dst.append('0');
}
return Integer.parseInt(dst.toString());
}
/**
* Convert an integer coordinate into a float string.
*/
public final static String intToFloatCoord(int coord) {
StringBuffer buf = new StringBuffer();
buf.append(coord);
buf.insert(buf.length() - 6, '.');
return buf.toString();
}
/**
* Parse a ISO8601 date string and return it in a calendar object. Return UTC time.
*/
public final static long parseISO8601(String text) throws Exception {
printOutToConsole(text);
// Example date string: 2006-11-29T15:30:00.000-08:00
int idx = text.indexOf('T');
if (idx == -1) {
// Invalid date
throw new IOException("錯誤的資料格?");
}
String date = text.substring(0, idx);
int idx2 = text.indexOf('-', ++idx);
String time;
if (idx2 == -1) {
time = text.substring(idx);
} else {
time = text.substring(idx, idx2);
}
idx = date.indexOf('-');
int year = Integer.parseInt(date.substring(0, idx));
idx2 = date.indexOf('-', ++idx);
int month = Integer.parseInt(date.substring(idx, idx2));
int day = Integer.parseInt(date.substring(++idx2));
idx = time.indexOf(':');
int hour = Integer.parseInt(time.substring(0, idx));
idx2 = time.indexOf(':', ++idx);
int min = Integer.parseInt(time.substring(idx, idx2));
// The separater between seconds and time offset field can be 'Z' for
// standard time,
// or +/- for time zone offset.
int idx3 = time.indexOf('+', ++idx2);
String zoneString = null;
int zoneOffset = 0; // time zone offset, in seconds
if (idx3 == -1) {
idx3 = time.indexOf('-', idx2);
} else {
zoneString = time.substring(idx3 + 1);
zoneOffset = 1;
}
if (idx3 == -1) {
idx3 = time.indexOf('Z', idx2);
} else {
zoneString = time.substring(idx3 + 1);
zoneOffset = -1;
}
if (idx3 == -1) {
idx3 = time.length();
} else if (zoneString != null) {
int idx4 = zoneString.indexOf(':', 0);
if (idx4 != -1) {
int zoneHour;
int zoneMin;
try {
zoneHour = Integer.parseInt(zoneString.substring(0, idx4));
zoneMin = Integer.parseInt(zoneString.substring(idx4 + 1));
zoneOffset *= zoneHour * 3600 + zoneMin * 60;
} catch (Exception ignored) {
zoneOffset = 0;
}
}
}
int sec = 0;
if (idx3 > idx2) {
// Filter out sub-second component
int idx4 = time.indexOf('.', idx2);
if (idx4 != -1)
idx3 = idx4;
sec = Integer.parseInt(time.substring(idx2, idx3));
}
// Make a calendar time assuming that is UTC, then we'll make time zone
// adjustment from UTC seconds.
Calendar updatedDate = Calendar.getInstance();
updatedDate.set(Calendar.YEAR, year);
updatedDate.set(Calendar.MONTH, month - 1); // NOTE: month starts from
// 0??
updatedDate.set(Calendar.DAY_OF_MONTH, day); // Day start from 1??
updatedDate.set(Calendar.HOUR_OF_DAY, hour);
updatedDate.set(Calendar.MINUTE, min);
updatedDate.set(Calendar.SECOND, sec);
updatedDate.set(Calendar.MILLISECOND, 0);
printOutToConsole("date: " + year + "-" + month + "-" + day + " " + hour + ":" + min + ":" + sec + " time "
+ updatedDate.getTime());
printOutToConsole("timezone offset " + zoneOffset);
return updatedDate.getTime().getTime() + zoneOffset * 1000;
}
/**
* Displays a UTC time (in milliseconds) as MM/DD-HH:MM
*/
public final static void formatTimeString(long utc, StringBuffer str) {
Calendar cal = Calendar.getInstance();
cal.setTime(new Date(utc));
str.append(cal.get(Calendar.MONTH) + 1); // NOTE: month starts from 0
str.append("/");
str.append(cal.get(Calendar.DAY_OF_MONTH));
str.append("-");
str.append(cal.get(Calendar.HOUR_OF_DAY));
str.append(":");
str.append(cal.get(Calendar.MINUTE));
}
/**
* Displays a UTC time in milliseconds as YYYY/MM/DD
*/
public final static void formatDateString(long utc, StringBuffer str) {
Calendar cal = Calendar.getInstance();
cal.setTime(new Date(utc));
str.append(cal.get(Calendar.YEAR));
str.append("/");
str.append(cal.get(Calendar.MONTH) + 1); // NOTE: month starts from 0
str.append("/");
str.append(cal.get(Calendar.DAY_OF_MONTH));
}
/**
* Display a UTC time as format hh:mm am/pm
*/
public final static void fromatTimeAmPm(long utc, StringBuffer str) {
Calendar cal = Calendar.getInstance();
cal.setTime(new Date(utc));
int hour = cal.get(Calendar.HOUR);
int minu = cal.get(Calendar.MINUTE);
if (hour < 10)
str.append("0");
str.append(hour);
str.append(":");
if (minu < 10)
str.append("0");
str.append(minu);
if (cal.get(Calendar.AM_PM) == 0)
str.append(" AM");
else
str.append(" PM");
}
/**
* Parse simple state response XMLs from server and retrieve attributes from it. Used by UserManager, PoiRepository
* (add/remove POI), etc.
*/
public final static String getXMLResponseAttribute(String reply, String attr, int startIndex, char matchCh) {
int start = reply.indexOf(attr, startIndex);
if (start < 0)
return null;
start += attr.length();
int end = reply.indexOf(matchCh, start);
if (end > start) {
String s = reply.substring(start, end);
return s;
}
return null;
}
/**
* Check the email address whether is valid.
*/
public final static boolean checkEmail(String emailAdd) {
int length = emailAdd.length();
int temp1 = emailAdd.indexOf("@");
int temp2 = emailAdd.indexOf(".");
// temp1 > 1 means in this email address contains an “@?and there is a
// user’s name before it.
// temp2 != -1 means in this email address contains an "."
// (length - temp1 > 3) means after “@?contains at least one letter
// except ??
// (length - temp2 > 1) means "." is not the last letter
if (temp1 > 1 && temp2 != -1 && (length - temp1 > 3) && (length - temp2 > 1)) {
return true;
} else
return false;
}
/*
* A Java implementation of the Secure Hash Algorithm, SHA-1, as defined in FIPS PUB 180-1 Copyright (C) Sam Ruby
* 2004 All rights reserved
*
* Based on code Copyright (C) Paul Johnston 2000 - 2002. See http://pajhome.org.uk/site/legal.html for details.
*
* Converted to Java by Russell Beattie 2004 Base64 logic and inlining by Sam Ruby 2004 Bug fix correcting single
* bit error in base64 code by John Wilson
*
* BSD License
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following
* disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
* the following disclaimer in the documentation and/or other materials provided with the distribution.
*
* Neither the name of the author nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// /*
// * Bitwise rotate a 32-bit number to the left
// */
// private final final static int rol(int num, int cnt) {
// return (num << cnt) | (num >>> (32 - cnt));
// }
/*
* Take a string and return the base64 representation of its SHA-1.
*/
public final static String sha1(String str) throws Exception {
// Convert a string to a sequence of 16-word blocks, stored as an array.
// Append padding bits and the length, as described in the SHA1 standard
byte[] x = str.getBytes("UTF-8");
int[] blks = new int[(((x.length + 8) >> 6) + 1) * 16];
int i;
for (i = 0; i < x.length; i++) {
blks[i >> 2] |= x[i] << (24 - (i % 4) * 8);
}
blks[i >> 2] |= 0x80 << (24 - (i % 4) * 8);
blks[blks.length - 1] = x.length * 8;
// calculate 160 bit SHA1 hash of the sequence of blocks
int[] w = new int[80];
int a = 1732584193;
int b = -271733879;
int c = -1732584194;
int d = 271733878;
int e = -1009589776;
int num;
for (i = 0; i < blks.length; i += 16) {
int olda = a;
int oldb = b;
int oldc = c;
int oldd = d;
int olde = e;
for (int j = 0; j < 80; j++) {
if (j < 16) {
w[j] = blks[i + j];
} else {
num = w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16];
w[j] = ((num << 1) | (num >>> (32 - 1)));
}
int t = ((a << 5) | (a >>> (32 - 5)))
+ e
+ w[j]
+ ((j < 20) ? 1518500249 + ((b & c) | ((~b) & d)) : (j < 40) ? 1859775393 + (b ^ c ^ d)
: (j < 60) ? -1894007588 + ((b & c) | (b & d) | (c & d)) : -899497514 + (b ^ c ^ d));
e = d;
d = c;
c = ((b << 30) | (b >>> (32 - 30))); // rol(b, 30);
b = a;
a = t;
}
a = a + olda;
b = b + oldb;
c = c + oldc;
d = d + oldd;
e = e + olde;
}
// Convert 160 bit hash to base64
int[] words = { a, b, c, d, e, 0 };
byte[] base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".getBytes();
byte[] result = new byte[28];
for (i = 0; i < 27; i++) {
int start = i * 6;
int word = start >> 5;
int offset = start & 0x1f;
if (offset <= 26) {
result[i] = base64[(words[word] >> (26 - offset)) & 0x3F];
} else if (offset == 28) {
result[i] = base64[(((words[word] & 0x0F) << 2) | ((words[word + 1] >> 30) & 0x03)) & 0x3F];
} else {
result[i] = base64[(((words[word] & 0x03) << 4) | ((words[word + 1] >> 28) & 0x0F)) & 0x3F];
}
}
result[27] = '=';
return new String(result);
}
public final static Bitmap bilinearResample(Bitmap oriImg, int newWidth, int newHeight) {
return bilinearResample(oriImg, newWidth, newHeight, WHITE);
}
/**
* Function for scale an image from a large to a smaller size, then return a new image with new size predefined.
*/
public final static Bitmap bilinearResample(Bitmap oriImg, int newWidth, int newHeight, int bgColor) {
int oldW = oriImg.getWidth();
int oldH = oriImg.getHeight();
int[] ori_rgb = new int[oldW * oldH];
int[] des_rgb = new int[newWidth * newHeight];
oriImg.getPixels(ori_rgb, 0, oldW, 0, 0, oldW, oldH);
int newIndex = 0;
// draw each pixel in the new image
for (int i = 1; i <= newHeight; i++) {
// generate the y calculation variables
int interplY = (i - 1) * oldH / newHeight;
int calcY = (i - 1) * oldH % newHeight;
for (int j = 1; j <= newWidth; j++) {
// generate the x calculation variables
int interplX = (j - 1) * oldW / newWidth;
int calcX = (j - 1) * oldW % newWidth;
int theColour1 = ori_rgb[(interplX) + (interplY) * oldW];
int theColour2 = ori_rgb[(interplX + 1) + (interplY) * oldW];
int theColour3 = ori_rgb[(interplX) + (interplY + 1) * oldW];
int theColour4 = ori_rgb[(interplX + 1) + (interplY + 1) * oldW];
// calculate the new colour
int alpha1 = (theColour1 >> 24 & 0xFF) * (newHeight - calcY) / newHeight + (theColour3 >> 24 & 0xFF)
* calcY / newHeight;
int alpha2 = (theColour2 >> 24 & 0xFF) * (newHeight - calcY) / newHeight + (theColour4 >> 24 & 0xFF)
* calcY / newHeight;
int newAlpha = isOutofColor(alpha1 * (newWidth - calcX) / newWidth + alpha2 * calcX / newWidth);
int newColor1r = (theColour1 >> 16 & 0xFF) * (newHeight - calcY) / newHeight
+ (theColour3 >> 16 & 0xFF) * calcY / newHeight;
int newColor2r = (theColour2 >> 16 & 0xFF) * (newHeight - calcY) / newHeight
+ (theColour4 >> 16 & 0xFF) * calcY / newHeight;
int newColorr = isOutofColor(newColor1r * (newWidth - calcX) / newWidth + newColor2r * calcX / newWidth);
int newColor1g = (theColour1 >> 8 & 0xFF) * (newHeight - calcY) / newHeight + (theColour3 >> 8 & 0xFF)
* calcY / newHeight;
int newColor2g = (theColour2 >> 8 & 0xFF) * (newHeight - calcY) / newHeight + (theColour4 >> 8 & 0xFF)
* calcY / newHeight;
int newColorg = isOutofColor(newColor1g * (newWidth - calcX) / newWidth + newColor2g * calcX / newWidth);
int newColor1b = (theColour1 & 0xFF) * (newHeight - calcY) / newHeight + (theColour3 & 0xFF) * calcY
/ newHeight;
int newColor2b = (theColour2 & 0xFF) * (newHeight - calcY) / newHeight + (theColour4 & 0xFF) * calcY
/ newHeight;
int newColorb = isOutofColor(newColor1b * (newWidth - calcX) / newWidth + newColor2b * calcX / newWidth);
int newColor = ((newAlpha & 0xFF) << 24) | ((newColorr & 0xFF) << 16) | ((newColorg & 0xFF) << 8)
| (newColorb & 0xFF);
// Set this pixel into the new image
des_rgb[newIndex++] = newColor;
}
}
Bitmap desImage = null;
desImage = Bitmap.createBitmap(des_rgb, newWidth, newHeight, Bitmap.Config.RGB_565);
// 縮放圖片
desImage = Bitmap.createScaledBitmap(desImage, newWidth, newHeight, true);
if (desImage == null)
desImage = oriImg;
return desImage;
}
// it's used by the function bilinearResample().
final static int isOutofColor(int color) {
if (color < 0)
color = 0;
if (color > 255)
color = 255;
return color;
}
/**
* If we are on low memory or the photo can not be loaded, we will show a red cross in the photo frame.
*/
final static void createImageLoadFail(Canvas canvas) {
Paint paint = new Paint();
paint.setTypeface(Typeface.DEFAULT);
int wh = (int) (4 * paint.getTextSize());
canvas.drawRGB(0, 0, 0);
canvas.drawRect(new Rect(0, 0, wh - 1, wh - 1), new Paint());
canvas.drawRGB(255, 0, 0);
int xStart = wh / 2 - 3;
int yStart = wh / 2 - 3;
canvas.drawLine(xStart, yStart, xStart + 6, yStart + 6, paint);
canvas.drawLine(xStart, yStart + 1, xStart + 6, yStart + 7, paint);
canvas.drawLine(xStart + 6, yStart, xStart, yStart + 6, paint);
canvas.drawLine(xStart + 6, yStart + 1, xStart, yStart + 7, paint);
}
final static boolean isInComponent(int x, int y, View c) {
if (c == null)
return false;
if (x < c.getLeft() || x > c.getLeft() + c.getWidth() || y < c.getTop() || y > c.getTop() + c.getHeight())
return false;
else
return true;
}
/**
* Divide the given string to paragraphs with the given font and width.
*
* @param strSource
* the source string
* @param font
* the font
* @param width
* the width of each line.
* @return the String array
*/
public final static String[] getParagraph(final String strSource, final Paint font, final int width) {
String[] strs = null;
if (strSource == null || font == null || width <= 0) {
return strs;
} else if (strSource.equals("")) {
strs = new String[] { "" };
return strs;
}
Vector<String> vector = new Vector<String>();
try {
String temp = strSource;
int i, j;
boolean isOver;
while (!temp.equals("")) {
isOver = false;
i = temp.indexOf("\n");
if (i == -1) {
i = temp.length();
isOver = font.measureText(temp) > width;
}
if (i > 0 && font.measureText(temp.substring(0, i)) > width) {
isOver = true;
}
if (isOver) {
// gets the critical point
while (font.measureText(temp.substring(0, i)) > width) {
i = i - 1;
}
}
vector.addElement(temp.substring(0, i));
if (i == temp.length()) {
temp = "";
} else {
if (temp.charAt(i) == '\n') {
temp = temp.substring(i + 1);
} else {
temp = temp.substring(i);
}
}
}
if (vector.size() > 0) {
strs = new String[vector.size()];
vector.copyInto(strs);
}
} catch (Exception e) {
printOutToConsole("getSubsection:" + e);
}
return strs;
}
/**
* Divide the given string to paragraphs with the given font and width.
*
* @param strSource
* the source string
* @param font
* the font
* @param width
* the width of each line.
* @return the String array
*/
public final static String[] getParagraph(final String strSource, final Paint font, final int width,
final String splitChars) {
String[] strs = null;
if (strSource == null || font == null || width <= 0) {
return strs;
} else if (strSource.equals("")) {
strs = new String[] { "" };
return strs;
}
Vector vector = new Vector(2);
try {
String temp = strSource;
int i, j;
boolean isOver;
while (!temp.equals("")) {
isOver = false;
i = temp.indexOf("\n");
if (i == -1) {
i = temp.length();
isOver = font.measureText(temp) > width;
}
if (i > 0 && font.measureText(temp.substring(0, i)) > width) {
isOver = true;
}
if (isOver) {
// gets the critical point
while (font.measureText(temp.substring(0, i)) > width) {
i = i - 1;
}
if (!splitChars.equals("")) {
j = i; // restore the last index of this line for maybe
// there is a long word over a line.
while (splitChars.indexOf(temp.charAt(i - 1)) == -1) {
i--;
if (i == 0) {
i = j; // crash a word, if it is needed.
break;
}
}
}
}
vector.addElement(temp.substring(0, i));
if (i == temp.length()) {
temp = "";
} else {
if (temp.charAt(i) == '\n') {
temp = temp.substring(i + 1);
} else {
temp = temp.substring(i);
}
}
}
if (vector.size() > 0) {
strs = new String[vector.size()];
vector.copyInto(strs);
}
} catch (Exception e) {
printOutToConsole("getSubsection:" + e);
}
return strs;
}
/**
* @param src
* source image.
* @param desW
* expected width
* @param desH
* expected height
* @param isBackgroundTrans
* makes the background transparent
* @param isTrans
* makes the image transparent
* @return Image
*/
// public final final static final Image scaleImage(Image src, int desW, int desH,
// boolean isBackgroundTrans, boolean isTrans) {
// Image desImg = null;
// try {
// int srcW = src.getWidth(); // source image width
// int srcH = src.getHeight(); // source image height
// int[] srcBuf = new int[srcW * srcH]; // source image pixel
// src.getRGB(srcBuf, 0, srcW, 0, 0, srcW, srcH);
// // compute interpolation table
// int[] tabY = new int[desH];
// int[] tabX = new int[desW];
// int sb = 0;
// int db = 0;
// int tems = 0;
// int temd = 0;
// int distance = srcH > desH ? srcH : desH;
// for (int i = 0; i <= distance; i++) { /* vertical direction */
// tabY[db] = sb;
// tems += srcH;
// temd += desH;
// if (tems > distance) {
// tems -= distance;
// sb++;
// }
// if (temd > distance) {
// temd -= distance;
// db++;
// }
// }
// sb = 0;
// db = 0;
// tems = 0;
// temd = 0;
// distance = srcW > desW ? srcW : desW;
// for (int i = 0; i <= distance; i++) { /* horizontal direction */
// tabX[db] = (short) sb;
// tems += srcW;
// temd += desW;
// if (tems > distance) {
// tems -= distance;
// sb++;
// }
// if (temd > distance) {
// temd -= distance;
// db++;
// }
// }
// // formation enlarge and shorten buffer pixel
// int[] desBuf = new int[desW * desH];
// int dx = 0;
// int dy = 0;
// int sy = 0;
// int oldy = -1;
// for (int i = 0; i < desH; i++) {
// if (oldy == tabY[i]) {
// System.arraycopy(desBuf, dy - desW, desBuf, dy, desW);
// } else {
// dx = 0;
// for (int j = 0; j < desW; j++) {
// desBuf[dy + dx] = srcBuf[sy + tabX[j]];
// dx++;
// }
// sy += (tabY[i] - oldy) * srcW;
// }
// oldy = tabY[i];
// dy += desW;
// }
// if (isTrans) {
// // int a= 100;//set the transparence of pixel 100
// for (int i = 0; i < desBuf.length; i++) {
// if (desBuf[i] == 0x00FFFFFF)
// continue;
// int alpha = ((desBuf[i] & 0xff000000) >>> 24) == 0 ? 0 : 100;
// desBuf[i] = ((alpha + 1) << 24) | (desBuf[i] & 0x00FFFFFF);
// }
// }
// if (isBackgroundTrans) {
// desImg = Image.createRGBImage(desBuf, desW, desH, true);
// } else {
// desImg = Image.createRGBImage(desBuf, desW, desH, false);
// }
// } catch (Exception ex) {
// LPUtils.printException(ex);
// desImg = null;
// }
// return desImg;
// }
/**
* @param strSrc
* @param strSepr
* @return
*/
public final static String[] string2Array(String strSrc, String strSepr) {
String[] astr = null;
try {
Vector vec = new Vector(5, 1);
str2Arr(strSrc, strSepr, vec);
vec.trimToSize();
astr = new String[vec.size()];
vec.copyInto(astr);
vec.removeAllElements();
} catch (Exception ex) {
}
return astr;
}
public final static void setPrint(Activity activity) {
if (getConfigStringFormAsset(activity, "isprintMessage").equalsIgnoreCase("true")) {
isPrintMessage_ = true;
}
setActivity(activity);
}
public final static void setActivity(Activity activity) {
// TODO Auto-generated method stub
activity_ = activity;
}
public final static Activity getActivity() {
return activity_;
}
private final static void str2Arr(String strSrc, String strSepr, Vector vec) throws Exception {
if (strSrc.indexOf(strSepr) == -1) {
vec.addElement(strSrc);
} else {
vec.addElement(strSrc.substring(0, strSrc.indexOf(strSepr)));
strSrc = strSrc.substring(strSrc.indexOf(strSepr) + strSepr.length());
str2Arr(strSrc, strSepr, vec);
}
}
// 將傳入的字串中的特殊字元予以替換,保證解析順利進行或使已替換的字串還?
public final static String insteadOfSpecillCharacter(String str, boolean isReplace) {
if ((null == str) || (str.equalsIgnoreCase("")))
return str;
String strTemp = str;
// 特殊字元?
String[] A = { "&" };
// 需要替換的字元
String[] substitute;
// 替換後的字元?
String[] B = { "***###" };
// 替換後的字元
String[] beReplaced;
if (isReplace) {
// 替換特殊字串,方便解析
substitute = A;
beReplaced = B;
} else {
// 將特殊字元還?
substitute = B;
beReplaced = A;
}
int length = substitute.length;
for (int i = 0; i < length; i++) {
strTemp = strTemp.replace(substitute[i], beReplaced[i]);
}
return strTemp;
}
// 設定與是否獲得焦?
// final final static public void setFocus(boolean isFocus, int keyCode, View view) {
// if (view instanceof LPTable) {
// LPTable temp = (LPTable) view;
// // temp.setFocus(isFocus, keyCode);
// } else {
// if (isFocus) {
// view.requestFocus();
// } else {
// view.clearFocus();
// }
// }
//
// }
/**
* @param obj
*/
public final static void printOutToConsole(Object obj) {
if (isPrintMessage_) {
if (obj instanceof String) {
printOutToConsole((String) obj);
} else if (obj instanceof byte[]) {
printOutToConsole((byte[]) obj);
} else {
System.out.println(obj);
}
}
}
/**
* @param s
*/
public final static void printOutToConsole(String s) {
if (isPrintMessage_) {
int length = s.length();
int offset = 3000;
if (length > offset) {// 解決報文過長,列印不全的問題?
int n = 0;
for (int i = 0; i < length; i += offset) {
n += offset;
if (n > length)
n = length;
System.err.println("Debug = " + s.substring(i, n));
}
} else {
System.err.println("Debug = " + s);
}
}
}
/**
* @param byts
*/
public final static void printOutToConsole(byte[] byts) {
if (isPrintMessage_) {
if (byts == null) {
return;
}
for (int i = 0; i < byts.length; i++) {
System.out.print("[" + i + "]" + " : \t");
System.out.println(byts[i]);
}
}
}
public final static void LogD(String tag, String msg) {
if (isPrintMessage_) {
android.util.Log.d(tag, msg);
}
}
public final static void printException(Exception e) {
if (isPrintMessage_) {
e.printStackTrace();
}
}
/**
* 檢測服務端發過來的介面前面是否帶有/,如果沒有則自動加?提高程式健壯?
*
* @param url
* @return
*/
public final static String checkUrl(Object url) {
// TODO Auto-generated method stub
String tempString = url.toString().trim();
if (!tempString.startsWith("/"))
tempString = "/".concat(tempString);
return tempString;
}
/**
* Network Byte Order
*
* @param byts
* @param offset
* @return
*/
public final static int byteArrayToIntInNBO(byte[] byts, int offset) {
int intValue = 0;
for (int i = 0; i < 4; i++) {
int shift = (4 - 1 - i) * 8;
intValue += (byts[i + offset] & 0x000000FF) << shift;
}
return intValue;
}
/**
* Network Byte Order
*
* @param intValue
* @return
*/
public final static byte[] intToByteArrayInNBO(int intValue) {
byte[] byt = new byte[4];
for (int i = 0; i < 4; i++) {
byt[i] = (byte) (intValue >>> (24 - i * 8));
}
return byt;
}
/**
* @param firstBytes
* @param lastBytes
* @return
*/
public final static byte[] jogBytes(byte[]... byts) throws Exception {
if (byts.length == 0) {
return null;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
for (byte[] byt : byts) {
if (byt == null) {
continue;
}
out.write(byt);
}
try {
out.flush();
} catch (Exception e) {
printException(e);
}
byte[] result = out.toByteArray();
try {
out.close();
} catch (Exception e) {
printException(e);
}
out = null;
return result;
}
public final static String getStringFormAsset(Activity activity, String str) {
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(activity.getAssets().open(str)), 8 * 1024);
String line;
StringBuilder buffer = new StringBuilder();
while ((line = in.readLine()) != null)
buffer.append(line).append('\n');
return buffer.toString();
} catch (IOException e) {
Utils.printException(e);
return "";
} finally {
if (in != null) {
try {
in.close();
in = null;
} catch (IOException e) {
// TODO Auto-generated catch block
printException(e);
}
}
}
}
/**
* 修正日期值的傳輸,將?”予以去除,月份日期小於10,則前面予以?
*
* @param value
* @return
*/
public final static String adjustDate(String value) {
// TODO Auto-generated method stub
if (value.contains("-")) {
String valueTemp = value;
String year = valueTemp.substring(0, valueTemp.indexOf("-"));
String month = valueTemp.substring(valueTemp.indexOf("-") + 1, valueTemp.lastIndexOf("-"));
String day = valueTemp.substring(valueTemp.lastIndexOf("-") + 1);
if (Integer.parseInt(month) < 10 && month.length() < 2)
month = "0".concat(month);
if (Integer.parseInt(day) < 10 && day.length() < 2)
day = "0".concat(day);
return year.concat(month).concat(day).replace("-", "");
}
return value;
}
/**
* 解讀assets資料夾下的Config.txt檔案資訊
*
* @param activity
* @param tag
* 需要在該檔案裡面查詢的key
* @return 檔案中key對應的value
*/
public final static String getConfigStringFormAsset(Activity activity, String tag) {
if (configHm_ == null) {
initConfigStringFormAsset(activity);
}
String value = configHm_.get(tag);
return value == null ? "" : value;
}
/**
* 解讀assets資料夾下的Config.txt檔案資訊
*
* @param activity
* @param tag
* 需要在該檔案裡面查詢的key
* @return 檔案中key對應的value
*/
private final static void initConfigStringFormAsset(Activity activity) {
// 只讀取一次Config檔案
if (null == activity)
return;
configHm_ = new HashMap<String, String>();
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(activity.getAssets().open("Config.txt")), 1024);
String line;
String key;
String value;
while ((line = in.readLine()) != null) {
int index = line.indexOf(" ");
if (index != -1) {
key = line.substring(0, index);
value = line.substring(index).trim();// 去掉前面的空?
configHm_.put(key, value);
}
}
String str_lag = configHm_.get("jat_lag");
jat_lag = Integer.parseInt(str_lag);
} catch (Exception e) {
} finally {
if (in != null) {
try {
in.close();
in = null;
} catch (Exception e) {
// TODO Auto-generated catch block
printException(e);
}
}
}
}
public final static int getScaledValueX(float num) {
// TODO Auto-generated method stub
float numtemp = SCALEDATEX * num;
return (int) numtemp;
}
public final static int getFontSize(int size) {
size = (int) (size * SCALEDFONT);
return size;
}
public final static int getScaledValueY(float num) {
// TODO Auto-generated method stub
float numtemp = SCALEDATEY * num;
return (int) numtemp;
}
/**
*
* @param wRate
* 參照寬度
* @param hRate
*/
private final static void setScaledParams(float wRate, float hRate) {
// TODO Auto-generated method stub
SCALEDATEX = wRate;
SCALEDATEY = hRate;
}
// 計算介面寬高
public final static void calculateScreenSize(Activity activity) {
// 從Config配置文件中讀取服務端xml的基準解析度,該解析度應時刻與服務端定義的模板標準解析度一?
BenchmarkresolutionW_ = Integer.parseInt(getConfigStringFormAsset(activity, "BenchmarkresolutionW"));
BenchmarkresolutionH_ = Integer.parseInt(getConfigStringFormAsset(activity, "BenchmarkresolutionH"));
DisplayMetrics dm = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
Component.SCREENWIDTH = dm.widthPixels;
// 該值為暫定值無實際意義,該值會在BaseView的onWindowFocusChanged方法中從新計算得?
// Component.SCREENHEIGHT = dm.heightPixels;
final float w = BenchmarkresolutionW_;
final float h = BenchmarkresolutionH_;
float wRate = dm.widthPixels / w;
float hRate = dm.heightPixels / h;
setScaledParams(wRate, hRate);
setBrHeight();
setMarginAndGap();
SCALEDFONT = 1;
int dw = dm.widthPixels;
int dh = dm.heightPixels;
float ds = dm.scaledDensity;
if (dw <= 240 && dh <= 320) {
if (ds != 0.75f) {
SCALEDFONT = 0.75f / ds;
}
} else if (dw <= 320 && dh <= 500) {
if (ds != 1f) {
SCALEDFONT = 1f / ds;
}
} else if (dw <= 480 && dh <= 900) {
if (ds != 1.5f) {
SCALEDFONT = 1.5f / ds;
}
} else if (dw <= 600) {
if (ds != 2f) {
SCALEDFONT = 2f / ds;
}
}
}
private static void setMarginAndGap() {
// TODO Auto-generated method stub
String tempString = getConfigStringFormAsset(getActivity(), "verticalMarginOfB");
if (null == tempString || tempString.equals(""))
tempString = "0";
LPLayout.VMB = getScaledValueY(Integer.parseInt(tempString));
printOutToConsole("Config設定的body框架縱向邊距經過縮放後為:" + LPLayout.VMB);
tempString = getConfigStringFormAsset(getActivity(), "horizontalMarginOfB");
if (null == tempString || tempString.equals(""))
tempString = "0";
LPLayout.HMB = getScaledValueX(Integer.parseInt(tempString));
printOutToConsole("Config設定body框架水平邊距經過縮放後為:" + LPLayout.HMB);
tempString = getConfigStringFormAsset(getActivity(), "verticalGapOfB");
if (null == tempString || tempString.equals(""))
tempString = "0";
LPLayout.VGB = getScaledValueY(Integer.parseInt(tempString));
printOutToConsole("Config設定的body框架子元素縱向間距經過縮放後為:" + LPLayout.VGB);
tempString = getConfigStringFormAsset(getActivity(), "horizontalGapOfB");
if (null == tempString || tempString.equals(""))
tempString = "0";
LPLayout.HGB = getScaledValueX(Integer.parseInt(tempString));
printOutToConsole("Config設定的body框架子元素橫向間距經過縮放後為:" + LPLayout.HGB);
tempString = getConfigStringFormAsset(getActivity(), "verticalMarginOfF");
if (null == tempString || tempString.equals(""))
tempString = "0";
LPLayout.VMF = getScaledValueY(Integer.parseInt(tempString));
printOutToConsole("Config設定的form框架縱向邊距經過縮放後為:" + LPLayout.VMF);
tempString = getConfigStringFormAsset(getActivity(), "horizontalMarginOfF");
if (null == tempString || tempString.equals(""))
tempString = "0";
LPLayout.HMF = getScaledValueX(Integer.parseInt(tempString));
printOutToConsole("Config設定的form框架水平邊距經過縮放後為:" + LPLayout.HMF);
tempString = getConfigStringFormAsset(getActivity(), "verticalGapOfF");
if (null == tempString || tempString.equals(""))
tempString = "0";
LPLayout.VGF = getScaledValueY(Integer.parseInt(tempString));
printOutToConsole("Config設定的form框架子元素縱向間距經過縮放後為:" + LPLayout.VGF);
tempString = getConfigStringFormAsset(getActivity(), "horizontalGapOfF");
if (null == tempString || tempString.equals(""))
tempString = "0";
LPLayout.HGF = getScaledValueX(Integer.parseInt(tempString));
printOutToConsole("Config設定的form框架子元素橫向間距經過縮放後為:" + LPLayout.HGF);
tempString = getConfigStringFormAsset(getActivity(), "verticalMarginOfD");
if (null == tempString || tempString.equals(""))
tempString = "0";
LPLayout.VMD = getScaledValueY(Integer.parseInt(tempString));
printOutToConsole("Config設定的div框架縱向邊距經過縮放後為:" + LPLayout.VMD);
tempString = getConfigStringFormAsset(getActivity(), "horizontalMarginOfD");
if (null == tempString || tempString.equals(""))
tempString = "0";
LPLayout.HMD = getScaledValueX(Integer.parseInt(tempString));
printOutToConsole("Config設定的div框架水平邊距經過縮放後為:" + LPLayout.HMD);
tempString = getConfigStringFormAsset(getActivity(), "verticalGapOfD");
if (null == tempString || tempString.equals(""))
tempString = "0";
LPLayout.VGD = getScaledValueY(Integer.parseInt(tempString));
printOutToConsole("Config設定的div框架子元素縱向間距經過縮放後為:" + LPLayout.VGD);
tempString = getConfigStringFormAsset(getActivity(), "horizontalGapOfD");
if (null == tempString || tempString.equals(""))
tempString = "0";
LPLayout.HGD = getScaledValueX(Integer.parseInt(tempString));
printOutToConsole("Config設定的div框架子元素橫向間距經過縮放後為:" + LPLayout.HGD);
tempString = getConfigStringFormAsset(getActivity(), "verticalMarginOfT");
if (null == tempString || tempString.equals(""))
tempString = "0";
LPLayout.VMT = getScaledValueY(Integer.parseInt(tempString));
printOutToConsole("Config設定的td框架縱向邊距經過縮放後為:" + LPLayout.VMT);
tempString = getConfigStringFormAsset(getActivity(), "horizontalMarginOfT");
if (null == tempString || tempString.equals(""))
tempString = "0";
LPLayout.HMT = getScaledValueX(Integer.parseInt(tempString));
printOutToConsole("Config設定的td框架水平邊距經過縮放後為:" + LPLayout.HMT);
tempString = getConfigStringFormAsset(getActivity(), "verticalGapOfT");
if (null == tempString || tempString.equals(""))
tempString = "0";
LPLayout.VGT = getScaledValueY(Integer.parseInt(tempString));
printOutToConsole("Config設定的td框架子元素縱向間距經過縮放後為:" + LPLayout.VGT);
tempString = getConfigStringFormAsset(getActivity(), "horizontalGapOfT");
if (null == tempString || tempString.equals(""))
tempString = "0";
LPLayout.HGT = getScaledValueX(Integer.parseInt(tempString));
printOutToConsole("Config設定的td框架子元素橫向間距經過縮放後為:" + LPLayout.HGT);
}
public static void setBrHeight() {
// TODO Auto-generated method stub
String tempString = getConfigStringFormAsset(getActivity(), "brHeight");
if (null == tempString || tempString.equals(""))
tempString = "0";
BRHEIGHT = getScaledValueY(Integer.parseInt(tempString));
printOutToConsole("Config設定的br節點高度經過縮放後為:" + BRHEIGHT);
}
public static int getBrHeight() {
return BRHEIGHT;
}
/**
* 獲取手機的model型號
*
* @return
*/
public final static String getPhoneModel() {
String temp = android.os.Build.MODEL;
temp = temp.replace(" ", "").replace("-", "_").trim();
return temp;
}
public final static String getPhoneTarget() {
String temp = android.os.Build.DEVICE;
temp = temp.replace(" ", "").replace("-", "_").trim();
return temp;
}
public final static String getClientID() {
String temp = android.os.Build.ID;
temp = temp.replace(" ", "").replace("-", "_").trim();
return temp;
}
/**
* 獲取介面解析度並且組合成?
*
* @param activity
* @return
*/
public final static String getResolution(Activity activity) {
DisplayMetrics dm = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
String w = String.valueOf(dm.widthPixels);
String h = String.valueOf(dm.heightPixels);
return w.concat("*").concat(h);
}
public final static Typeface getTypeFace(String string) {
Typeface tface = null;
try {
if (string.equalsIgnoreCase("bold")) {
tface = Typeface.defaultFromStyle(Typeface.BOLD);
} else if (string.equalsIgnoreCase("normal")) {
tface = Typeface.defaultFromStyle(Typeface.NORMAL);
} else {
tface = null;
}
} catch (Exception e) {
tface = null;
}
return tface;
}
/**
* 設定字型是否粗體
* */
private final static boolean getFontType(String string) {
if (string.equalsIgnoreCase("bold")) {
return true;
} else {
return false;
}
}
/** * 圖片去色,返回灰度圖片 * @param bmpOriginal 傳入的圖?* @return 去色後的圖片 */
public final static Bitmap getGrayBitmap(Bitmap bmpOriginal) {
if (null == bmpOriginal)
return null;
int width, height;
height = bmpOriginal.getHeight();
width = bmpOriginal.getWidth();
Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bmpGrayscale);
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
paint.setColorFilter(f);
c.drawBitmap(bmpOriginal, 0, 0, paint);
return bmpGrayscale;
}
/**
* @param activity
* @param fileName
* @param data
*/
public final static void updateFile(Activity activity, String fileName, byte[] data) {
try {
FileOutputStream fos = activity.openFileOutput(fileName, Activity.MODE_PRIVATE);
fos.write(new byte[] {}); // clear file.
fos.write(data);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
Utils.printException(e);
} catch (IOException e) {
Utils.printException(e);
} catch (Exception e) {
Utils.printException(e);
}
}
/**
* @param activity
* @param fullPathName
* @return
*/
public final static byte[] readFile(Activity activity, String fullPathName) {
byte[] buffer = null;
FileInputStream fis = null;
try {
File file = new File(fullPathName);
if (file.exists()) {
fis = activity.openFileInput(fullPathName);
int len = fis.available();
buffer = new byte[len];
fis.read(buffer);
fis.close();
}
} catch (FileNotFoundException e) {
printException(e);
} catch (IOException e) {
printException(e);
} catch (Exception e) {
printException(e);
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
}
}
}
return buffer;
}
public final static String getVersionName(Activity activity) {
try {
PackageManager pm = activity.getPackageManager();
PackageInfo pi;
pi = pm.getPackageInfo(activity.getPackageName(), PackageManager.GET_ACTIVITIES);
return pi.versionName;
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
Utils.printException(e);
return "1.0";
}
}
/**
* User-Agent string we use in all of our HTTP transactions. XXX DO NOTE CHANGE THIS!!
*/
public final static String makeUserAgent(String version) {
StringBuffer buf = new StringBuffer("LightPole/");
buf.append(version);
buf.append("/");
buf.append("android1.5");
return buf.toString();
}
// Get a code from data.
private final static int getCode(byte data[], int tree[]) {
int node = tree[0];
while (node >= 0) {
if (bitIndex == 0)
bitByte = (data[gIndex++] & 0xFF);
node = (((bitByte & (1 << bitIndex)) == 0) ? tree[node >> 16] : tree[node & 0xFFFF]);
bitIndex = (bitIndex + 1) & 0x7;
}
return (node & 0xFFFF);
}
/**
* 判斷報文是否存在xml?如果沒有則手動加?
*
* @param xml
* @return
*/
public final static String addXmlHead(String xml) {
if (xml.indexOf("<?xml") == -1) {
xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>".concat(xml);
}
return xml;
}
// get num bits from data. the num should not bigger than 32.
private final static int getBits(byte[] data, int num) {
int result = 0;
int i = 0;
if (bitIndex != 0) {
i = 8 - bitIndex;
result = bitByte >> bitIndex;
}
while (i < num) {
bitByte = data[gIndex++] & 0xFF;
result |= (bitByte << i);
i += 8;
}
bitIndex = (bitIndex + num) & 0x7;// calculate (bitIndex + num)%8
result &= (0xffffffff >>> (32 - num));
return result;
}
// It's used to decompress gzip data. Re. rfc1951 and rfc 1952.
public final static byte[] gunzip(byte[] gzipData) throws IOException {
// Check if the data is gzip format and if it is used "deflate"
// compression method.
if (gzipData[0] != 31 || gzipData[1] != -117)
throw new IOException("壓縮資料格式錯誤!");
if (gzipData[2] != 8)
throw new IOException("壓縮資料方法錯誤!");
// Skip the gzip data header.
byte flg = gzipData[3];
gIndex = 10;
bitIndex = 0;
bitByte = 0;
if ((flg & 4) != 0)
gIndex += getBits(gzipData, 16);
if ((flg & 8) != 0)
while (gzipData[gIndex++] != 0)
;
if ((flg & 16) != 0)
while (gzipData[gIndex++] != 0)
;
if ((flg & 2) != 0)
gIndex += 2;
int temp = gIndex;
gIndex = gzipData.length - 4;
// The size of the original input data
int size = getBits(gzipData, 16) | (getBits(gzipData, 16) << 16);
byte[] unzipData = new byte[size];
gIndex = temp;
int unzipIndex = 0;
bitIndex = 0;
bitByte = 0;
int lastBlock = 0; // 0 indicates have more block when 1 indicates it is
// the last block.
int type = 0;// 0 indicates uncompress data, 1 indicates use final final static
// Huffman, 2 indicates use dynamic Huffman.
while (lastBlock == 0) {
lastBlock = getBits(gzipData, 1);
type = getBits(gzipData, 2);
if (type == 0) {
// uncompress data
bitIndex = 0;
int length = getBits(gzipData, 16);
gIndex += 2;
System.arraycopy(gzipData, gIndex, unzipData, unzipIndex, length);
gIndex += length;
unzipIndex += length;
} else {
byte[] lBits;
byte[] dBits;
if (type == 1) {
// use final final static huffman.
lBits = new byte[288];// The lTree node numbers 286, the
// last two nodes is use for full
// tree.
for (int i = 0; i < 288; i++) {
if (i < 144 || i > 279) {
lBits[i] = 8;
} else if (i < 256) {
lBits[i] = 9;
} else {
lBits[i] = 7;
}
}
dBits = new byte[32];// The dTree node numbers 30, the last
// two nodes is use for full tree.
for (int i = 0; i < dBits.length; i++) {
dBits[i] = 5;
}
} else if (type == 2) {
// use dynamic huffman.
int hlit = getBits(gzipData, 5) + 257;
int hdist = getBits(gzipData, 5) + 1;
int hclen = getBits(gzipData, 4) + 4;
byte[] bltreeBits = new byte[19];// The blTree node numbers
// 19.
for (int i = 0; i < hclen; i++)
bltreeBits[DYNAMIC_L_ORDER[i]] = (byte) getBits(gzipData, 3);
int[] blTree = huffmanTree(bltreeBits);
lBits = decompressCode(gzipData, blTree, hlit);
dBits = decompressCode(gzipData, blTree, hdist);
} else {
throw new IOException("不能正確解壓資料.");
}
int[] lTree = huffmanTree(lBits);// The literal/length tree.
int[] dTree = huffmanTree(dBits);// The distance tree.
int code = 0;
while ((code = getCode(gzipData, lTree)) != 256) {// code=256
// indicates
// the end
// of this
// block.
if (code < 256) {// literal byte
unzipData[unzipIndex++] = (byte) code;
} else {// length/distance pairs
code -= 257;
int length = EXTRA_L_VALUES[code];
if (EXTRA_L_BITS[code] > 0)
length += getBits(gzipData, EXTRA_L_BITS[code]);
code = getCode(gzipData, dTree);
int distance = EXTRA_D_VALUES[code];
if (EXTRA_D_BITS[code] > 0)
distance += getBits(gzipData, EXTRA_D_BITS[code]);
while (distance < length) {
System.arraycopy(unzipData, unzipIndex - distance, unzipData, unzipIndex, distance);
unzipIndex += distance;
length -= distance;
}
System.arraycopy(unzipData, unzipIndex - distance, unzipData, unzipIndex, length);
unzipIndex += length;
}
}
}
}
return unzipData;
}
// Get a huffman tree.
private final static int[] huffmanTree(byte bits[]) {
int bl_count[] = new int[MAX_BITS + 1];
for (int i = 0; i < bits.length; i++) {
bl_count[bits[i]]++;
}
int code = 0;
bl_count[0] = 0;
int next_code[] = new int[MAX_BITS + 1];
// Count the number of codes for each code length.
for (int i = 1; i <= MAX_BITS; i++) {
code = (code + bl_count[i - 1]) << 1;
next_code[i] = code;
}
int tree[] = new int[((bits.length - 1) << 1) + MAX_BITS];
int treeInsert = 1;
for (int i = 0; i < bits.length; i++) {
int len = bits[i];
if (len != 0) {
code = next_code[len]++;
int node = 0;
for (int bit = len - 1; bit >= 0; bit--) {
int value = code & (1 << bit);
if (value == 0) {
int left = tree[node] >> 16;
if (left == 0) {
tree[node] |= (treeInsert << 16);
node = treeInsert++;
} else
node = left;
} else {
int right = tree[node] & 0xFFFF;
if (right == 0) {
tree[node] |= treeInsert;
node = treeInsert++;
} else
node = right;
}
}
tree[node] = 0x80000000 | i;
}
}
return tree;
}
// Decompress the literal/length code and the distance code.
private final static byte[] decompressCode(byte data[], int blTree[], int count) {
int code = 0;
byte previousCode = 0;
int times = 0; // The number of the previous code's length need to
// repeat.
byte treeBits[] = new byte[count];
int index = 0;
while (index < count) {
code = getCode(data, blTree);
if (code == 16) {
times = getBits(data, 2) + 3;
} else if (code == 17) {
times = getBits(data, 3) + 3;
previousCode = 0;
} else if (code == 18) {
times = getBits(data, 7) + 11;
previousCode = 0;
} else {
times = 0;
previousCode = (byte) code;
treeBits[index++] = (byte) code;
}
for (int i = 0; i < times; i++) {
treeBits[index++] = previousCode;
}
}
return treeBits;
}
public final static String getVersion() {
// 獲取手機作業系統版本?
return android.os.Build.VERSION.RELEASE;
}
public final static String getModel() {
// 獲取手機型號
return android.os.Build.MODEL;
}
public final static String getName() {
// 獲取使用者姓???
return android.os.Build.USER;
}
public final static String getDeviceName() {
return android.os.Build.DEVICE;
}
public final static String getPlayform() {
// 當前系統平臺
return "Android";
}
public final static String getUUID() {
final TelephonyManager tm = (TelephonyManager) activity_.getBaseContext().getSystemService(
Context.TELEPHONY_SERVICE);
final String tmDevice, tmSerial, tmPhone, androidId;
tmDevice = "" + tm.getDeviceId();
tmSerial = "" + tm.getSimSerialNumber();
androidId = ""
+ android.provider.Settings.Secure.getString(activity_.getContentResolver(),
android.provider.Settings.Secure.ANDROID_ID);
UUID deviceUuid = new UUID(androidId.hashCode(), ((long) tmDevice.hashCode() << 32) | tmSerial.hashCode());
return deviceUuid.toString();
}
public final static String connectType(Activity bv) {
// TODO Auto-generated method stub
try {
Context context = bv.getApplicationContext();
ConnectivityManager connectivity = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = connectivity.getActiveNetworkInfo();
if ((null != ni) && ni.isAvailable()) {
return ni.getTypeName();
}
} catch (Exception e) {
Utils.printException(e);
return getConfigStringFormAsset(getActivity(), "httpError");
}
return getConfigStringFormAsset(getActivity(), "httpError");
}
private final static String getLocationByNet(Activity bv) {
// TODO Auto-generated method stub
double LATITUDE = 0;
double LONGITUDE = 0;
int timeoutConnection = 3000;
int timeoutSocket = 5000;
TelephonyManager mTelNet = (TelephonyManager) bv.getSystemService(Context.TELEPHONY_SERVICE);
String operator = mTelNet.getNetworkOperator();
CellLocation cl = mTelNet.getCellLocation();
// #ifdef Android2.2
if (cl instanceof CdmaCellLocation) {
CdmaCellLocation location = (CdmaCellLocation) cl;
LATITUDE = (double) location.getBaseStationLatitude() / 14400;// 14400?*90/1296000
LONGITUDE = (double) location.getBaseStationLongitude() / 14400;
} else if (null != operator && !operator.equals("")) {
// #else
// @ if (null != operator && !operator.equals("")) {
// #endif
String mcc = operator.substring(0, 3);
String mnc = operator.substring(3);
if (cl instanceof GsmCellLocation) {
GsmCellLocation location = (GsmCellLocation) cl;
if (null != location) {
int cid = location.getCid();
int lac = location.getLac();
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
HttpClient httpclient = new DefaultHttpClient(httpParameters);
HttpPost post = new HttpPost("http://www.google.com/loc/json");
try {
JSONObject holder = new JSONObject();
holder.put("version", "1.1.0");
holder.put("host", "maps.google.com");
holder.put("address_language", "zh_CN");
holder.put("request_address", true);
JSONObject tower = new JSONObject();
tower.put("mobile_country_code", mcc);
tower.put("mobile_network_code", mnc);
tower.put("cell_id", cid);
tower.put("location_area_code", lac);
JSONArray towerarray = new JSONArray();
towerarray.put(tower);
holder.put("cell_towers", towerarray);
StringEntity query = new StringEntity(holder.toString());
post.setEntity(query);
HttpResponse response = httpclient.execute(post);
HttpEntity entity = response.getEntity();
BufferedReader buffReader = new BufferedReader(new InputStreamReader(entity.getContent()));
StringBuffer strBuff = new StringBuffer();
String result = null;
while ((result = buffReader.readLine()) != null) {
strBuff.append(result);
}
JSONObject json = new JSONObject(strBuff.toString());
JSONObject subjosn = new JSONObject(json.getString("location"));
LATITUDE = Double.parseDouble(subjosn.getString("latitude"));
LONGITUDE = Double.parseDouble(subjosn.getString("longitude"));
} catch (Exception e) {
// LPUtils.printException(e);
Utils.printException(e);
}
}
}
}
return (String.valueOf(LATITUDE)).concat(",").concat(String.valueOf(LONGITUDE));
}
/**
* 檢視android手機是否被刷過機.linux系統下root許可權可以使用su命令,android本身也是小型的linux系統
*
* @param command
* "id" 或其他的 su命令
*/
public final static boolean runRootCommand(String command) {
Process process = null;
DataOutputStream os = null;
try {
process = Runtime.getRuntime().exec("su");
os = new DataOutputStream(process.getOutputStream());
os.writeBytes(command + "\n");
os.writeBytes("exit\n");
os.flush();
process.waitFor();
} catch (Exception e) {
printException(e);
return false;
} finally {
try {
if (os != null) {
os.close();
}
process.destroy();
} catch (Exception e) {
// nothing
}
}
return true;
}
/**
* * 儲存物件到文?* * @param obj * @param fileName * @throws Exception
*
* @param publicKey
*/
public static void saveFile(Activity activity, Object obj, String fileName) {
ObjectOutputStream output;
try {
output = new ObjectOutputStream(activity.openFileOutput(fileName, Context.MODE_PRIVATE));
output.writeObject(obj);
output.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
printException(e);
} catch (IOException e) {
// TODO Auto-generated catch block
printException(e);
}
}
/**
* 讀取Config的文字預設顏色設定,如果沒有,預設為黑色
*
* @param activity
*/
public static void readTextClolr(Activity activity) {
String colortemp = getConfigStringFormAsset(activity, "textColor");
Component.TEXTCOLOR = Color.BLACK;
if (null != colortemp && !colortemp.equals("")) {
if (colortemp.equalsIgnoreCase("black"))
Component.TEXTCOLOR = Color.BLACK;
else if (colortemp.equalsIgnoreCase("BLUE"))
Component.TEXTCOLOR = Color.BLUE;
else if (colortemp.equalsIgnoreCase("CYAN"))
Component.TEXTCOLOR = Color.CYAN;
else if (colortemp.equalsIgnoreCase("dkgray"))
Component.TEXTCOLOR = Color.DKGRAY;
else if (colortemp.equalsIgnoreCase("white"))
Component.TEXTCOLOR = Color.WHITE;
else if (colortemp.equalsIgnoreCase("gray"))
Component.TEXTCOLOR = Color.GRAY;
else if (colortemp.equalsIgnoreCase("green"))
Component.TEXTCOLOR = Color.GREEN;
else if (colortemp.equalsIgnoreCase("ltgray"))
Component.TEXTCOLOR = Color.LTGRAY;
else if (colortemp.equalsIgnoreCase("magenta"))
Component.TEXTCOLOR = Color.MAGENTA;
else if (colortemp.equalsIgnoreCase("red"))
Component.TEXTCOLOR = Color.RED;
else if (colortemp.equalsIgnoreCase("transparent"))
Component.TEXTCOLOR = Color.TRANSPARENT;
else if (colortemp.equalsIgnoreCase("yellow"))
Component.TEXTCOLOR = Color.YELLOW;
}
}
/** * 從檔案讀取object * * @param fileName * @return * @throws Exception */
public static Object readFromFile(Activity activity, String fileName) {
ObjectInputStream input;
try {
input = new ObjectInputStream(activity.openFileInput(fileName));
Object obj = input.readObject();
input.close();
return obj;
} catch (StreamCorruptedException e) {
// TODO Auto-generated catch block
printException(e);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
printException(e);
} catch (IOException e) {
// TODO Auto-generated catch block
printException(e);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
printException(e);
}
return null;
}
public static void saveFile(String name, byte[] buffer) {
if (null == name || name.equals(""))
return;
name = OffStoreDownload.FILEROOT.concat(name);
if (name.endsWith("/")) {
createPath(name);
} else {
createFile(name, buffer);
}
}
/**
* @param activity
* @param fullPathName
* @return
*/
public final static byte[] readFile(String fullPathName) {
byte[] buffer = null;
try {
File file = new File(fullPathName);
FileInputStream fis = new FileInputStream(file);
int len = fis.available();
buffer = new byte[len];
fis.read(buffer);
fis.close();
buffer = AESCipher.decrypt(buffer, AESCipher.customerKey_, AESCipher.customerIv_);
} catch (FileNotFoundException e) {
printException(e);
} catch (IOException e) {
printException(e);
} catch (Exception e) {
printException(e);
}
return buffer;
}
private static void createFile(String path, byte[] buffer) {
// TODO Auto-generated method stub
File file = null;
FileOutputStream fstream = null;
try {
file = new File(path);
if (!file.exists()) {
file.createNewFile();
fstream = new FileOutputStream(file);
buffer = AESCipher.encrypt(buffer, AESCipher.customerKey_, AESCipher.customerIv_);
fstream.write(buffer);
}
} catch (Exception e) {
printException(e);
} finally {
if (fstream != null) {
try {
fstream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
printException(e);
}
}
}
}
public static void createPath(String path) {
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
}
/**
* 初始化本地儲存的 key,iv
*
* @param activity
*/
public static void initCustomerSecretKey(Activity activity) {
try {
TelephonyManager tm = (TelephonyManager) activity.getSystemService(Activity.TELEPHONY_SERVICE);
String deviceId = tm.getDeviceId();
String deviceName = Build.DEVICE;
String packageName = activity.getPackageName();
if (deviceId == null) {
deviceId = "";
}
if (deviceName == null) {
deviceName = "";
}
if (packageName == null) {
packageName = "com.rytong.tools";
}
String message = deviceId.concat(deviceName).concat(packageName)
.concat(RSACipher.PUBLIC_CER_MODULUS_FILENAME).concat(HMac.KEY_MAC_MD5);
byte[] sha1 = HMac.SHA1(message.getBytes());
byte[] md5 = MD5.getMD5(message.getBytes());
byte[] secretKey = new byte[sha1.length + md5.length];
System.arraycopy(sha1, 0, secretKey, 0, sha1.length);
System.arraycopy(md5, 0, secretKey, sha1.length, md5.length);
AESCipher.customerKey_ = ClientHello.getAESKey(secretKey);
AESCipher.customerIv_ = new byte[16];
for (int i = 0; i < 16; i++) {
AESCipher.customerIv_[i] = secretKey[secretKey.length - 1 - i];
}
} catch (Exception e) {
printOutToConsole(e);
}
}
/**
* 清空介面所有控制元件
*/
public static void clearWidget() {
// TODO Auto-generated method stub
if (null != Component.VWIDGETARRAY && !Component.VWIDGETARRAY.isEmpty()) {
int size = Component.VWIDGETARRAY.size();
Component comp;
int index = Integer.MIN_VALUE;
for (int i = 0; i < size; i++) {
comp = (Component) Component.VWIDGETARRAY.get(i);
if (null != comp.getTag() && comp.getTag().equalsIgnoreCase("body"))
index = i;
}
if (index != Integer.MIN_VALUE) {
comp = (Component) Component.VWIDGETARRAY.get(index);
comp.releaseResource(comp);
}
}
}
}
相關文章
- jenkins離線外掛下載Jenkins
- 樹莓派搭建個人 NAS 下載機(實現離線下載功能)樹莓派
- VSCode安裝離線下載外掛VSCode
- 谷歌瀏覽器下載離線安裝包谷歌瀏覽器
- Mac視訊下載離線工具:Softorino YouTube ConverterMac
- 下載 Internet Explorer 11(離線安裝程式)
- Flutter下實現WebView攔截載入離線資源FlutterWebView
- 記一次離線下載nessus 外掛的方法
- rhel9.2離線下載安裝包,並安裝
- linux 開發離線環境下載及安裝Linux
- [譯]前端離線指南(下)前端
- android sdk離線升級方法Android
- Ubuntu下離線安裝PostgreSQLUbuntuSQL
- Mac 下使用 Aria2 實現迅雷離線和百度雲下載Mac
- Android Studio使用離線GradleAndroidGradle
- ReactNative打離線包-android篇ReactAndroid
- VNC連線軟體下載,VNC連線軟體下載!
- Android工具下載Android
- Cocos2d-X 2.2 離線 API Referen 下載 200多MAPI
- Android SDK4.0 離線安裝方法Android
- [Android]Android原始碼下載Android原始碼
- gitlab下載、離線安裝、備份還原測試(gitlab-ce)Gitlab
- 下載Android程式碼Android
- Android 原始碼下載Android原始碼
- android資源下載Android
- Android WebView 實現離線快取閱讀AndroidWebView快取
- Window離線環境下如何安裝pyhanlpHanLP
- 基於linux下unzip離線安裝Linux
- Windows 8 下離線安裝.NET Framework 3.5WindowsFramework
- Chrome瀏覽器官方離線安裝包下載Chrome瀏覽器
- Google Chrome (32/64) 離線安裝包下載地址GoChrome
- 利用抓包工具從Windows 10 應用商店裡下載各種離線應用Windows
- 百度搜尋:藍易雲【centos 7.9離線下載安裝vscode,以及外掛安裝下載教程。】CentOSVSCode
- 為什麼多 TCP 連線分塊下載比單連線下載快TCP
- 堅果雲for Android支援離線預覽office嗎?Android
- 純小白uni-app+Android Studio離線打包APPAndroid
- Android 視訊教程下載Android
- [Android]CTS -google下載地址AndroidGo