Recording calls in android why this not works
Asked Answered
B

2

3

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;
            }
        }
    }
}
Brief answered 7/9, 2013 at 9:52 Comment(1)
Where are the manifest lines for ServiceCaller ? Can you please share the code in github?Kirkcudbright
B
10

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"/>
Brief answered 8/9, 2013 at 9:53 Comment(5)
Can this record both sides sound however I dont think so cause you have taken MIC as the AudioSource which will record the audio from the phone on which its installed, the other end's voice will be less audible. I have tried and found out same.Gaullism
Can you please share the project in github?Kirkcudbright
Who will call ServiceCaller?Mallen
first time it is working but crashing on receiving the second call.can u share the manifest also??Compurgation
Hi It's not working when app is killed or removed from backgroundDisaffection
L
1

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.

Leatherback answered 16/5, 2015 at 15:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.