成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

OPhone系統之電話功能詳解

移動開發
OPhone作為一個嵌入式操作系統,目前主要運行在有電話功能的手持設備上,因此最基本的電話功能——如:撥打、接聽電話,接收、發送短信,就成為它最重要的核心功能了。

概述

支持OPhone系統完成基本電話功能的底層硬件基礎是:無線通訊模塊(例如:GSM/GPRSmodem),而在其之上的抽象——無線接口層(RIL:RadioInterfaceLayer)是本文討論的相關API的靈魂,它完成了對基本電話功能與Radio硬件之間的抽象,負責提供數據的可靠傳輸、AT命令發送,以及命令回應(response)的解析等工作。它是通訊網絡無關的,共包含兩個基本部件:RIL守護進程(RILDaemon)和RIL廠商專用實現(VendorRIL)。前者負責初始化VendorRIL實例,并管理來自應用層API的調用——將其轉化為“主動請求命令”分派給VendorRIL實現;而后者是具體無線通訊網絡的專用實現,掌管并驅動著無線網絡硬件模塊的通訊工作,并把“被動請求命令”上報給RIL守護進程,從而達成網絡通訊。

本文將從撥打電話、接聽電話、發送短消息等多個基本功能出發,向大家介紹相關API的具體使用方法。

電話功能

OPhone系統本身有內置的電話應用(Phone.apk)提供撥打和接聽電話的能力,它提供了虛擬數字鍵盤幫助用戶撥號并發起呼叫。當有來電呼入時,它會振鈴提示并顯示來電信息提示界面,用戶通過提示界面上的功能按鈕,接聽或者拒絕來電。但對于開發者而言,我們真正關心的是如何通過API調用這些基本的電話功能?

首先,讓我們一起來看與撥打電話相關的功能吧。撥打電話是用戶自主發起的動作,所以是“主動請求命令”,它首先在JavaAPI層通過Socket與RIL守護進程建立連接并發送請求命令,然后命令被轉發至VendorRIL實現,并且最終建立通話呼叫的網絡鏈接。這是底層的原理和流程,如何通過API實現呢?#t#

還得先從OPhone系統中的Intent(意圖)說起,“意圖”被用來描述和表達某個要求或者目地,針對撥打電話的意圖,有兩個與之相關的Intent常量可以使用:Intent.ACTION_CALL和Intent.ACTION_DIAL,區別在于前者會導航到數字撥號鍵盤,后者直接進行呼叫,具體請看示例代碼:

  1. //取得目標號碼     
  2. String number = editText.getText().toString();     
  3. Uri data = Uri.parse("tel:" + number);     
  4. //調用撥打電話功能     
  5. if (v.getId() == R.id.btn_dial) {     
  6.    //進入撥號界面     
  7.    Intent intent = new Intent(Intent.ACTION_DIAL, data);     
  8.    intent.addCategory(Intent.CATEGORY_DEFAULT);     
  9.    startActivity(intent);     
  10. } else if (v.getId() == R.id.btn_call) {     
  11.    //直接進行呼叫     
  12.    Intent intent = new Intent(Intent.ACTION_CALL, data);     
  13.    intent.addCategory(Intent.CATEGORY_DEFAULT);     
  14.    startActivity(intent);     
  15. }    

代碼非常簡單,關鍵是使用Intent.ACTION_DIAL或Intent.ACTION_CALL做為Intent的action名稱,并把Uri類型的data數據作為目標電話號碼附加到Intent中。

除直接撥打電話之外,還有一種需求特別常見——即捕獲撥打電話的動作并獲取目標電話號碼,以便做出進一步的具體處理。要實現該需求還得先了解一下背后的故事:在OPhone系統中有一種被稱為廣播接收器(BroadcastReceiver)的應用程序類型,它會選擇接收某個“頻道”上的廣播數據并做出相應處理,廣播數據的產生源頭可以是系統中的任何應用程序。對“撥打電話”而言,廣播數據在Intent.ACTION_NEW_OUTGOING_CALL頻道上,所以要監聽該動作,就需要編寫廣播接收器,并將其指向以上的特定頻道。

