Android四大組件應用系列——實現電話攔截和電話錄音


一、問題描述

  使用BordercastReceiver和Service組件實現下述功能:

1.當手機處於來電狀態,啟動監聽服務,對來電進行監聽錄音。

2.設置電話黑名單,當來電是黑名單電話,則直接掛斷。

  當撥打電話或電話狀態發生改變時,系統就會發出有序廣播,因此我們可以使用BordercastReceiver接受廣播,因BordercastReceiver執行時間短不能執行耗時任務也不能使用子線程,因此我們應啟動一個Service來監聽電話並進行處理

二、加入AIDL文件

  Android沒有對外公開結束通話的API,要結束通話就必須使用AIDL與電話管理服務進行通信,並調用服務中的API實現結束通話,這樣需要android 源碼文件NeighboringCellInfo.aidl和ITelephony.aidl添加到項目中,如圖所示:

 

Android Studio 會自動編譯產生對應的類文件

三、編寫TelReceiver組件
public class TelReceiver extends BroadcastReceiver {
    public TelReceiver() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Intent i=new Intent(context,ListenPhoneService.class);
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        i.setAction(intent.getAction());
        i.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER,
                intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER));//電話號碼
        i.putExtra(TelephonyManager.EXTRA_STATE,
                intent.getStringExtra(TelephonyManager.EXTRA_STATE));//電話狀態
        context.startService(i);//啟動服務
    }
}

  注冊廣播:

<receiver android:name=".TelReceiver" >
    <intent-filter android:priority="1000" >
        <action android:name="android.intent.action.PHONE_STATE" />
        <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
    </intent-filter>
</receiver>
四、編寫ListenPhoneService組件
public class ListenPhoneService  extends  Service {
    private  AudioManager mAudioManager;
    private TelephonyManager tm;
    public ListenPhoneService() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mAudioManager=(AudioManager)getSystemService(Context.AUDIO_SERVICE);
        tm=(TelephonyManager)getSystemService(Service.TELEPHONY_SERVICE);
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if(intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)){//去電廣播,android沒有來電話廣播
        }else{//去掉撥打電話就是來電狀態了
  //方法1
//獲得來電電話
// String number=intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
//獲得電話狀態
// String state=intent.getStringExtra(TelephonyManager.EXTRA_STATE);
//            Log.d("jereh", "incoming phone:" + number);
//            Log.d("jereh","call state:"+state);
//            TelephonyManager.EXTRA_STATE_IDLE: 沒有來電 或者 掛斷
//            TelephonyManagerEXTRA_STATE_OFFHOOK: 接起電話
//            TelephonyManager.EXTRA_STATE_RINGING:當電話呼入時,響鈴時
//           if(state.equals(TelephonyManager.EXTRA_STATE_RINGING)){
//           if(number.equals("13280998858")){//攔截指定的電話號碼
//               mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
//               Log.d("jereh","電話被攔截");
//              stopCall();
//                    mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);//恢復鈴聲
//                }
//            }else if(state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){
        //接起電話
//                recordCall();//開始錄音
//            }else if(state.equals(TelephonyManager.EXTRA_STATE_IDLE)){
//                stopCall();//停止錄音
//            }
 //方法2
            // 設置一個監聽器,監聽電話狀態
            tm.listen(listener,PhoneStateListener.LISTEN_CALL_STATE);
        }

        return super.onStartCommand(intent, flags, startId);
    }

    /**
     * 掛斷電話
     */
    private void stopCall(){
        try {
            //Android的設計將ServiceManager隱藏了,所以只能使用反射機制獲得。
            Method method=Class.forName("android.os.ServiceManager").getMethod("getService", String.class);
            IBinder binder=(IBinder)method.invoke(null, new Object[]{"phone"});//獲得系統電話服務
            ITelephony telephoney=ITelephony.Stub.asInterface(binder);
            telephoney.endCall();//掛斷電話
            stopSelf();//停止服務
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    PhoneStateListener listener=new PhoneStateListener(){
        @Override
        public  void onCallStateChanged(int state,String incomingNumber){
            switch (state){
                //手機空閑了
                case TelephonyManager.CALL_STATE_IDLE:
                     stopCall();//停止錄音
                    break;
                //接起電話
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    recordCall();//開始錄音
                    break;
                // 響鈴時
                case TelephonyManager.CALL_STATE_RINGING:
                    Log.e("jereh", "來電號碼是:"+ incomingNumber);
                    // 如果該號碼屬於黑名單
                    if (incomingNumber.equals("123456")) {
                        // 如果是黑名單,就進行屏蔽
                        stopCall();
                    }
                    break;
            }
        }
    };

    /**
     * 停止錄音
     */
    private void stopRecord(){
        if(recording){
            recorder.stop();
            recorder.release();
            recording=false;
            stopSelf();//停止服務
        }
    }
    /**
     * 電話錄音
     */
    private MediaRecorder recorder;
    private boolean recording ;
    private void recordCall(){
        Log.d("jereh", "record calling")
  if( Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
       recorder=new MediaRecorder();
       recorder.setAudioSource(MediaRecorder.AudioSource.MIC);//讀麥克風的聲音
       recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);//設置輸出格式
       recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);// 編碼方式
       File file=new    File(Environment.getDownloadCacheDirectory().getAbsolutePath(),"recorder");
      if(!file.exists()){
                file.mkdir();
       }
   recorder.setOutputFile(file.getAbsolutePath() + "/"
   + System.currentTimeMillis() + "3gp");// 存放的位置是放在sd卡recorder目錄下
    try {
            recorder.prepare();
            recorder.start();
            recording=true;

       } catch (IOException e) {
                e.printStackTrace();
      }
      }
 }
    @Override
    public IBinder onBind(Intent intent) {
         throw new UnsupportedOperationException("Not yet implemented");
    }
}
Service XML配置
<service
    android:name=".ListenPhoneService"
    android:enabled="true"
    android:exported="true" >
</service>
五、最后別忘了一些權限的設置
<!-- 添加訪問手機電話狀態的權限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- 撥打電話權限 -->
<uses-permission android:name="android.permission.CALL_PHONE" />
<!-- 監聽手機去電的權限 -->
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<!-- 在SDCard中創建與刪除文件權限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<!-- 往SDCard寫入數據權限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

 

作者:傑瑞教育
出處: http://www.cnblogs.com/jerehedu/ 
版權聲明:本文版權歸 傑瑞教育 技有限公司和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
技術咨詢:JRedu技術交流
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM