工具類(餓狼巨獻)
1、Android攔截短信
一、AndroidManifest.xml <uses-permission android:name="android.permission.RECEIVE_SMS"/> <receiver android:name=".SMSReceiver"> <intent-filter android:priority="1000"> <action android:name="android.provider.Telephony.SMS_RECEIVED"></action> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </receiver> 二 、廣播類 package com.rekoo.blocksms; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.telephony.SmsMessage; import android.widget.Toast; public class SMSReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { System.out.println("SMSReceiver, isOrderedBroadcast()=" + isOrderedBroadcast()); Bundle bundle = intent.getExtras(); Object messages[] = (Object[]) bundle.get("pdus"); SmsMessage smsMessage[] = new SmsMessage[messages.length]; for (int n = 0; n < messages.length; n++) { smsMessage[n] = SmsMessage.createFromPdu((byte[]) messages[n]); //如果短信內容包含“123”,則攔截短信。用戶收不到短信了。 if(smsMessage[n].getMessageBody().contains("123")){ //退出廣播 // this.abortBroadcast(); System.out.println("====222===打印==="); } Toast.makeText(context, "我是11111111", 1).show(); System.out.println("發件人:"+smsMessage[n].getOriginatingAddress()+" 短信內容:"+smsMessage[n].getMessageBody()+" "+smsMessage[n].getIndexOnIcc()); } } }
2、手機是否聯網?
<!-- 檢測網絡狀態 權限--> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> package com.rekoo.sms; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; public class NetHelper { /** * 是否聯網網絡 * */ public static boolean IsHaveInternet(final Context context) { try { ConnectivityManager manger = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo info = manger.getActiveNetworkInfo(); return (info!=null && info.isConnected()); } catch (Exception e) { return false; } } }
3、Application的使用
一、Application類簡介(相當於“全局變量”) * Base class for those who need to maintain global application state. You can * provide your own implementation by specifying its name in your * AndroidManifest.xml's <application> tag, which will cause that class * to be instantiated for you when the process for your application/package is * created. 這段話這么翻譯或許會通順些:application類是一個基類,這個基類的作用是為了獲取整個應用程序的狀態。你可以自己繼承或實現這個類,當你要使用自己拓展的application類的時候,只要在manifest.xml中的<application>標簽中name應用自己定義的類就行了,這樣做的結果是:當你的應用程序或者包所在的進程創建的時候,這個類就會被實例化。 就是說application是用來保存全局變量的,並且是在package創建的時候就跟着存在了。所以當我們需要創建全局變量的時候,不需 要再像j2se那樣需要創建public權限的static變量,而直接在application中去實現。只需要調用Context的getApplicationContext或者Activity的getApplication方法來獲得一個application對象,再做出相應 的處理。 二、具體用法 配置文件: <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" //加入自定義的Application類 android:name="com.rekoo.quicktransfer.Applications" > public class Applications extends Application{ List<AppPackageInfo> appInfos; public List<AppPackageInfo> getAppInfos() { return appInfos; } public void setAppInfos(List<AppPackageInfo> appInfos) { this.appInfos = appInfos; } } ** 利用Context對象,獲取到application對象 1、存取到 appInfos ((Applications)WelcomePageActivity.this.getApplication()).setAppInfos(mlistAppInfo); 2、取 appInfos 的值 ((Applications)LogicActivity.this.getApplication()).getAppInfos();
4、http請求
private static String baseUrl = "http://59.108.111.76:10001/?"; private static HttpResponse httpResponse; private static HttpEntity httpEntity; private static InputStream inputStream; public static void sendToCode(String authorCode){ String url = baseUrl+"acode="+authorCode; System.out.println("url="+url); try { int jsonObject_rc = -1; //生成一個請求對象 HttpGet httpPost=new HttpGet(url); //生成一個http客戶端對象 HttpClient httpClient=new DefaultHttpClient(); httpResponse=httpClient.execute(httpPost); System.out.println("codeStatus:"+httpResponse.getStatusLine().getStatusCode()); /**請求發送成功,並得到響應**/ if(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK){ httpEntity=httpResponse.getEntity(); inputStream=httpEntity.getContent(); BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream)); String result=""; String line=""; while((line=bufferedReader.readLine()) != null){ result=result+line; } System.out.println("result="+result); /* //======解析 Json數據 jsonObject_rc = new JSONObject(result.toString()).getInt("rc"); if (jsonObject_rc == 0) { JSONObject jsonObject_data = new JSONObject(result.toString()).getJSONObject("data"); //獲取子項... // int type = jsonObject_data.getInt("type"); int ptype = jsonObject_data.getJSONObject("type").getInt("ptype"); int pnum = jsonObject_data.getJSONObject("type").getInt("pnum"); System.out.println("====type:num==="+ptype+","+pnum); int num = jsonObject_data.getInt("num"); System.out.println("====獎勵次數:"+num); }*/ }else { //連接失敗... } } catch (Exception e) { e.printStackTrace(); } }
5、int 和 byte[]互轉
/** * int類型轉byte[]類型 */ public static byte[] int2ByteArray(int i) { byte[] result = new byte[4]; result[0] = (byte)((i >> 24) & 0xFF); result[1] = (byte)((i >> 16) & 0xFF); result[2] = (byte)((i >> 8) & 0xFF); result[3] = (byte)(i & 0xFF); return result; } /** * 將4字節的byte數組轉成int值 */ public static int byteArray2int(byte[] b){ byte[] a = new byte[4]; int i = a.length - 1,j = b.length - 1; for (; i >= 0 ; i--,j--) {//從b的尾部(即int值的低位)開始copy數據 if(j >= 0) a[i] = b[j]; else a[i] = 0;//如果b.length不足4,則將高位補0 } int v0 = (a[0] & 0xff) << 24;//&0xff將byte值無差異轉成int,避免Java自動類型提升后,會保留高位的符號位 int v1 = (a[1] & 0xff) << 16; int v2 = (a[2] & 0xff) << 8; int v3 = (a[3] & 0xff) ; return v0 + v1 + v2 + v3; }
6、int和String互轉
1》String.valueOf(i) 2》 Integer.toString(i) 3》 i+""
7、int轉為像素值
private int getPixels(int dpValue) { Resources r = activity.getResources(); int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue, r.getDisplayMetrics()); return px; }
8、Java多線程編程環境中單例模式的實現
【常用的單例模式】 class RekooSDk{ private static RekooSDk instance; private RekooSDk(){ } public static Singleton getInstance(){ if (instance == null) synchronized(instance){ if(instance == null) instance = new RekooSDk(); } return instance; } } 讓我們來看一下這個代碼是如何工作的:首先當一個線程發出請求后,會先檢查instance是否為null,如果不是則直接返回其內容,這樣避免了進入synchronized塊所需要花費的資源。其次,即使第2節提到的情況發生了,兩個線程同時進入了第一個if判斷,那么他們也必須按照順序執行synchronized塊中的代碼,第一個進入代碼塊的線程會創建一個新的Singleton實例,而后續的線程則因為無法通過if判斷,而不會創建多余的實例。 上述描述似乎已經解決了我們面臨的所有問題,但實際上,從JVM的角度講,這些代碼仍然可能發生錯誤。 對於JVM而言,它執行的是一個個Java指令。在Java指令中創建對象和賦值操作是分開進行的,也就是說instance = new Singleton();語句是分兩步執行的。但是JVM並不保證這兩個操作的先后順序,也就是說有可能JVM會為新的Singleton實例分配空間,然后直接賦值給instance成員,然后再去初始化這個Singleton實例。這樣就使出錯成為了可能,我們仍然以A、B兩個線程為例: 1. A、B線程同時進入了第一個if判斷 2. A首先進入synchronized塊,由於instance為null,所以它執行instance = new Singleton(); 3. 由於JVM內部的優化機制,JVM先畫出了一些分配給Singleton實例的空白內存,並賦值給instance成員(注意此時JVM沒有開始初始化這個實例),然后A離開了synchronized塊。 4. B進入synchronized塊,由於instance此時不是null,因此它馬上離開了synchronized塊並將結果返回給調用該方法的程序。 5. 此時B線程打算使用Singleton實例,卻發現它沒有被初始化,於是錯誤發生了。 4 通過內部類實現多線程環境中的單例模式 為了實現慢加載,並且不希望每次調用getInstance時都必須互斥執行,最好並且最方便的解決辦法如下: Java代碼 public class Singleton{ private Singleton(){ … } private static class SingletonContainer{ private static Singleton instance = new Singleton(); } public static Singleton getInstance(){ return SingletonContainer.instance; } } JVM內部的機制能夠保證當一個類被加載的時候,這個類的加載過程是線程互斥的。這樣當我們第一次調用getInstance的時候,JVM能夠幫我們保證instance只被創建一次,並且會保證把賦值給instance的內存初始化完畢,這樣我們就不用擔心3.2中的問題。此外該方法也只會在第一次調用的時候使用互斥機制,這樣就解決了3.1中的低效問題。最后instance是在第一次加載SingletonContainer類時被創建的,而SingletonContainer類則在調用getInstance方法的時候才會被加載,因此也實現了惰性加載。
9、long轉String
Long.toString(long);
10、MD5加密
import java.security.MessageDigest; public class Md5 { /** * MD5加密 * 約定字符串:"zhaonimei!@#AMN" */ public static void main(String[] args) { String str = "713F813742FA7FAE7A10505CDDA4321" + "zhaonimei!@#AMN"; String test = MD5(str); System.out.println("加密后:"+test); } //加密 public static String MD5(String inStr) { MessageDigest md5 = null; try { md5 = MessageDigest.getInstance("MD5"); } catch (Exception e) { System.out.println(e.toString()); e.printStackTrace(); return ""; } char[] charArray = inStr.toCharArray(); byte[] byteArray = new byte[charArray.length]; for (int i = 0; i < charArray.length; i++) byteArray[i] = (byte) charArray[i]; byte[] md5Bytes = md5.digest(byteArray); StringBuffer hexValue = new StringBuffer(); for (int i = 0; i < md5Bytes.length; i++) { int val = ((int) md5Bytes[i]) & 0xff; if (val < 16) hexValue.append("0"); hexValue.append(Integer.toHexString(val)); } return hexValue.toString(); } }
11、Random隨機數公式
產生Min-Max之間的數字
實現原理:
Math.round(Math.random()*(Max-Min)+Min);
12、String 轉 int
int key = Integer.parseInt(string);
13、Android發短信
權限: <!-- 短信相關的權限 --> <uses-permission android:name="android.permission.SEND_SMS"/> <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission> <uses-permission android:name="android.permission.READ_SMS"></uses-permission> /** * 發送短信 * destinationAddress:收信人的手機號碼 * scAddress:發信人的使命召喚2中文版使命召喚之聯合進攻已經打上了免CD補丁手機號碼 * text:發送信息的內容 * sentIntent:發送是否成功的回執,用於監聽短信是否發送成功 * DeliveryIntent:接收是否成功的回執,用於監聽短信對方是否接收成功 */ public static void sendSMS(Context context){ //發送內容 String smstext = "短信內容"; //測試... System.out.println("smstext="+smstext); Intent sentIntent = new Intent("SENT_SMS_ACTION"); PendingIntent sentPI = PendingIntent.getBroadcast(context, 0, sentIntent,0); Intent deliverIntent = new Intent("DELIVERED_SMS_ACTION"); PendingIntent deliverPI = PendingIntent.getBroadcast(context, 0,deliverIntent, 0); SmsManager smsManager = SmsManager.getDefault(); smsManager.sendTextMessage(Constant.connectNum, null, smstext, sentPI, deliverPI); }
14、獲取手機mac地址
/** * 獲取mac地址 * */ public static String getLocalMacAddress(Context context) { WifiManager wifi = (WifiManager)context.getSystemService(Context.WIFI_SERVICE); WifiInfo info = wifi.getConnectionInfo(); return info.getMacAddress(); }
15、獲取meta-data的值
應用Sence: <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <meta-data android:value="40080001" android:name="DIANXIN_CHANNEL"/> . . . </application> 方法: /** * 獲取到 meta-data的數據 * */ private static String getMetaData(Context context){ ApplicationInfo appInfo; try { appInfo = context.getPackageManager() .getApplicationInfo(context.getPackageName(),PackageManager.GET_META_DATA); int msg=appInfo.metaData.getInt("DIANXIN_CHANNEL"); System.out.println("msg="+msg); return String.valueOf(msg); } catch (NameNotFoundException e) { e.printStackTrace(); } return "未找到"; }
16、時間戳
System.currentTimeMillis();
17、解析Json數據
格式:{"rc":0,"data":{"openid":x,"token":x},"code":{"type":{"num":5}}} //rc節點 int rc = new JSONObject(result.toString()).getInt("rc"); //data節點 JSONObject jsonObject_data = new JSONObject(result.toString()).getJSONObject("data"); //openid節點 String openid = jsonObject_data.getInt("openid"); //num節點 JSONObject jsonObject_data = new JSONObject(result.toString()).getJSONObject("code"); int num =jsonObject_data.getJSONObject("type").getInt("num");
18、消息隊列+Asynctask+Callback
一、Socket使用 1、Socket客戶端,發送請求,啟用子線程執行(使用BlockingQueue阻塞消息隊列控制) //1、定義消息隊列 public static BlockingQueue<Integer> QUEUE = new LinkedBlockingQueue<Integer>(); //2、放入消息隊列值 Constants.QUEUE.put(num); public class SendSockets extends Thread{ @Override public void run(){ while(true){ //3、阻塞消息隊列(如果QUEUE不為空,取出執行之后操作) int num = Constants.QUEUE.take(); } } } 2、Socket服務端,用Asynctask實現多線程接受(doInBackground子線程,onProgressUpdate主線程更新UI) public class ReceiveSocket extends AsyncTask<String, String, Boolean>{ //運行於子線程中 @Override protected Boolean doInBackground(String... params){ while(true){ //...Socket接受返回來的消息 args_in:為獲取到的消息內容 //1、發送消息到主線程 publishProgress(args_in); } } //運行於主線程,用於更新主線程數據(UI) @Override protected void onProgressUpdate(String... values) { //2、...操作,更新主線程 super.onProgressUpdate(values); //回調callback isSuccess(args_in, callback); } } * 關於Asynctask的詳解 1、onPreExecute() 高負載代碼執行之前調用 ,通常用來顯示一個進度條,在主線程中執行 2、doInBackGround() onPreExecute() 執行完后調用,此方法通常就是放高負載代碼的,比如遠程請求,巨大數據載入等,你不用新建線程來包裝此方法 AsyncTask(或子類)會自動在新線程中調用此方法 3、onPostExecute(Result) 在doInBackground完成之后調用,一般是設置結果,取消第一個方法顯示的進度條。 4、onProgressUpdate() 一般用來更新第一個方法顯示的進度條,什么下載了50% 51% 。。。 二、Callback回調 1、新建接口 public interface Callback{ void success(String success); void fail(String fail); } 2、作為參數,傳進執行回調的方法內 //匿名類 ShareToQQ.Share(new Callback(){ @Override public void success(String success) { super.success(success); //success為回調回來的內容 System.out.println("回調的數據:"+success); } @Override public void fail(String fail) { super.fail(fail); } }); 4、Share方法的實現 public void Share(Callback callback){ callback.success("成功..."); }
19、頁數公式
頁數 = (總數+PAGE_SIZE-1)/PAGE_SIZE
20、用keystore給apk簽名
用jdk自帶工具jarsigner.exe 命令行到 C:\Program Files\Java\jdk1.6.0_24\bin>jarsigner.exe -verbose -keystore d:\aa\debug.kestore -storepass android -signedjar d:\aa\gblnn_signed.apk d:\aa\gblnn.apk androiddebugkey 規范: >jarsigner.exe -verbose -keystore keystore文件路徑 -storepass 密碼 -signedjar 要生成的新apk路徑 待簽名的apk路徑 alias名稱(為希望使用的簽名證書中的alias名稱)