請看示例代碼:

  1. public class OutgoingCallReceiver extends BroadcastReceiver {     
  2.         // logger name     
  3.         private static final String tag = "OutgoingCallReceiver";     
  4.         @Override    
  5.         public void onReceive(Context context, Intent intent) {     
  6.             // 監聽到撥打電話動作,并獲取目標電話號碼     
  7.            String name = Intent.EXTRA_PHONE_NUMBER;     
  8.            String phoneNumber = intent.getStringExtra(name);     
  9.             Log.d(tag, "Outgoing call -> " + phoneNumber);     
  10.            // TODO:you code....     
  11.         }     
  12.     }    

然后,再將以上廣播接收器申明在AndroidManifest.xml文件中:

  1. <receiver android:name="OutgoingCallReceiver">     
  2.     <intent-filter>     
  3.      <action android:name=  
  4. "android.intent.action.NEW_OUTGOING_CALL"/>     
  5.       <category android:name="android.intent.category.DEFAULT"/>     
  6.    </intent-filter>     
  7. </receiver>    

其中action.name指向的正是常量Intent.ACTION_NEW_OUTGOING_CALL的字符串字面值。當再次撥號時,無論使用上文介紹的API或通過內置的電話應用程序,該接收器都會自動捕捉到并且獲取目標電話號碼。
再進一步考慮,假設需要將某特定號碼屏蔽掉——禁止用戶撥打該號碼,要怎么才能做到呢?其實,只需要在廣播接收器的實現代碼中,有選擇的終止廣播數據傳播即可。請看示例代碼:

  1. //禁止向[139999999]號碼撥打電話     
  2.    String target = "139999999";     
  3.    if (phoneNumber.equalsIgnoreCase(target)) {     
  4.       // 終止廣播數據的傳播     
  5.       abortBroadcast();     
  6.       // 顯示提示信息     
  7.       String msg = "號碼[" + target + "]被禁止~!";     
  8.       Toast.makeText(context, msg, Toast.LENGTH_LONG).show();     
  9.    }    

需要注意的是,并不是所有廣播都可以終止,只有有序廣播(Orderedbroadcasts)才能夠被終止。什么是有序廣播呢?#p#

讓我們來回顧一下關于BroadcastReceiver的基礎知識:廣播被分為兩種不同的類型:“普通廣播(Normalbroadcasts)”和“有序廣播(Orderedbroadcasts)”。前者是完全異步的,所有接收器(邏輯上)都在同一時刻運行,對消息傳遞的效率而言這是很好的做法,但缺點是:接收器不能返回結果并且無法終止廣播數據的傳播;然而后者是逐個的執行接收器——系統會按照接收器申明的優先級別(申明在intent-filter元素的android:priority屬性中),按順序逐次執行。OPhone系統定義:使用Context.sendBroadcast方法發起的都是普通廣播,而有序廣播必須使用另一個方法:Context.sendOrderedBroadcast。幸運的是“向外撥打電話”時系統發出的正是有序廣播,因此我們可以輕松地阻止它。

繼續深入“接聽電話”功能,它是用戶被動響應的活動,所以屬于“被動請求命令”。來電首先會被VendorRIL實現模塊發現,然后上報給RIL守護進程,由守護進程再向更高抽象層次的應用程序報告,最終將依次觸發振鈴提示、顯示來電信息界面等一系列的動作。我們關注的焦點依然是:如何監聽到來電并獲取電話號碼?解決該問題的方法之一是,通過系統服務Context.TELEPHONY_SERVICE注冊關注電話狀態變化的監聽器,從而監測到來電信息。

