編輯:關於Android編程
BroadcastReceiver除了接收用戶所發送的廣播消息之外,還有一個重要的用途:接收系統廣播。如果應用需要在系統特定時刻執行某些操作,就可以通過監聽系統廣播來實現。Android的大量系統事件都會對外發送標准廣播。以下是Android常見的廣播Action常量(詳請參考Android API文檔中關於Intent的說明)。
Action常量
說明
ACTION_TIME_CHANGED
系統時間被改變。
ACTION_DATE_CHANGED
系統日期被改變。
ACTION_TIMEZONE_CHANGED
系統時區被改變。
ACTION_BOOT_COMPLETED
系統啟動完成。
ACTION_PACKAGE_ADDED
新的應用程序被安裝。
ACTION_PACKAGE_CHANGED
應用程序被改變。
ACTION_PACKAGE_REMOVED
應用程序被卸載。
ACTION_PACKAGE_RESTARTED
應用程序被重新啟動。
ACTION_PACKAGE_DATA_CLEARED
應用程序數據被清理。
ACTION_BATTERY_CHANGED
電池電量改變。
ACTION_SHUTDOWN
系統被關閉。
ACTION_BATTRY_LOW
電池電量低。
ACTION_POWER_CONNECTED
外接電源被連通。
ACTION_POWER_DISCONNECTED
外接電源被斷開。
ACTION_SHUTDOWN
系統關閉。
ACTION_NEW_OUTGOING_CALL
播出電話。
ACTION _PHONE_STATE
系統通話狀態改變。
通過 來監聽特殊的廣播,即可以實現應用跟隨系統執行特定的某些操作。
在實際應用總往往會讓一些應用跟隨系統啟動,比如一個黑名單來電自動攔截的APP,監聽垃圾短信的APP... ...等等。為了讓Service能跟隨系統啟動,我們需要讓BroadcastReceiver監聽Action名為:ACTION_BOOT_COMPLETED常量的Intent,然後在BroadcastReceiver啟動特定的Service即可。
程序清單:
public class LaunchWithSys extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub Intent launchService=new Intent(context, LaunchService.class); //啟動指定Service context.startActivity(launchService); } }
實例二:短息提醒
在Android中當系統收到短信後會發出一個有序的廣播,該廣播的Intent的Action為android.provider.Telephony.SMS_RECEIVED。因此只需要在程序中開發一個對應的BroadcastReceiver即可監聽到系統接收到的短信。
程序清單:
public class SmsReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub //如果收到短信 if (intent.getAction().equals(“android.provider.Telephony.SMS_RECEIVED”)) { //取消這條有序廣播(取消後會讓其它應用收不到短信) abortBroadcast(); Bundle bundle=intent.getExtras(); if (bundle!=null) {//如果數據不為空 //獲得收到的短信數據 Object[] objArray=(Object[]) bundle.get(“pdus”); //根據objArray的大小創建一個SmsMessage數組,用於封裝短信內容 SmsMessage []smsMessage=new SmsMessage[objArray.length]; StringBuffer sb=new StringBuffer(); sb.append(“時間:”+new DateFormat().format(“yyyy-MM-dd hh.mm.ss”, new Date())); //遍歷smsMessage數組取出所有短信 for (int i = 0; i < smsMessage.length; i++) { //將每條字節類型的短信數據轉換成SmsMessage對象 smsMessage[i]=SmsMessage.createFromPdu((byte[])objArray[i]); //獲取短信發送地址 sb.append(“發送者:”+smsMessage[i].getOriginatingAddress()); //獲取短信內容 sb.append(“短信內容:”+smsMessage[i].getDisplayMessageBody()+”\n”); } Toast.makeText(context, sb.toString(), Toast.LENGTH_LONG).show(); } } } }
實例分析: 由於接收到的短信內容是以字節數組形式保存的,為了便於用這些數據,需要使用SmsMessage.createFromPdu方法將這些字節數組形式的數據轉換成SmsMessage對象。
由於接收器可能收到多條短信,因此,通過“pdus”返回了一個短信數組(byte[])所以需要遍歷這個數組取出每一條短信。
由於需要監測系統發出的接收短信的廣播,所以在配置文件中需要進行如下配置:
另外,由於程序需要接收短信,所以需要賦予程序接收短信的權限。
運行效果圖:
實例三:手機電量提醒
當手機電量發生變化是系統會發出,Intent的Action名為ACTION_BATTERY_CHANGED的廣播,當手機電量過低時系統會發出Intent的Action名為ACTION_BATTRY_LOW的廣播。所以,只需監測對應Intent的BroadcastReceiver便可實現手機低電量提醒的應用。
程序清單:
public class MianActivity extends Activity { TextView show; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.mian); show=(TextView)findViewById(R.id.show); ShowPowerReceiver showPowerReceiver=new ShowPowerReceiver(); IntentFilter filter=new IntentFilter(); filter.addAction(Intent.ACTION_BATTERY_CHANGED); //注冊showPowerReceiver registerReceiver(showPowerReceiver, filter); } /** * Describe: * 手機電量提醒 * */ class ShowPowerReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub //判斷接收到的是否為電量變化的BroadCast Action if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) { //當前電量 int level=intent.getIntExtra("level", 0); //總電量 int scale=intent.getIntExtra("scale", 100); int current=level*100/scale; show.setText("當前電量:"+current+"%"); } } } }程序運行效果圖:
實例四:來去電提醒
當通話狀態改變時候系統會發出,Intent的Action名為ACTION _PHONE_STAT的廣播,當手機播出電話時系統會發出Intent的Action名為ACTION_NEW_OUTGOING_CALL的廣播。所以,只需監測對應Intent的BroadcastReceiver便可實現來去電提醒的應用。
程序清單:
來電提醒 public class InCallReceiver extends BroadcastReceiver { private static Object obj; /** * 創建一個永不關閉的Toast * @param context Context context上下文 * @param msg String msg 消息提示信息 * */ public static void showToast(Context context, String msg) { //創建一個Toast對象 Toast toast = Toast.makeText(context, msg, Toast.LENGTH_SHORT); //設置Toast的顯示位置 toast.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 0); try { //從toast對象中獲取mTN對象 Field field = toast.getClass().getDeclaredField("mTN"); field.setAccessible(true); obj = field.get(toast); //從TN對象中獲得show方法 Method method = obj.getClass().getDeclaredMethod("show", null); //調用TN對象的show方法來顯示Toast信息提示框 method.invoke(obj, null); } catch (Exception e) { } } /** * 關閉Toast * */ public static void closeToast() { if (obj != null) { try { Method method = obj.getClass().getDeclaredMethod("hide", null); method.invoke(obj, null); } catch (Exception e) { } } } @Override public void onReceive(final Context context, final Intent intent) { //獲取電話管理服務 TelephonyManager tm = (TelephonyManager) context .getSystemService(Service.TELEPHONY_SERVICE); switch (tm.getCallState()) { case TelephonyManager.CALL_STATE_RINGING://響鈴 String incomingNumber = intent .getStringExtra("incoming_number"); showToast(context, incomingNumber); break; case TelephonyManager.CALL_STATE_OFFHOOK://接聽電話 Log.d("call_state", "offhook"); break; case TelephonyManager.CALL_STATE_IDLE://掛斷電話 closeToast(); } } } //去電提醒 public class OutCallReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //獲取去電的電話號碼 String outcomingNumber = intent .getStringExtra(Intent.EXTRA_PHONE_NUMBER); InCallReceiver.showToast(context, outcomingNumber); } }配置文件:AndroidManifest.xml
程序運行效果圖:
最後:由於在接收廣播的時候,系統會為每一次接收廣播單獨創建一個廣播接收器,即使是同一個廣播的多次接收。因此,當電話處於不同的通話狀態時,實際上是在不同的接收器對象中發生的,所以需要使用靜態變量來保存Toast對象,不然closeTost我無法獲取在上一個狀態創建的Toast對象,也就無法關閉Toast信息框了。
年末較閒,就上個星期查找各方面的資料關於android截圖事情,自已也測試一些代碼,已改改進或者優化。接下來進行總結一下。其實,如果真正android系統截屏是需要roo
一、VC與模板概念的理解MVC本來是存在於Desktop程序中的,M是指數據模型,V是指用戶界面,C則是控制器。使用MVC的目的是將M和V的實現代碼分離,從而使同一個程序
上一篇,我們基本知道了EventBus的使用步驟,接下來先簡單研究一下其中的源碼。在分析源碼之前,我們先回顧一下Java反射的知識點:JAVA反射機制基本定義:JAVA反
前言在Android View 事件分發機制源碼詳解(ViewGroup篇)一文中,主要對ViewGroup#dispatchTouchEvent的源碼做了相應的解析,其