0

I am trying to create call recorder to run in Service in background but am getting MediaRecorder Start failed error, when it tries to start mediarecorder in background, java code gives

Java code used is as follows:

MainActivity.java

package com.example.callrecorder2;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;


public class MainActivity extends ActionBarActivity {

    // onCreate method.
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Initialise display.
        setContentView(R.layout.activity_main);

        // Declare buttons for Start and Stop.
        Button startService = (Button)findViewById(R.id.startbutton);
        Button stopService  = (Button)findViewById(R.id.stopbutton);

        // Set listeners for buttons.
        startService.setOnClickListener(startServiceListener);
        stopService.setOnClickListener(stopServiceListener); 

        // Initialise serviceStatus text field in display.
        TextView tv = (TextView) findViewById(R.id.recording_status);
        tv.setText(getString(R.string.rec_stop_status));

    }   
    // Define OnClickListener for Start Service button.
    private OnClickListener startServiceListener = new OnClickListener() {
        public void onClick(View v){

            // Start the Service.
            Intent serviceIntent = new Intent(MainActivity.this,callreceiverservice.class);
            startService(serviceIntent);
            Log.i("DUMDUM","Start Button Clicked");
            // Display Service Running message.
            TextView tv = (TextView) findViewById(R.id.recording_status);
            tv.setText(getString(R.string.rec_start_status));
        }               
    };
    // Define OnClickListener for Stop Service button.
    private OnClickListener stopServiceListener = new OnClickListener() {
        public void onClick(View v){

            // Stop the Service.
            Intent serviceIntent = new Intent(MainActivity.this,callreceiverservice.class);
            stopService(serviceIntent);
            Log.i("DUMDUM","Stop Button Clicked");

            // Display Service Not Running message.
            TextView tv = (TextView) findViewById(R.id.recording_status);
            tv.setText(getString(R.string.rec_stop_status));
        }               
    };


}

callreceiverservice.java

package com.example.callrecorder2;

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.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;

public class callreceiverservice extends Service  {
    int checkIt = 0;
    Context contextt;
    private static final String ACTION="android.intent.action.PHONE_STATE";
    private BroadcastReceiver yourReceiver;

    private static final String AUDIO_RECORDER_FILE_EXT_3GP = ".3gp";
    private static final String AUDIO_RECORDER_FILE_EXT_MP4 = ".mp4";
    private static final String AUDIO_RECORDER_FOLDER = "AudioRecorder";

    private MediaRecorder recorder = null;  
    private int currentFormat = 0;
    private int output_formats[] = { MediaRecorder.OutputFormat.THREE_GPP ,MediaRecorder.OutputFormat.MPEG_4 };
    private String file_exts[] = { AUDIO_RECORDER_FILE_EXT_3GP , AUDIO_RECORDER_FILE_EXT_MP4 }; 
    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;        
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {

        Log.i("DUMDUM","Into onStartCommand");
        final IntentFilter theFilter = new IntentFilter();
        theFilter.addAction(ACTION);
        this.yourReceiver = new BroadcastReceiver(){
             @Override
                public void onReceive(Context context, Intent intent) {
                    contextt = context;
                    TelephonyManager tm = (TelephonyManager) context.getSystemService(
                            Context.TELEPHONY_SERVICE);
                    tm.listen(new CallStateListener(), PhoneStateListener.LISTEN_CALL_STATE);
                    Log.i("DUMDUM","Into onRecieve");

             }  
        };      
        this.registerReceiver(this.yourReceiver, theFilter);
        return START_STICKY;
    }


    class CallStateListener extends PhoneStateListener {

        private String getFilename(){
            String filepath = Environment.getExternalStorageDirectory().getPath();
            File file = new File(filepath,AUDIO_RECORDER_FOLDER);

            if(!file.exists()){
                file.mkdirs();
            }

            return (file.getAbsolutePath() + "/" + System.currentTimeMillis() + file_exts[currentFormat]);
        }
        private MediaRecorder.OnErrorListener errorListener = new MediaRecorder.OnErrorListener() {
            @Override
            public void onError(MediaRecorder mr, int what, int extra) {
                AppLog.logString("Error: " + what + ", " + extra);
            }
        };

        private MediaRecorder.OnInfoListener infoListener = new MediaRecorder.OnInfoListener() {
            @Override
            public void onInfo(MediaRecorder mr, int what, int extra) {
                AppLog.logString("Warning: " + what + ", " + extra);
            }
        };

