Recording calls in android why this not works

2019-02-05 08:59发布

问题:

I am starting a service from MainActivity, which run indefinitely looking for incoming and outgoing calls to record.

Why is that the sample "switch-case" doesn't work?

No error occurs but I can record only each of incoming and outgoing.

The service is killed after recording the call, it will be recreated START_STICKY but never going to get started.

Please help. Thanks in advance!


Is there any other codes to record incoming and outgoing call in android?

package com.exampled.demoserv;

import java.io.File;
import java.io.IOException;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.MediaRecorder;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.widget.Toast;


public class ParentalService extends Service 
{
    @Override
    public void onCreate()
    {
        //Toast.makeText(getApplicationContext(), "Service Created", Toast.LENGTH_SHORT).show();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        // TODO Auto-generated method stub
        //Toast.makeText(getApplicationContext(), "Subu's Monitoring sTARTED", Toast.LENGTH_SHORT).show();
        startMonitor();
        return START_STICKY_COMPATIBILITY;
    }

    @Override
    public IBinder onBind(Intent arg0)
    {
        // TODO Auto-generated method stub
        Toast.makeText(getApplicationContext(), "Service Binded", Toast.LENGTH_SHORT).show();
        return null;
    }

    @Override
    public void onDestroy()
    {
        // TODO Auto-generated method stub
        super.onDestroy();
        Toast.makeText(getApplicationContext(), "Destroyed", Toast.LENGTH_SHORT).show();
    }

    public void startMonitor() 
    {
        TelephonyManager mTelephonyMgr = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
        mTelephonyMgr.listen(new TeleListener(), PhoneStateListener.LISTEN_CALL_STATE);
    }

    class TeleListener extends PhoneStateListener
    {
        boolean recording = false;
        final MediaRecorder recorder = new MediaRecorder();
        String inc_num="", fname;

        public void onCallStateChanged(int state, String incomingNumber) throws IllegalStateException
        {
            super.onCallStateChanged(state, incomingNumber);

            switch (state) {
                case TelephonyManager.CALL_STATE_IDLE:
                    //CALL_STATE_IDLE;
                    Toast.makeText(getApplicationContext(), "CALL_STATE_IDLE : "+Boolean.toString(recording), Toast.LENGTH_SHORT).show();

                    if(recording==true)
                    {
                        recorder.stop();
                        recorder.reset();
                        recorder.release();
                        Toast.makeText(getApplicationContext(), "Released_idle", Toast.LENGTH_SHORT).show();
                    }
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    Toast.makeText(getApplicationContext(), Boolean.toString(recording)+" : Offhook",Toast.LENGTH_SHORT).show();

                    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);   
                    recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 
                    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 

                    String file= Environment.getExternalStorageDirectory().toString();
                    String filepath= file+"/111111111111Aandroid_Subui";
                    File dir= new File(filepath);
                    dir.mkdirs();

                    if(inc_num.length()==0)
                    {
                        fname="outgoingNum";
                    }

                    filepath+="/"+fname+".3gp";
                    recorder.setOutputFile(filepath);

                    try {
                        recorder.prepare();
                    } catch (IllegalStateException e) {
                        // TODO Auto-generated catch block
                    e.printStackTrace();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                    recorder.start();  
                    recording=true;
                    break;
                case TelephonyManager.CALL_STATE_RINGING:
                    //CALL_STATE_RINGING
                    inc_num = incomingNumber;
                    Toast.makeText(getApplicationContext(), "CALL_STATE_RINGING : "+incomingNumber, Toast.LENGTH_SHORT).show();
                    break;
                default:
                    Toast.makeText(getApplicationContext(), "Default reached", Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    }
}

回答1:

Finally Got the Result... Now I can record both incoming and outgoing calls(2.2)..

Changed the whole structure..

Here is my CallRecordingService.java Toasting will make you understood whats going arround... :)

package com.exampled.beta;

import java.io.File;
import java.io.IOException;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaRecorder;
import android.os.Environment;
import android.os.IBinder;
import android.telephony.TelephonyManager;
import android.widget.Toast;

public class CallRecordingService extends Service
{
    final MediaRecorder recorder = new MediaRecorder();
    boolean recording = false;
    int i = 0;
    String fname;

