Androidは電話で自動録音する機能を実現します。


私たちはAndroid携帯を使って電話をかけている時に、来た電話に対して自動録音をする必要があるかもしれません。ここではAndroidでの通話の自動録音を実現する方法を詳しく説明します。
       自動録音の鍵は携帯電話の状態の変化をどうやって監督するかです。
       1)着信の状態の転換は以下の通りです。
       アイドル(IDEL)->チャイム(RINGING)->レシーブ(ACTIVE)->オフ(DISCONECTING――DISCONECTED)->アイドル(IDEL)
       または  アイドル(IDEL)->チャイム(RINGING)->拒否――>アイドル(IDEL)
       2)電気除去状態の転換は以下の通りである。
       アイドル(IDEL)――>>ダイヤル(DIALING)->(相手)ベル(ALERTING)――>接続を確立する(ACTIVE)――オフ(DISCONECTING――DISCONECTED)――アイドル(IDEL)
       アイドル(IDEL)->ダイヤル(DIALING)――>(相手)ベル(ALERTING)――>保留/拒否――アイドル(IDEL)
       以下はそれぞれ電気と電気について分析し、実現します。
       1、まず着信の分析と実現を行います。
       電気に行くよりも、着信状態の切り替え検査は簡単です。androidアプリのPhone Station Listener類は対応する方法を提供していますが、その中をカバーするオンカライズChend(int state、String incompingNumber)方法が必要です。その上で録音機能を追加すればいいです。その中のstateパラメータは各種の電話状態です。その時私達はそれを下の私達が使う状態と比較します。もし電話が私達が欲しい状態であれば、一連の操作を行います。そうでなければ、彼を無視します。これらの状態を取得するには、もう一つの電話関連部門が必要です。それはTelephonyManagerです。このクラスはいくつかの電話状態を提供しています。その中で私たちが使うべきのはTelephonyManager.CALL_です。STATE_IDLE(空き)、TelephonyManager.CALL_STATE_OFFHOOKとTelephonyManager.CALLSTATE_RINGINGの3つの状態です。この3つの状態を判別すると、android.telephone.Phone Station Listener類を継承し、上記のオンカライズChend(int state,String incompingNumber)方法を実現できます。下記のコードをご覧ください。

public class TelListener extends PhoneStateListener {  
  
 @Override  
 public void onCallStateChanged(int state, String incomingNumber) {  
  super.onCallStateChanged(state, incomingNumber);  
  
  switch (state) {  
  case TelephonyManager.CALL_STATE_IDLE: //     ,          
   Log.i("TelephoneState", "IDLE");  
   //            
   break;  
  case TelephonyManager.CALL_STATE_RINGING: //       
   Log.i("TelephoneState", "RINGING");  
   //            
   break;  
  case TelephonyManager.CALL_STATE_OFFHOOK: //   ,    
   Log.i("TelephoneState", "OFFHOOK");  
   //            
   break;  
  }  
  
  Log.i("TelephoneState", String.valueOf(incomingNumber));  
 }  
  
} 
上記の着信状態のモニターコードはまだ十分ではありません。また、ActivityまたはServiceの中でモニターを実現する必要があります。方法は簡単です。コードは以下の通りです。

/** 
*  activity    service       ,          
*/ 
TelephonyManager telMgr = (TelephonyManager)context.getSystemService( 
    Context.TELEPHONY_SERVICE); 
  telMgr.listen(new TelListener(), PhoneStateListener.LISTEN_CALL_STATE); 
このようにして、着信状態のモニター機能を実現しましたが、設備の中で走るにはまだ足りないです。携帯電話の状態を取る権限が二つ必要です。

<uses-permission android:name="android.permission.READ_PHONE_STATE" /> 
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" /> 
これでもう走れます。
       ここまで言うと、録音機能が実現できれば、その上で着信自動録音を実現すれば大丈夫だと思いますが、簡単に話してください。着信なら、録音したいなら、テレフォニーのManager.CALLをモニターしています。STATE_OFFHOOKの状態でテープレコーダーをオンにして録音を開始し、TelephonyManager.CALLをモニターしています。STATE_IDLEの状態ではテープレコーダーを閉じて録音を停止します。このようにして、着信録音機能は完成します。録音機能と同様に権限が必要です。