OPhone系統提供了PhoneStateListener對象做為監聽器的抽象,它是用于即時監測:服務狀態、信號強度、消息等待指示等各方面有關電話功能狀態變化的回調方法機制。想要監測來電呼叫,PhoneStateListener的onCallStateChanged方法是入口點,它把電話呼叫狀態分為三種類型:空閑(IDLE)、振鈴(RINGING)和摘機(OFFHOOK),其中振鈴狀態正是來電呼入的標志,因此具體的方法是:重新實現PhoneStateListener對象的onCallStateChanged方法,并關注RINGING狀態。請看示例代碼:

  1. class MyPhoneStateListener extends PhoneStateListener {     
  2.         public void onCallStateChanged(int state, String incoming) {     
  3.            switch (state) {     
  4.            case TelephonyManager.CALL_STATE_RINGING:     
  5.                // Ringing-振鈴,有電話呼入     
  6.                Log.d(tag, "RINGING~");     
  7.                Log.d(tag, "獲得來電號碼:" + incoming);     
  8.                // TODO:YOU CODE     
  9.                break;     
  10.            case TelephonyManager.CALL_STATE_OFFHOOK:     
  11.                // Offhook-摘機,呼出電話已接通或呼入電話已接起     
  12.                Log.d(tag, "OFFHOOK~");     
  13.                break;     
  14.            case TelephonyManager.CALL_STATE_IDLE:     
  15.                // IDLE-空閑,結束通話狀態     
  16.                Log.d(tag, "IDLE~");     
  17.                break;     
  18.            }     
  19.         }     
  20.     }    

然后,再將該監聽器對象注冊到系統服務TelephonyManager中,以下示例代碼演示了注冊和解除監聽器的方法:

  1. //取得系統服務:TelephonyManager     
  2. String sname = Context.TELEPHONY_SERVICE;     
  3. TelephonyManager tm = (TelephonyManager)   
  4. getSystemService(sname);     
  5.       
  6. //注冊監聽器     
  7. phoneStateListener = new MyPhoneStateListener();     
  8. tm.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);     
  9. Log.d(tag, "listen ok~!");     
  10.       
  11. // 解除監聽器     
  12. tm.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);     
  13. Log.d(tag, "listen cancel~!");   

系統服務TelephonyManager位于android.telephony包下,其listen方法用于注冊和解除自定義的監聽器對象,注冊與解除的區別體現在listen方法的第二個參數——int類型的標志(flag)位上。

遺憾的是,雖然我翻閱了大量文檔,但仍未能找到在監聽器中拒絕來電的方法——即如何拒接的問題,有興趣的讀者請繼續研究。

短消息功能

除電話功能之外,短消息功能也是特別常用的基本電話功能。同樣在OPhone系統中內置有短消息應用(Mms.apk),提供了編寫、發送、接收和閱讀短消息等功能。本文將要討論的重點是:在API級別使用短消息功能的具體方法。

通過API發送短消息的代理是android.telephony包下的SmsManager類,它提供的getDefault()靜態方法可以獲得對象實例,sendTextMessage方法用于發送短消息,sendMultipartTextMessage方法用于發送多條短信。具體用法請看示例代碼:

  1. // 準備短消息內容及相關信息     
  2. String to = "5554";// 目標號碼     
  3. String from = null;// 發送人號碼     
  4. String content = "message text content~~";  
  5. // 短消息內容   // 發送后 執行的Intent     
  6. Intent i = new Intent();     
  7. PendingIntent sent = PendingIntent.getBroadcast  
  8. (this, 0, i, 0);     
  9. // 發送給接收人之后(此處應該指:信息報告或回執)   
  10. 執行的Intent     
  11. PendingIntent delivery = PendingIntent.getBroadcast(this, 0, i, 0);     
  12. // 發送短消息     
  13. SmsManager manager = SmsManager.getDefault();     
  14. manager.sendTextMessage(to, from, content, sent, delivery);    

值得注意的是做為參數的PendingIntent對象,可以把它簡單的理解成:“即將發生的Intent”,也就是說在短信發送完成后和短信送達后,分別向系統發出廣播通知,關注這一事件的應用將監聽此廣播。當然也可以用PendingIntent.getActivity或者getService來創建PendingIntent對象,從而做出其它形式的響應。