            @Override
            public void onCallStateChanged(int state, String incomingNumber) {
                //Log.i("DUMDUM","Into Call state Listener Class");
                super.onCallStateChanged(state, incomingNumber);
                switch (state) {
                case TelephonyManager.CALL_STATE_RINGING:
                    // called when someone is ringing to this phone

                    Toast.makeText(contextt, "Incoming: " + incomingNumber,
                            Toast.LENGTH_LONG).show();
                    checkIt = 1;
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    Toast.makeText(contextt, "CALL_STATE_OFFHOOK " + incomingNumber,
                            Toast.LENGTH_LONG).show();

                    recorder = new MediaRecorder();
                    AppLog.logString("setAudioSource(): " + MediaRecorder.AudioSource.VOICE_CALL);
                    recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
                    AppLog.logString("setOutputFormat: " + output_formats[currentFormat]);
                    recorder.setOutputFormat(output_formats[currentFormat]);
                    AppLog.logString("setAudioEncoder(): " + MediaRecorder.AudioEncoder.AMR_NB);
                    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
                    AppLog.logString("getFilename(): " + getFilename());
                    recorder.setOutputFile(getFilename());

                    recorder.setOnErrorListener(errorListener);
                    recorder.setOnInfoListener(infoListener);

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

                    checkIt = 0;
                    break;
                case TelephonyManager.CALL_STATE_IDLE:
                    Toast.makeText(contextt, "CALL_STATE_IDLE " + incomingNumber,
                            Toast.LENGTH_LONG).show();

                    if (recorder != null) {
                          recorder.stop();
                          recorder.release();
                          recorder = null;
                       }
                    if (checkIt == 1) {
                     //startting the service
                        break;
                    }
                }

            }

        }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // Do not forget to unregister the receiver!!!
        Log.i("DUMDUM","Into onDestroy");
        this.unregisterReceiver(this.yourReceiver);
    }
}

AppLog.java

package com.example.callrecorder2;

import android.util.Log;

public class AppLog {
private static final String APP_TAG = "AudioRecorder";

    public static int logString(String message){
        return Log.i(APP_TAG,message);
    }

}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.callrecorder2"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
    <uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            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=".callreceiverservice"> 
            </service>
    </application>

</manifest>

Logcat of application displaying error message:

08-19 19:49:06.582: E/MediaRecorder(942): start failed: -2147483648
08-19 19:49:06.582: D/AndroidRuntime(942): Shutting down VM
08-19 19:49:06.582: W/dalvikvm(942): threadid=1: thread exiting with uncaught exception (group=0x40a71930)
08-19 19:49:06.602: E/AndroidRuntime(942): FATAL EXCEPTION: main
08-19 19:49:06.602: E/AndroidRuntime(942): java.lang.RuntimeException: start failed.
08-19 19:49:06.602: E/AndroidRuntime(942):  at android.media.MediaRecorder.start(Native Method)
08-19 19:49:06.602: E/AndroidRuntime(942):  at com.example.callrecorder2.callreceiverservice$CallStateListener.onCallStateChanged(callreceiverservice.java:124)
08-19 19:49:06.602: E/AndroidRuntime(942):  at android.telephony.PhoneStateListener$2.handleMessage(PhoneStateListener.java:369)
08-19 19:49:06.602: E/AndroidRuntime(942):  at android.os.Handler.dispatchMessage(Handler.java:99)
08-19 19:49:06.602: E/AndroidRuntime(942):  at android.os.Looper.loop(Looper.java:137)
08-19 19:49:06.602: E/AndroidRuntime(942):  at android.app.ActivityThread.main(ActivityThread.java:5041)
08-19 19:49:06.602: E/AndroidRuntime(942):  at java.lang.reflect.Method.invokeNative(Native Method)
08-19 19:49:06.602: E/AndroidRuntime(942):  at java.lang.reflect.Method.invoke(Method.java:511)
08-19 19:49:06.602: E/AndroidRuntime(942):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
08-19 19:49:06.602: E/AndroidRuntime(942):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
08-19 19:49:06.602: E/AndroidRuntime(942):  at dalvik.system.NativeStart.main(Native Method)

Please help to solve this error as I have tried everything but runtime Error is not going away.

Deep
  • 11
  • 3
  • have you tried changing the audio source: `recorder.setAudioSource(MediaRecorder.AudioSource.MIC);` See answer here: http://stackoverflow.com/a/23522046/2543138 – brwngrldev Aug 22 '14 at 02:11
  • @adavis - it still gives me error if I change it to recorder.setAudioSource(MediaRecorder.AudioSource.MIC); Any ways I want to record call in background, through MIC recording voice is not clear. – Deep Aug 23 '14 at 00:20

1 Answers1

0

I was able to record call by using actual phone to run the app with Throwable Try , catch block around it, the error still occurs but am able to by pass it on actual phone.

try { recorder.start();
}catch (Throwable t) {
t.printStackTrace();
Log.w("TEST", t);

NOTE: On Emulator call recieving will not work and keeps giving the error even if you put try catch block with Throwable.

Deep
  • 11
  • 3