<uses-permission android:name="android.permission.RECORD_AUDIO"/>  
  
<!--                         -->  
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>  
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 
2、電話の自動録音が終わったら、電気の自動録音の実現方法を紹介します。
       上記のように、着信状態の傍受よりも、電気に行くのが面倒で、このような方法は通用しないということです。これは主にアンディアプリには、状態監査に行く対応の種類と方法が提供されていないからです。最初はネットで検索しましたが、対応の解決方法が見つからないです。ほとんどは電話で傍受しています。つまり上記の方法です。しかし、途中で一つのブログを見つけました。システムログを調べる方式で、その中から電気が流れている状態のキーワードを見つけました。仕方なくこの方法を妥協しました。
       私の(連想A 65上の)発信ログの内容は以下の通りです。
       フィルタキーワードはmforegroundです。

01-06 16:29:54.225: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : DIALING 
01-06 16:29:54.245: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mForegroundCall.getState() : DIALING 
01-06 16:29:54.631: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : DIALING 
01-06 16:29:54.645: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mForegroundCall.getState() : DIALING 
01-06 16:29:54.742: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : DIALING 
01-06 16:29:54.766: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mForegroundCall.getState() : DIALING 
01-06 16:29:54.873: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : DIALING 
01-06 16:29:54.877: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mForegroundCall.getState() : DIALING 
01-06 16:29:55.108: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : DIALING 
01-06 16:29:55.125: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mForegroundCall.getState() : DIALING 
01-06 16:29:57.030: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : ACTIVE 
01-06 16:29:57.155: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mForegroundCall.getState() : ACTIVE 
01-06 16:29:57.480: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : ACTIVE 
01-06 16:29:57.598: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mForegroundCall.getState() : ACTIVE 
01-06 16:29:59.319: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : DISCONNECTING 
01-06 16:29:59.373: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mForegroundCall.getState() : DISCONNECTING 
01-06 16:30:00.392: D/InCallScreen(251): - onDisconnect: currentlyIdle:true ; mForegroundCall.getState():DISCONNECTED 
01-06 16:30:00.399: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): - onDisconnect: currentlyIdle:true ; mForegroundCall.getState():DISCONNECTED 
01-06 16:30:01.042: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : IDLE 
01-06 16:30:01.070: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mForegroundCall.getState() : IDLE 
01-06 16:30:01.558: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : IDLE 
01-06 16:30:01.572: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mForegroundCall.getState() : IDLE 
            キーワードをフィルタする  mbackground

