自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

OPhone系統(tǒng)之電話功能詳解

移動(dòng)開發(fā)
OPhone作為一個(gè)嵌入式操作系統(tǒng),目前主要運(yùn)行在有電話功能的手持設(shè)備上,因此最基本的電話功能——如:撥打、接聽電話,接收、發(fā)送短信,就成為它最重要的核心功能了。

概述

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

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

電話功能

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

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

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

  1. //取得目標(biāo)號(hào)碼     
  2. String number = editText.getText().toString();     
  3. Uri data = Uri.parse("tel:" + number);     
  4. //調(diào)用撥打電話功能     
  5. if (v.getId() == R.id.btn_dial) {     
  6.    //進(jìn)入撥號(hào)界面     
  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.    //直接進(jìn)行呼叫     
  12.    Intent intent = new Intent(Intent.ACTION_CALL, data);     
  13.    intent.addCategory(Intent.CATEGORY_DEFAULT);     
  14.    startActivity(intent);     
  15. }    

代碼非常簡單,關(guān)鍵是使用Intent.ACTION_DIAL或Intent.ACTION_CALL做為Intent的action名稱,并把Uri類型的data數(shù)據(jù)作為目標(biāo)電話號(hào)碼附加到Intent中。

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

請看示例代碼:

  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.             // 監(jiān)聽到撥打電話動(dòng)作,并獲取目標(biāo)電話號(hào)碼     
  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的字符串字面值。當(dāng)再次撥號(hào)時(shí),無論使用上文介紹的API或通過內(nèi)置的電話應(yīng)用程序,該接收器都會(huì)自動(dòng)捕捉到并且獲取目標(biāo)電話號(hào)碼。
再進(jìn)一步考慮,假設(shè)需要將某特定號(hào)碼屏蔽掉——禁止用戶撥打該號(hào)碼,要怎么才能做到呢?其實(shí),只需要在廣播接收器的實(shí)現(xiàn)代碼中,有選擇的終止廣播數(shù)據(jù)傳播即可。請看示例代碼:

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

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

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

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

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

  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, "獲得來電號(hào)碼:" + incoming);     
  8.                // TODO:YOU CODE     
  9.                break;     
  10.            case TelephonyManager.CALL_STATE_OFFHOOK:     
  11.                // Offhook-摘機(jī),呼出電話已接通或呼入電話已接起     
  12.                Log.d(tag, "OFFHOOK~");     
  13.                break;     
  14.            case TelephonyManager.CALL_STATE_IDLE:     
  15.                // IDLE-空閑,結(jié)束通話狀態(tài)     
  16.                Log.d(tag, "IDLE~");     
  17.                break;     
  18.            }     
  19.         }     
  20.     }    

然后,再將該監(jiān)聽器對象注冊到系統(tǒng)服務(wù)TelephonyManager中,以下示例代碼演示了注冊和解除監(jiān)聽器的方法:

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

系統(tǒng)服務(wù)TelephonyManager位于android.telephony包下,其listen方法用于注冊和解除自定義的監(jiān)聽器對象,注冊與解除的區(qū)別體現(xiàn)在listen方法的第二個(gè)參數(shù)——int類型的標(biāo)志(flag)位上。

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

短消息功能

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

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

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

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

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

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

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

總結(jié)

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

責(zé)任編輯:chenqingxiang 來源: ophonesdn
相關(guān)推薦

2010-07-23 14:51:09

OPhone開發(fā)

2022-02-17 20:57:07

OpenHarmon操作系統(tǒng)鴻蒙

2009-03-24 08:33:14

AndroidGoogle移動(dòng)os

2010-09-17 10:18:59

ODTOPhone

2011-05-05 09:56:01

OPhoneAndroid

2010-03-04 16:08:21

Android系統(tǒng)平臺(tái)

2011-03-03 11:30:09

Pureftpd

2022-05-10 11:17:27

電話子系統(tǒng)數(shù)據(jù)服務(wù)模塊

2010-09-16 13:38:13

OPhone

2009-08-21 10:51:55

ASP.NET Rou解析URL

2010-05-12 14:18:32

思科統(tǒng)一通信系統(tǒng)

2010-05-19 09:33:27

Linux系統(tǒng)監(jiān)控工具top

2010-09-27 13:49:06

移動(dòng)開發(fā)OPhoneUPhone

2010-05-19 10:14:41

vmstatLinux系統(tǒng)監(jiān)控工具

2010-07-26 15:12:20

坐標(biāo)變換

2009-11-25 17:48:18

PHP文件系統(tǒng)相關(guān)函數(shù)

2009-10-22 12:27:30

linux塊設(shè)備

2018-06-15 15:50:34

技術(shù)

2011-02-21 10:07:46

OPhone 2.5OPhone

2010-05-21 14:00:42

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)