    BroadcastReceiver CallRecorder = new BroadcastReceiver()
    {
        @Override
        public void onReceive(Context arg0, Intent intent)
        {
            // TODO Auto-generated method stub
            String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
            i++;

            if(TelephonyManager.EXTRA_STATE_OFFHOOK.equals(state))
            {
                Toast.makeText(getApplicationContext(), state, Toast.LENGTH_LONG).show();

                Toast.makeText(arg0, "Start CaLLED "+recording+fname, Toast.LENGTH_LONG).show();

                startRecording();
            }

            if(TelephonyManager.EXTRA_STATE_IDLE.equals(state) && recording == true)
            {
                Toast.makeText(getApplicationContext(), state, Toast.LENGTH_LONG).show();

                Toast.makeText(arg0, "STOP CaLLED :"+recording, Toast.LENGTH_LONG).show();
                stopRecording();
            }

            if(TelephonyManager.EXTRA_STATE_RINGING.equals(state))
            {
                fname = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
                Toast.makeText(getApplicationContext(), state+" : "+fname, Toast.LENGTH_LONG).show();
            }
        }
    };

    BroadcastReceiver OutGoingNumDetector = new BroadcastReceiver()
    {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            // TODO Auto-generated method stub
            fname=intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
        }
    };

    @Override
    public void onCreate()
    {
        // TODO Auto-generated method stub
        super.onCreate();
        Toast.makeText(getApplicationContext(), "Service Created", Toast.LENGTH_LONG).show();

        IntentFilter RecFilter = new IntentFilter();
        RecFilter.addAction("android.intent.action.PHONE_STATE");
        registerReceiver(CallRecorder, RecFilter);
        IntentFilter OutGoingNumFilter=new IntentFilter();
        OutGoingNumFilter.addAction("android.intent.action.NEW_OUTGOING_CALL");
        registerReceiver(OutGoingNumDetector, OutGoingNumFilter);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        // TODO Auto-generated method stub
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public IBinder onBind(Intent arg0)
    {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void onDestroy()
    {
        // TODO Auto-generated method stub
        super.onDestroy();
        unregisterReceiver(CallRecorder);
        unregisterReceiver(OutGoingNumDetector);
        Toast.makeText(getApplicationContext(), "Destroyed", Toast.LENGTH_SHORT).show();
    }

    public void startRecording()
    {
        if(recording==false)
        {
            Toast.makeText(getApplicationContext(), "Recorder_Sarted"+fname, Toast.LENGTH_LONG).show();
            recorder.setAudioSource(MediaRecorder.AudioSource.MIC);   
            recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 
            recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 
            String file= Environment.getExternalStorageDirectory().toString();
            String filepath= file+"/11111111111111";
            File dir= new File(filepath);
            dir.mkdirs();

            filepath+="/"+fname+".3gp";
            recorder.setOutputFile(filepath);

            try {
                recorder.prepare();
            } catch (IllegalStateException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            recorder.start(); 
            recording=true;
        }
    }

    public void stopRecording()
    {
        if(recording==true)
        {
            Toast.makeText(getApplicationContext(), "Recorder_Relesed from "+recording, Toast.LENGTH_LONG).show();

            recorder.stop();
            recorder.reset();
            recorder.release();
            recording=false;
            broadcastIntent();
        }
    }

    public void broadcastIntent()
    {
       Intent intent = new Intent();
       intent.setAction("com.exampled.beta.CUSTOM_INTENT");
       sendBroadcast(intent);
       Toast.makeText(getApplicationContext(), "BroadCaste", Toast.LENGTH_LONG).show();
    }
}

ServiceCaller.java

package com.exampled.beta;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class ServiceCaller extends BroadcastReceiver
{
    @Override
    public void onReceive(Context arg0, Intent arg1)
    {
        // TODO Auto-generated method stub
        arg0.stopService(new Intent(arg0,CallRecordingService.class));
        Intent intent=new Intent(arg0, CallRecordingService.class);
        arg0.startService(intent);
        Toast.makeText(arg0, "Service Explicitely", Toast.LENGTH_SHORT).show();
    }
}

MainActivity.java

package com.exampled.beta;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;

public class MainActivity extends Activity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent(this,CallRecordingService.class);

        startService(intent);
        finish();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        // Inflate the menu; this adds items to the action bar if it is
        // present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}

PERMISSIONS

<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.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>


回答2:

Instead of myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);

use myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);

This particular option is described here> http://developer.android.com/reference/android/media/MediaRecorder.AudioSource.html Voice call uplink + downlink audio source That means the recording will contain both voices.

Be careful when you start recording. When the call is initiated or when the other-party answer the call.