本來對于短消息功能而言,同樣會面臨要監聽“收到”和“發出”短消息事件的需求,然而,實現方法與監聽電話功能的方法卻完全不同——系統并未提供監聽器注冊接口和底層廣播消息等途徑,而是要依賴于“內容提供者(Contentproviders)”類型的應用程序,它具有觀察者模式機制,該機制的基本思路是:OPhone系統會把短消息數據(包括發出的和接收到的)保存在一個內容提供者應用程序中(你可以理解成Database或者文件系統的資料庫),該程序允許開發者向其注冊“觀察者對象(ObserverObject)”,以即時了解資料庫中數據的變化,因此只要編寫自己的觀察者對象,并注冊到“發出”或“收到”短信所在的資料庫中,就可以監聽到相關事件了。

簡單說一下“內容提供者(Contentproviders)”,它是一種獨特的應用程序類型,是保存和讀取數據的高級抽象接口,接口實現的背后可以使用數據庫、文件,甚至是遠程網絡來持久保存數據,并且它在一定程度上也呼應著REST架構的思想,例如:使用URI命名標識具體數據;具有增(insert)、刪(delete)、改(update)、查(query)4個基本操作方法,等等。在OPhone系統中,用來存儲短消息數據的內容提供者程序是:TelephonyProvider。

然而令人遺憾的是,以上方法在當前OPhone版本(OPhoneSDK_1.5.beta)中并不可用。通過編寫代碼實際測試發現,TelephonyProvider應用并未響應觀察者機制,雖然注冊新的觀察者不會導致錯誤,但也并未按預想對onChange方法進行回調,初步判斷可能是當前的TelephonyProvider應用有特殊的定制和實現。具體原因還有待進一步學習和研究,同時也歡迎對此有興趣的讀者與我一道共同尋找解決方法。

總結

本文介紹了OPhone平臺中基本電話功能的基礎知識,并通過示例代碼演示了在API級別,使用和控制基本電話功能的具體方法和技巧。

責任編輯:chenqingxiang 來源: ophonesdn
相關推薦

2010-07-23 14:51:09

OPhone開發

2022-02-17 20:57:07

OpenHarmon操作系統鴻蒙

2011-05-05 09:56:01

OPhoneAndroid

2009-03-24 08:33:14

AndroidGoogle移動os

2010-09-17 10:18:59

ODTOPhone

2010-03-04 16:08:21

Android系統平臺

2011-03-03 11:30:09

Pureftpd

2010-09-16 13:38:13

OPhone

2022-05-10 11:17:27

電話子系統數據服務模塊

2010-07-26 15:12:20

坐標變換

2009-08-21 10:51:55

ASP.NET Rou解析URL

2010-09-27 13:49:06

移動開發OPhoneUPhone

2010-05-12 14:18:32

思科統一通信系統

2010-05-19 10:14:41

vmstatLinux系統監控工具

2010-05-19 09:33:27

Linux系統監控工具top

2009-09-08 17:45:13

Ophone Widg

2010-07-23 16:08:38

OPhone平臺

2009-11-25 17:48:18

PHP文件系統相關函數

2011-02-21 10:07:46

OPhone 2.5OPhone

2009-10-22 12:27:30

linux塊設備
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品日日夜夜 | 免费久| 成年人精品视频在线观看 | 久久99久久| 欧美日韩精品综合 | 一区欧美 | 九九热久久免费视频 | 天天澡天天狠天天天做 | 精品一区二区三区四区五区 | 精品成人av | 欧美日韩成人一区二区 | 国产精品亚洲一区 | 精品国产高清一区二区三区 | 久久国产精品亚洲 | 亚洲精品一二区 | 久产久精国产品 | 国产精品久久久久久影院8一贰佰 | 久久久久网站 | 亚av在线 | 日韩欧美在线一区 | 午夜在线观看免费 | 自拍偷拍3p | 激情小说综合网 | 久久久免费少妇高潮毛片 | 午夜视频一区二区三区 | 成人性视频免费网站 | 99久热| 国产欧美综合在线 | 精品欧美一区二区精品久久久 | 在线国产小视频 | 国产线视频精品免费观看视频 | 久久亚洲一区 | 91天堂 | 国产精品一区二区在线 | 日日夜夜草 | 色婷婷精品国产一区二区三区 | 欧美一区视频 | 91在线视频观看 | 欧美日韩国产一区 | 国产一区二区三区四区 | 欧美日韩国产精品一区二区 |