• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            life02

              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
              197 隨筆 :: 3 文章 :: 37 評(píng)論 :: 0 Trackbacks
            http://blog.csdn.net/tyfjy/article/details/6452126

            今天介紹一下在Android中實(shí)現(xiàn)通話接通后震動(dòng)提示,這里通話主要是針對(duì)撥出的電話.想要在接通的時(shí)候給出震動(dòng)提示那么我們就需要知道通話何時(shí)是被接通的.這樣才能在進(jìn)入該狀態(tài)后給出提示.SDK中并沒有直接獲得這種狀態(tài)的方式.首先我們看一下SDK中電話服務(wù)類為我們提供了哪些通話狀態(tài).

            SDK中的TelephonyManager類提供了3種電話的狀態(tài).

            CALL_STATE_IDLE 空閑狀態(tài)

            CALL_STATE_OFFHOOK 摘機(jī)狀態(tài)

            CALL_STATE_RINGING  響鈴狀態(tài)

            這幾個(gè)狀態(tài)很容易理解,其中摘機(jī)狀態(tài)即拿起話筒(對(duì)于座機(jī)電話而言的動(dòng)作),但這個(gè)狀態(tài)可能發(fā)生在撥入電話接通時(shí),也可能是撥出電話時(shí).但是卻不能說明撥出電話接通時(shí).通過以上3種狀態(tài)我們僅能組合出:掛機(jī),來電接通.這兩個(gè)狀態(tài).而今天我們要實(shí)現(xiàn)的功能卻無法做到.

            看來我們需要尋找其他方法來實(shí)現(xiàn)了,SDK靠不住啊……

             

            還好Android在運(yùn)行時(shí)會(huì)有大量的log產(chǎn)生,看看我們能不能從這上面找到突波口呢.我們選擇AndroidRadio模塊的日志來分析.首先我們需要寫一段代碼來讀取Radio相關(guān)的log.讀取log就不得不用到logcat.

            1.     Process process;  
            2.         InputStream inputstream;  
            3.         BufferedReader bufferedreader;  
            4.         try {  
            5.             process = Runtime.getRuntime().exec("logcat -v time -b radio");  
            6.             inputstream = process.getInputStream();  
            7.             InputStreamReader inputstreamreader = new InputStreamReader(  
            8.                     inputstream);  
            9.             bufferedreader = new BufferedReader(inputstreamreader);  
            10.     String str = "";  
            11. while ((str = bufferedreader.readLine()) != null) {  
            12.        log.i("mLogcat",str);  
            13. }  
            14. catch (Exception e) {  
            15.               
            16.         }  
             

             

            另外,要讓程序能夠讀取系統(tǒng)log需要指定權(quán)限,在AndroidManifest.xml文件中加入一下內(nèi)容.

            1. <uses-permission android:name="android.permission.READ_LOGS"></uses-permission>  
             

             

             

            通過上面這段代碼我們就可以將Radiolog輸出到了,這樣我們就可以通過在DDMS中查看這些log,分析其中的通話過程.具體抓到的log就不貼出來了.大家可以自己編寫程序通過上面的代碼來抓取和分析.我只說一下我的分析結(jié)果.

            通過分析log發(fā)現(xiàn)了一些蛛絲馬跡.其中有幾條日志很有用.

            GET_CURRENT_CALLS  id=1,DIALING

            GET_CURRENT_CALLS  id=1,ALERTING

            GET_CURRENT_CALLS  id=1,ACTIVE

            由于log較長(zhǎng)我只拿了每條log的開頭部分,真實(shí)的會(huì)多很多內(nèi)容.當(dāng)我們撥出電話的時(shí)候,會(huì)輸入這么幾條log.

            撥號(hào)->提醒->活動(dòng).

             

            大致是這么個(gè)過程.經(jīng)過幾次測(cè)試發(fā)現(xiàn),電話接通時(shí)會(huì)進(jìn)入活動(dòng)狀態(tài),并會(huì)輸出:GET_CURRENT_CALLS  id=1,ACTIVE  這條log,至此我們已經(jīng)接近成功了.

            不過之后我又發(fā)現(xiàn)在撥號(hào)開始到電話接通這段時(shí)間內(nèi)會(huì)經(jīng)過多次的

            撥號(hào)->提醒->活動(dòng),這樣的狀態(tài)變化,僅當(dāng)話筒中嘟聲響起后GET_CURRENT_CALLS這條日志會(huì)鎖定在ALERTING.在電話接通前便不再出現(xiàn)

            GET_CURRENT_CALLS日志了.

            可能上面的這段表述大家不是很清楚,換句話說在通話接通之前會(huì)出現(xiàn)多次的

            GET_CURRENT_CALLS ACTIVE 這樣的日志,而僅有一次是電話接通產(chǎn)生的.這就給我們?cè)斐闪寺闊?span lang="EN-US">.不能只是單純的抓取GET_CURRENT_CALLS ACTIVE 這樣的信息來判斷了.

            我們只能通過一些邏輯上的判斷來實(shí)現(xiàn)了.下面看我的代碼.

            1. class TestThread implements Runnable {  
            2.     //振動(dòng)器   
            3.     Vibrator mVibrator;  
            4.     //電話服務(wù)   
            5.     TelephonyManager telManager;  
            6.     public TestThread(Vibrator mVibrator, TelephonyManager telManager) {  
            7.         this.mVibrator = mVibrator;  
            8.         this.telManager = telManager;  
            9.     }  
            10.     @Override  
            11.     public void run() {  
            12.         //獲取當(dāng)前話機(jī)狀態(tài)   
            13.         int callState = telManager.getCallState();  
            14.         Log.i("TestService""開始.........." + Thread.currentThread().getName());  
            15.         //記錄撥號(hào)開始時(shí)間   
            16.         long threadStart = System.currentTimeMillis();  
            17.         Process process;  
            18.         InputStream inputstream;  
            19.         BufferedReader bufferedreader;  
            20.         try {  
            21.             process = Runtime.getRuntime().exec("logcat -v time -b radio");  
            22.             inputstream = process.getInputStream();  
            23.             InputStreamReader inputstreamreader = new InputStreamReader(  
            24.                     inputstream);  
            25.             bufferedreader = new BufferedReader(inputstreamreader);  
            26.             String str = "";  
            27.             long dialingStart = 0;  
            28.             boolean enableVibrator = false;  
            29.             boolean isAlert = false;  
            30.             while ((str = bufferedreader.readLine()) != null) {  
            31.                 //如果話機(jī)狀態(tài)從摘機(jī)變?yōu)榭臻e,銷毀線程   
            32.                 if (callState == TelephonyManager.CALL_STATE_OFFHOOK  
            33.                         && telManager.getCallState() == TelephonyManager.CALL_STATE_IDLE) {  
            34.                     break;  
            35.                 }  
            36.                 // 線程運(yùn)行5分鐘自動(dòng)銷毀   
            37.                 if (System.currentTimeMillis() - threadStart > 300000) {  
            38.                     break;  
            39.                 }  
            40.                 Log.i("TestService", Thread.currentThread().getName() + ":"  
            41.                         + str);  
            42.                 // 記錄GSM狀態(tài)DIALING   
            43.                 if (str.contains("GET_CURRENT_CALLS")  
            44.                         && str.contains("DIALING")) {  
            45.                     // 當(dāng)DIALING開始并且已經(jīng)經(jīng)過ALERTING或者首次DIALING   
            46.                     if (!isAlert || dialingStart == 0) {  
            47.                         //記錄DIALING狀態(tài)產(chǎn)生時(shí)間   
            48.                         dialingStart = System.currentTimeMillis();  
            49.                         isAlert = false;  
            50.                     }  
            51.                     continue;  
            52.                 }  
            53.                 if (str.contains("GET_CURRENT_CALLS")  
            54.                         && str.contains("ALERTING")&&!enableVibrator) {  
            55.                       
            56.                     long temp = System.currentTimeMillis() - dialingStart;  
            57.                     isAlert = true;  
            58.                     //這個(gè)是關(guān)鍵,當(dāng)?shù)谝淮蜠IALING狀態(tài)的時(shí)間,與當(dāng)前的ALERTING間隔時(shí)間在1.5秒以上并且在20秒以內(nèi)的話   
            59.                     //那么認(rèn)為下次的ACTIVE狀態(tài)為通話接通.   
            60.                     if (temp > 1500 && temp < 20000) {  
            61.                         enableVibrator = true;  
            62.                         Log.i("TestService""間隔時(shí)間....." + temp + "....."  
            63.                                 + Thread.currentThread().getName());  
            64.                     }  
            65.                     continue;  
            66.                 }  
            67.                 if (str.contains("GET_CURRENT_CALLS") && str.contains("ACTIVE")  
            68.                         && enableVibrator) {  
            69.                     mVibrator.vibrate(100);  
            70.                     enableVibrator = false;  
            71.                     break;  
            72.                 }  
            73.             }  
            74.             Log.i("TestService""結(jié)束.........."  
            75.                     + Thread.currentThread().getName());  
            76.         } catch (Exception e) {  
            77.             // TODO: handle exception   
            78.         }  
            79.     }  
            80. }  
             

             

            我的這個(gè)方法比較牽強(qiáng),是通過判斷第一次DIALING與每一次ALERTING之間的間隔,當(dāng)間隔大于1.5秒.那么認(rèn)為已經(jīng)進(jìn)入了"嘟"聲提示的時(shí)候了,那么下一個(gè)ACTIVE將是電話接通.這個(gè)1.5秒是通過分析日志得出的.但是這種方法我始終覺得不太靠譜.如果大家有好的方法可以交流交流.

            剩下的就是讓這個(gè)線程在電話撥出時(shí)觸發(fā),并且常駐在電話中時(shí)候準(zhǔn)備這就可以了.可以采用Service配合Receiver來實(shí)現(xiàn).Service來實(shí)現(xiàn)常駐,Receiver來實(shí)現(xiàn)監(jiān)聽撥出電話.基本就可以完成,我們想要的功能了.

            以上代碼我都測(cè)試過99%有效,哈哈.這里面提到了一些Android的基礎(chǔ)內(nèi)容像logcat,Service,Receiver.這些如果大家不了解的話可以到網(wǎng)上搜一下.有很多寫的很不錯(cuò)的文章介紹Android的基礎(chǔ)內(nèi)容.我這里就不一一介紹了.

            希望我寫的東西對(duì)大家有所幫助.OK,就到這里吧.

             

            posted on 2012-01-06 09:50 life02 閱讀(723) 評(píng)論(0)  編輯 收藏 引用 所屬分類: Android開發(fā)
            久久久久亚洲AV成人网人人网站 | 97精品国产97久久久久久免费| www.久久热| 久久国产精品99久久久久久老狼| 久久久久久久亚洲Av无码| 久久婷婷激情综合色综合俺也去 | 精品久久香蕉国产线看观看亚洲| 伊人色综合久久天天人手人婷| 亚洲欧美日韩中文久久| 午夜天堂精品久久久久| www.久久99| 久久综合久久综合亚洲| 久久青青草原亚洲av无码app| 国产午夜免费高清久久影院| 精品久久久久久国产牛牛app| 久久伊人五月丁香狠狠色| 久久不见久久见免费视频7| 国产精品免费久久| 久久天天躁狠狠躁夜夜不卡 | 精品久久久久中文字幕一区| 日韩亚洲国产综合久久久| 无码国内精品久久人妻| 久久久久人妻精品一区三寸蜜桃| 影音先锋女人AV鲁色资源网久久| 午夜不卡888久久| 伊人久久久AV老熟妇色| 精品视频久久久久| 久久久av波多野一区二区| 久久久久久国产精品美女 | 亚洲色大成网站www久久九| 99久久精品国产毛片| 久久久久99精品成人片欧美| 理论片午午伦夜理片久久| 99久久这里只有精品| 久久综合噜噜激激的五月天| 婷婷久久综合九色综合九七| 久久九九全国免费| 狠狠色丁香婷综合久久| 久久国产精品99精品国产| 久久棈精品久久久久久噜噜| 久久久久久久久久久久久久 |