01-06 16:29:54.226: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE 
01-06 16:29:54.256: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE 
01-06 16:29:54.638: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE 
01-06 16:29:54.652: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE 
01-06 16:29:54.743: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE 
01-06 16:29:54.770: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE 
01-06 16:29:54.875: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE 
01-06 16:29:54.882: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE 
01-06 16:29:55.109: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE 
01-06 16:29:55.142: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE 
01-06 16:29:57.031: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE 
01-06 16:29:57.160: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE 
01-06 16:29:57.481: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE 
01-06 16:29:57.622: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE 
01-06 16:29:59.319: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE 
01-06 16:29:59.373: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE 
01-06 16:30:01.042: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE 
01-06 16:30:01.070: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE 
01-06 16:30:01.559: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE 
01-06 16:30:01.573: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE 
上記のログから見られます。各行の最後にある大文字の英語の単語は電気を消した状態です。状態の説明は以下の通りです。
  •        DIALINGダイヤル、相手はまだベル
  • を鳴らしていません。
  •        ACTIVE   相手の電話は
  • でつながります。
  •        DISCONECTING通話が切断された時の
  •        DISCONECTED  通話が切断されました。電話を切ったと考えられます。

  •        私が電話したのは10010で、ベルが鳴らない過程(パソコンが自動的につながっているのが速いです)です。まだ一つ足りない状態です。状態はALERTINGです。これは相手がベルを鳴らしている状態です。
           これらの発信状態があればいいです。今はシステムログを読んで、これらの状態を見つけます。抽出したキーワードは上記のmforeground(フロント通話状態)とmback ground(バックグラウンド通話状態)です。この行のログにmforgroundが含まれている場合は、上の状態の単語が含まれているかどうか確認してください。ならば、システムログを読み込むコードを見てみましょう。
    
    package com.sdvdxl.phonerecorder; 
     
    import java.io.BufferedReader; 
    import java.io.IOException; 
    import java.io.InputStream; 
    import java.io.InputStreamReader; 
     
    import com.sdvdxl.outgoingcall.OutgoingCallState; 
     
    import android.content.Context; 
    import android.content.Intent; 
    import android.util.Log; 
     
    /** 
     * 
     * @author sdvdxl 
     *         
     * onPhoneStateChanged: mForegroundCall.getState()           
     * mBackgroundCall.getState()      
     *     DIALING       ,      ,        , 
     * ALERTING     ,       , 
     *    ACTIVE       
     *    DISCONNECTED            
     *    IDLE           
     *  
     */ 
    public class ReadLog extends Thread { 
     private Context ctx; 
     private int logCount; 
      
     private static final String TAG = "LogInfo OutGoing Call"; 
      
     /** 
      *       
      * @author sdvdxl 
      *  
      */ 
     private static class CallViewState { 
      public static final String FORE_GROUND_CALL_STATE = "mForeground"; 
     } 
      
     /** 
      *      
      * @author sdvdxl 
      * 
      */ 
     private static class CallState { 
      public static final String DIALING = "DIALING"; 
      public static final String ALERTING = "ALERTING"; 
      public static final String ACTIVE = "ACTIVE"; 
      public static final String IDLE = "IDLE"; 
      public static final String DISCONNECTED = "DISCONNECTED"; 
     } 
      
     public ReadLog(Context ctx) { 
      this.ctx = ctx; 
     } 
      
     /** 
      *   Log  
      *        log 
      *          
      */ 
     @Override 
     public void run() { 
      Log.d(TAG, "        "); 
       
      String[] catchParams = {"logcat", "InCallScreen *:s"}; 
      String[] clearParams = {"logcat", "-c"}; 
       
      try { 
       Process process=Runtime.getRuntime().exec(catchParams); 
       InputStream is = process.getInputStream(); 
       BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 
        
       String line = null; 
       while ((line=reader.readLine())!=null) { 
        logCount++; 
        //     
       Log.v(TAG, line); 
         
        //    512     
        if (logCount>512) { 
         //     
         Runtime.getRuntime().exec(clearParams) 
          .destroy();//    ,     
         logCount = 0; 
         Log.v(TAG, "-----------    ---------------"); 
        }  
         
        /*---------------------------------    -----------------------*/ 
        //   
        if (line.contains(ReadLog.CallViewState.FORE_GROUND_CALL_STATE) 
          && line.contains(ReadLog.CallState.IDLE)) { 
         Log.d(TAG, ReadLog.CallState.IDLE); 
        } 
         
        //    ,      ,    ,        , 
        if (line.contains(ReadLog.CallViewState.FORE_GROUND_CALL_STATE) 
          && line.contains(ReadLog.CallState.DIALING)) { 
         Log.d(TAG, ReadLog.CallState.DIALING); 
        } 
         
        //          
        if (line.contains(ReadLog.CallViewState.FORE_GROUND_CALL_STATE) 
          && line.contains(ReadLog.CallState.ALERTING)) { 
         Log.d(TAG, ReadLog.CallState.ALERTING); 
        } 
         
        //   ,     
        if (line.contains(ReadLog.CallViewState.FORE_GROUND_CALL_STATE) 
          && line.contains(ReadLog.CallState.ACTIVE)) { 
         Log.d(TAG, ReadLog.CallState.ACTIVE); 
        } 
         
        //    ,    
        if (line.contains(ReadLog.CallViewState.FORE_GROUND_CALL_STATE) 
          && line.contains(ReadLog.CallState.DISCONNECTED)) { 
         Log.d(TAG, ReadLog.CallState.DISCONNECTED); 
        } 
         
       } //END while 
        
      } catch (IOException e) { 
       e.printStackTrace(); 
      } //END try-catch 
     } //END run 
    } //END class ReadLog 
    以上のコードの中でスレッドが使われているのは、ログを読み込む過程で主方法を阻む他の方法の実行を防ぐためであり、プログラムが対応する電話状態を捕捉するのに影響を与える。
           さて、電気除去中の状態の変化を捉えましたが、どうやってプログラムに通知すればいいですか?キャプチャ後すぐにシステムに放送を送り、プログラムを放送して受信してから録音イベントを処理する方法を採用しています。放送を送るには、唯一の放送を送ります。そのためには、次のような種類があります。
    
    package com.sdvdxl.outgoingcall; 
     
    import com.sdvdxl.phonerecorder.ReadLog; 
     
    import android.content.Context; 
    import android.util.Log; 
     
    public class OutgoingCallState { 
     Context ctx; 
     public OutgoingCallState(Context ctx) { 
      this.ctx = ctx; 
     } 
      
     /** 
      *        
      * @author sdvdxl 
      * 
      */ 
     public static final class ForeGroundCallState { 
      public static final String DIALING =  
        "com.sdvdxl.phonerecorder.FORE_GROUND_DIALING"; 
      public static final String ALERTING =  
        "com.sdvdxl.phonerecorder.FORE_GROUND_ALERTING"; 
      public static final String ACTIVE =  
        "com.sdvdxl.phonerecorder.FORE_GROUND_ACTIVE"; 
      public static final String IDLE =  
        "com.sdvdxl.phonerecorder.FORE_GROUND_IDLE"; 
      public static final String DISCONNECTED =  
        "com.sdvdxl.phonerecorder.FORE_GROUND_DISCONNECTED"; 
     } 
      
     /** 
      *            , 
      *            
      */ 
     public void startListen() { 
      new ReadLog(ctx).start(); 
      Log.d("Recorder", "           ,          "); 
     } 
      
    } 
     プログラムはシステムログの読み込み権限が必要です。
    XML/HTMLコード
              
           そして、ログを読み込むクラスで各状態を検出したところに放送が送信されます。ログを読み込むための完全なコードは以下の通りです。
    
    package com.sdvdxl.phonerecorder; 
     
    import java.io.BufferedReader; 
    import java.io.IOException; 
    import java.io.InputStream; 
    import java.io.InputStreamReader; 
     
    import com.sdvdxl.outgoingcall.OutgoingCallState; 
     
    import android.content.Context; 
    import android.content.Intent; 
    import android.util.Log; 
     
    /** 
     * 
     * @author mrloong 
     *         
     * onPhoneStateChanged: mForegroundCall.getState()           
     * mBackgroundCall.getState()      
     *     DIALING       ,      ,        , 
     * ALERTING     ,       , 
     *    ACTIVE       
     *    DISCONNECTED            
     *    IDLE           
     *  
     */ 
    public class ReadLog extends Thread { 
     private Context ctx; 
     private int logCount; 
      
     private static final String TAG = "LogInfo OutGoing Call"; 
      
     /** 
      *       
      * @author sdvdxl 
      *  
      */ 
     private static class CallViewState { 
      public static final String FORE_GROUND_CALL_STATE = "mForeground"; 
     } 
      
     /** 
      *      
      * @author sdvdxl 
      * 
      */ 
     private static class CallState { 
      public static final String DIALING = "DIALING"; 
      public static final String ALERTING = "ALERTING"; 
      public static final String ACTIVE = "ACTIVE"; 
      public static final String IDLE = "IDLE"; 
      public static final String DISCONNECTED = "DISCONNECTED"; 
     } 
      
     public ReadLog(Context ctx) { 
      this.ctx = ctx; 
     } 
      
     /** 
      *   Log  
      *        log 
      *          
      */ 
     @Override 
     public void run() { 
      Log.d(TAG, "        "); 
       
      String[] catchParams = {"logcat", "InCallScreen *:s"}; 
      String[] clearParams = {"logcat", "-c"}; 
       
      try { 
       Process process=Runtime.getRuntime().exec(catchParams); 
       InputStream is = process.getInputStream(); 
       BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 
        
       String line = null; 
       while ((line=reader.readLine())!=null) { 
        logCount++; 
        //     
       Log.v(TAG, line); 
         
        //    512     
        if (logCount>512) { 
         //     
         Runtime.getRuntime().exec(clearParams) 
          .destroy();//    ,     
         logCount = 0; 
         Log.v(TAG, "-----------    ---------------"); 
        }  
         
        /*---------------------------------    -----------------------*/ 
        //   
        if (line.contains(ReadLog.CallViewState.FORE_GROUND_CALL_STATE) 
          && line.contains(ReadLog.CallState.IDLE)) { 
         Log.d(TAG, ReadLog.CallState.IDLE); 
        } 
         
        //    ,      ,    ,        , 
        if (line.contains(ReadLog.CallViewState.FORE_GROUND_CALL_STATE) 
          && line.contains(ReadLog.CallState.DIALING)) { 
         //     
         Intent dialingIntent = new Intent(); 
         dialingIntent.setAction(OutgoingCallState.ForeGroundCallState.DIALING); 
         ctx.sendBroadcast(dialingIntent); 
          
         Log.d(TAG, ReadLog.CallState.DIALING); 
        } 
         
        //          
        if (line.contains(ReadLog.CallViewState.FORE_GROUND_CALL_STATE) 
          && line.contains(ReadLog.CallState.ALERTING)) { 
         //     
         Intent dialingIntent = new Intent(); 
         dialingIntent.setAction(OutgoingCallState.ForeGroundCallState.ALERTING); 
         ctx.sendBroadcast(dialingIntent); 
          
         Log.d(TAG, ReadLog.CallState.ALERTING); 
        } 
         
        //   ,     
        if (line.contains(ReadLog.CallViewState.FORE_GROUND_CALL_STATE) 
          && line.contains(ReadLog.CallState.ACTIVE)) { 
         //     
         Intent dialingIntent = new Intent(); 
         dialingIntent.setAction(OutgoingCallState.ForeGroundCallState.ACTIVE); 
         ctx.sendBroadcast(dialingIntent); 
          
         Log.d(TAG, ReadLog.CallState.ACTIVE); 
        } 
         
        //    ,    
        if (line.contains(ReadLog.CallViewState.FORE_GROUND_CALL_STATE) 
          && line.contains(ReadLog.CallState.DISCONNECTED)) { 
         //     
         Intent dialingIntent = new Intent(); 
         dialingIntent.setAction(OutgoingCallState.ForeGroundCallState.DISCONNECTED); 
         ctx.sendBroadcast(dialingIntent); 
          
         Log.d(TAG, ReadLog.CallState.DISCONNECTED); 
        } 
         
       } //END while 
        
      } catch (IOException e) { 
       e.printStackTrace(); 
      } //END try-catch 
     } //END run 
    } //END class ReadLog 
    放送を送りました。受信者が必要です。受信者を定義するには以下の通りです。
    
    package com.sdvdxl.phonerecorder; 
     
    import android.content.BroadcastReceiver; 
    import android.content.Context; 
    import android.content.Intent; 
    import android.util.Log; 
     
    import com.sdvdxl.outgoingcall.OutgoingCallState; 
     
    public class OutgoingCallReciver extends BroadcastReceiver { 
     static final String TAG = "Recorder"; 
     private MyRecorder recorder; 
      
     public OutgoingCallReciver() { 
      recorder = new MyRecorder(); 
     } 
      
     public OutgoingCallReciver (MyRecorder recorder) { 
      this.recorder = recorder; 
     } 
      
     @Override 
     public void onReceive(Context ctx, Intent intent) { 
      String phoneState = intent.getAction(); 
       
      if (phoneState.equals(Intent.ACTION_NEW_OUTGOING_CALL)) { 
       String phoneNum = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);//     
       recorder.setPhoneNumber(phoneNum); 
       recorder.setIsCommingNumber(false); 
       Log.d(TAG, "       "); 
       Log.d(TAG, "       :" + phoneNum); 
      } 
       
      if (phoneState.equals(OutgoingCallState.ForeGroundCallState.DIALING)) { 
       Log.d(TAG, "    ..."); 
      } 
       
      if (phoneState.equals(OutgoingCallState.ForeGroundCallState.ALERTING)) { 
       Log.d(TAG, "    ..."); 
      } 
       
      if (phoneState.equals(OutgoingCallState.ForeGroundCallState.ACTIVE)) { 
       if (!recorder.isCommingNumber() && !recorder.isStarted()) { 
        Log.d(TAG, "           "); 
        recorder.start(); 
         
       } 
      } 
       
      if (phoneState.equals(OutgoingCallState.ForeGroundCallState.DISCONNECTED)) { 
       if (!recorder.isCommingNumber() && recorder.isStarted()) { 
        Log.d(TAG, "         "); 
        recorder.stop(); 
       } 
      } 
     } 
     
    } 
          このようなコードがあります。
    
    String phoneState = intent.getAction();  
        
      if (phoneState.equals(Intent.ACTION_NEW_OUTGOING_CALL)) {  
       String phoneNum = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);//      
       recorder.setPhoneNumber(phoneNum);  
       recorder.setIsCommingNumber(false);  
       Log.d(TAG, "       ");  
       Log.d(TAG, "       :" + phoneNum);  
      } 
     ここでは、受信システムからのブロードキャストを受信するためのものである。このようにして、電気除去状態が得られた。
           3、上記の主要コードがあります。つまり、電話をかけてモニター機能が完成しました。次はserviceを作成してモニターを実行します。
    
    package com.sdvdxl.service; 
     
    import android.app.Service; 
    import android.content.Context; 
    import android.content.Intent; 
    import android.content.IntentFilter; 
    import android.os.IBinder; 
    import android.telephony.PhoneStateListener; 
    import android.telephony.TelephonyManager; 
    import android.util.Log; 
    import android.widget.Toast; 
     
    import com.sdvdxl.outgoingcall.OutgoingCallState; 
    import com.sdvdxl.phonerecorder.MyRecorder; 
    import com.sdvdxl.phonerecorder.OutgoingCallReciver; 
    import com.sdvdxl.phonerecorder.TelListener; 
     
    public class PhoneCallStateService extends Service { 
     private OutgoingCallState outgoingCallState; 
     private OutgoingCallReciver outgoingCallReciver; 
     private MyRecorder recorder; 
      
     @Override 
     public void onCreate() { 
      super.onCreate(); 
       
      //------     onStartCommand , 2.3.5       service         -------- 
      //      ,                       
      //    ,            
      Log.d("Recorder", "     ..."); 
      recorder = new MyRecorder(); 
      outgoingCallState = new OutgoingCallState(this); 
      outgoingCallReciver = new OutgoingCallReciver(recorder); 
      outgoingCallState.startListen(); 
      Toast.makeText(this, "     ", Toast.LENGTH_LONG).show(); 
       
      //   
      IntentFilter outgoingCallFilter = new IntentFilter(); 
      outgoingCallFilter.addAction(OutgoingCallState.ForeGroundCallState.IDLE); 
      outgoingCallFilter.addAction(OutgoingCallState.ForeGroundCallState.DIALING); 
      outgoingCallFilter.addAction(OutgoingCallState.ForeGroundCallState.ALERTING); 
      outgoingCallFilter.addAction(OutgoingCallState.ForeGroundCallState.ACTIVE); 
      outgoingCallFilter.addAction(OutgoingCallState.ForeGroundCallState.DISCONNECTED); 
       
      outgoingCallFilter.addAction("android.intent.action.PHONE_STATE"); 
      outgoingCallFilter.addAction("android.intent.action.NEW_OUTGOING_CALL"); 
       
      //      
      registerReceiver(outgoingCallReciver, outgoingCallFilter); 
       
      //   
      TelephonyManager telmgr = (TelephonyManager)getSystemService( 
        Context.TELEPHONY_SERVICE); 
      telmgr.listen(new TelListener(recorder), PhoneStateListener.LISTEN_CALL_STATE); 
       
       
     } 
      
     @Override 
     public IBinder onBind(Intent intent) { 
      // TODO Auto-generated method stub 
      return null; 
     } 
     
     @Override 
     public void onDestroy() { 
      super.onDestroy(); 
      unregisterReceiver(outgoingCallReciver); 
      Toast.makeText( 
        this, "         ", Toast.LENGTH_LONG) 
        .show(); 
      Log.d("Recorder", "         "); 
     } 
     
     @Override 
     public int onStartCommand(Intent intent, int flags, int startId) { 
       
      return START_STICKY; 
     } 
     
    } 
    以下のサービスを登録します。
    XML/HTMLコード
    <service android:name=「come.sdvice.service.Phone CallStteService」/>  
           これまでのところ、電話をかけてきたモニター機能は完成しました。録音機が一つ残っています。録音機のコードを添付してください。
    
    package com.sdvdxl.phonerecorder; 
     
    import java.io.File; 
    import java.io.IOException; 
    import java.text.SimpleDateFormat; 
    import java.util.Date; 
     
    import android.media.MediaRecorder; 
    import android.os.Environment; 
    import android.util.Log; 
     
    public class MyRecorder { 
     private String phoneNumber; 
     private MediaRecorder mrecorder; 
     private boolean started = false; //          
     private boolean isCommingNumber = false;//      
     private String TAG = "Recorder"; 
      
      
     public MyRecorder(String phoneNumber) { 
      this.setPhoneNumber(phoneNumber); 
     } 
      
     public MyRecorder() { 
     } 
     
     public void start() { 
      started = true; 
      mrecorder = new MediaRecorder(); 
       
      File recordPath = new File( 
        Environment.getExternalStorageDirectory() 
        , "/My record");  
      if (!recordPath.exists()) { 
       recordPath.mkdirs(); 
       Log.d("recorder", "    "); 
      } 
       
      String callDir = "  "; 
      if (isCommingNumber) { 
       callDir = "  "; 
      } 
      String fileName = callDir + "-" + phoneNumber + "-"  
        + new SimpleDateFormat("yy-MM-dd_HH-mm-ss") 
         .format(new Date(System.currentTimeMillis())) + ".mp3";//   3gp 
      File recordName = new File(recordPath, fileName); 
       
      try { 
       recordName.createNewFile(); 
       Log.d("recorder", "    " + recordName.getName()); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
       
      mrecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT); 
      mrecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT); 
      mrecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); 
       
      mrecorder.setOutputFile(recordName.getAbsolutePath()); 
       
      try { 
       mrecorder.prepare(); 
      } catch (IllegalStateException e) { 
       e.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      mrecorder.start(); 
      started = true; 
      Log.d(TAG , "    "); 
     } 
      
     public void stop() { 
      try { 
       if (mrecorder!=null) { 
        mrecorder.stop(); 
        mrecorder.release(); 
        mrecorder = null; 
       } 
       started = false; 
      } catch (IllegalStateException e) { 
       e.printStackTrace(); 
      } 
       
       
      Log.d(TAG , "    "); 
     } 
      
     public void pause() { 
       
     } 
     
     public String getPhoneNumber() { 
      return phoneNumber; 
     } 
     
     public void setPhoneNumber(String phoneNumber) { 
      this.phoneNumber = phoneNumber; 
     } 
     
     public boolean isStarted() { 
      return started; 
     } 
     
     public void setStarted(boolean hasStarted) { 
      this.started = hasStarted; 
     } 
     
     public boolean isCommingNumber() { 
      return isCommingNumber; 
     } 
     
     public void setIsCommingNumber(boolean isCommingNumber) { 
      this.isCommingNumber = isCommingNumber; 
     } 
     
    } 
           これで、電話で自動録音する機能はすべて完成しました。みんな自分で書いてみて、実現できます。
           以上はAndroidの電話録音の開発です。必要な友達を助けたいです。ありがとうございます。