I can only record my voice from this code, not against the turns.
And I used MediaRecorder.AudioSource.VOICE_CALL instead of MediaRecorder.AudioSource.MIC
But still I am getting my voice only.
Here is my code
public class RecorderService extends IntentService {
private Context mContext;
private MediaRecorder recorder;
static final String TAGS = "RecorderService";
private String phoneNumber;
public RecorderService() {
super("RecorderService");
}
#Override
protected void onHandleIntent(Intent intent) {
}
#Override
public int onStartCommand(#Nullable Intent intent, int flags, int startId) {
Log.e(TAGS, "Started!");
mContext = getApplicationContext();
phoneNumber = intent.getStringExtra("number");
Log.e(TAGS, "Calling Number : " + phoneNumber);
recorder = new MediaRecorder();
startRecording();
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.e(TAGS, "Stopped!");
stopRecording();
}
private void startRecording() {
Log.e(TAGS, "Recording Started");
File file = new File(Environment.getExternalStorageDirectory()
+ File.separator
+ "My Records"
+ File.separator);
recorder.reset();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
recorder.setOutputFile(file.getAbsolutePath() + "record.mp3");
try {
recorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
recorder.start();
}
private void stopRecording() {
Log.e(TAGS, "Recording Stopped");
if (recorder != null) {
recorder.stop();
recorder.reset();
recorder.release();
recorder = null;
}
}
}
Any suggestions!
You can't. Not unless you're a system app (which you need to be installing your own custom OS or be root to get). VOICE_CALL requires the CAPTURE_AUDIO_OUTPUT permission which is a system permission- normal apps can't use it.
How do the other apps on the Play store do it? They use the mic, and hope the output of the call is loud enough to pick it up.
Related
Hi I am making call recorder application. In my app I am allowing user to record call. and then recording will be saved in directory. But right now I am facing one issue in my application. after making call if I check in saved recordings, only my voice is I can listen, call receiver's voice is not recording. can any one help me to solve this issue?
public class RecorderService extends Service {
MediaRecorder recorder;
static final String TAGS=" Inside Service";
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
public int onStartCommand(Intent intent,int flags,int startId)
{
recorder = new MediaRecorder();
recorder.reset();
String phoneNumber=intent.getStringExtra("number");
Log.d(TAGS, "Phone number in service: "+phoneNumber);
String time=new CommonMethods().getTIme();
String path=new CommonMethods().getPath();
String rec=path+"/"+phoneNumber+"_"+time+".mp4";
recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
recorder.setOutputFile(rec);
try {
recorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
recorder.start();
Log.d(TAGS, "onStartCommand: "+"Recording started");
return START_NOT_STICKY;
}
public void onDestroy()
{
super.onDestroy();
recorder.stop();
recorder.reset();
recorder.release();
recorder=null;
Log.d(TAGS, "onDestroy: "+"Recording stopped");
}
}
First time when i run this code it runs fine but when i pause and play it again mainthread stop for more than or equal to 20 second and then show ANR dialog and after that it didn't start again.Reviewed this code many time but not able to debug.I also comment startRecording() and stopRecording() but after that it runs okay i.e, the problem is in starting and stopping the service.
public class RecordingService extends Service {
private String filePath = null;
private String dateSuffix = null;
private MediaRecorder mediaRecorder = null;
private DatabaseHelperClass databaseHelperClass;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
databaseHelperClass = new DatabaseHelperClass(getApplicationContext());
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
startRecording();
return START_STICKY;
}
#Override
public void onDestroy() {
stopRecording();
super.onDestroy();
}
private void stopRecording() {
try {
if (mediaRecorder != null) {
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder = null;
}
}
catch (IllegalStateException e){
}
}
private void startRecording() {
if (mediaRecorder != null)
mediaRecorder.release();
pathCreater();
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mediaRecorder.setAudioChannels(1);
mediaRecorder.setOutputFile(filePath);
try {
mediaRecorder.prepare();
mediaRecorder.start();
} catch (IOException e) {
e.printStackTrace();
}
}
private void pathCreater() {
String fileName;
File file;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MMM MM dd, yyyy h:mm a");
long date = System.currentTimeMillis();
dateSuffix = simpleDateFormat.format(date);
do {
fileName = getString(R.string.file_name_suffix) + "_" + dateSuffix + ".mp3";
filePath = Environment.getExternalStorageDirectory().getAbsolutePath();
filePath += "/" + fileName;
file = new File(filePath);
} while (file.exists() && !file.isDirectory());
}
}
I am creating a background audio recorder using Service class. When I start recording it works fine but when I stop it, it throws IllegalStateException on onStop().
Here is my Service Class Code:
public class AudioRecorderService extends Service {
MediaRecorder mAudioRecorder;
String fileName = null;
public AudioRecorderService() {
}
#Override
public void onCreate() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
setupRecorder();
Toast.makeText(this, "Recording Started", Toast.LENGTH_LONG).show();
return START_STICKY;
}
private void setupRecorder(){
fileName = Environment.getDataDirectory().getAbsolutePath() + "/" + "test.mp4";
mAudioRecorder = new MediaRecorder();
mAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mAudioRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mAudioRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mAudioRecorder.setAudioEncodingBitRate(256);
mAudioRecorder.setAudioChannels(1);
mAudioRecorder.setAudioSamplingRate(44100);
mAudioRecorder.setOutputFile(fileName);
try {
mAudioRecorder.prepare();
mAudioRecorder.start();
} catch (IOException e) {
e.printStackTrace();
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
if (mAudioRecorder != null) {
mAudioRecorder.stop();
mAudioRecorder.reset();
mAudioRecorder.release();
}
Toast.makeText(this, "Recording Done", Toast.LENGTH_LONG).show();
}
}
I am unable to figure out what's wrong with the code. Please can anyone help????
While starting and stopping it should be in this order. Incase of any errors notification is necessary
MediaRecorder recorder = null;
private void startRecording(File file) {
if (recorder != null) {
recorder.release();
}
recorder = new MediaRecorder();
recorder.setAudioSource(AudioSource.MIC);
recorder.setOutputFormat(OutputFormat.THREE_GPP);
recorder.setAudioEncoder(AudioEncoder.AMR_WB);
recorder.setOutputFile(file.getAbsolutePath());
try {
recorder.prepare();
recorder.start();
} catch (IOException e) {
Log.e("Error", "io problems while preparing [" +
file.getAbsolutePath() + "]: " + e.getMessage());
}
}
Now java.lang.IllegalStateException
Happens when you do not follow the order above, miss some important steps or when prepare() failed, but you continue anyway. The latter is where it is most likely to go wrong. You should only call start() when prepare() did exit without exceptions. Otherwise you will get an IllegalStateException. Since it is a RuntimeException you might not catch it and your app will force close.
While stopping follow this order
private void stopRecording() {
if (recorder != null) {
recorder.stop();
recorder.release();
recorder = null;
}
}
and last but not the lease in Manifest , the permission
<uses-permission
android:name="android.permission.RECORD_AUDIO" />
You are getting error because of mAudioRecorder.reset();
#Override
public void onDestroy() {
if (mAudioRecorder != null) {
mAudioRecorder.stop();
// here is error
mAudioRecorder.reset();
mAudioRecorder.release();
}
Toast.makeText(this, "Recording Done", Toast.LENGTH_LONG).show();
}
Update it.:
#Override
public void onDestroy() {
if (mAudioRecorder != null) {
mAudioRecorder.stop();
mAudioRecorder.release();
}
Toast.makeText(this, "Recording Done", Toast.LENGTH_LONG).show();
}
Refer official site : https://developer.android.com/guide/topics/media/audio-capture.html
I have added these 2 permissions on AndroidManifest.xml and it won't crash anymore.
P/S: The App will ask for your permission for recording the audio when upon starting it.
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
Am trying to write an app that reads from the microphone and where I, in the same app, write the results/buffer myself to my own file (in a separate thread). Believe me I have Googled till my fingers were numb. But I am having a problem with the whole "callback" part.
Whether it's the onPeriodicNotification or onMarkerReached part, I just can't seem to get it right. Not looking for anyone to write it for me, but if I could just find the proper shell online, I could do it myself.
So if anyone knows of a good example, please.
Made a simple Sound Manager in which you can record sound :
public class SoundManager {
private static final String TAG = SoundManager.class.getSimpleName();
public boolean isRecording = false;
private MediaRecorder recorder;
private String audioFileName = "sound";
private Context mContext;
private String storePath;
public SoundManager(Context context) {
this.mContext = context;
}
public void onRecord(boolean toStart) {
if (toStart) {
try {
startRecording();
isRecording = true;
} catch (IOException e) {
Log.d("Tag", e.toString());
}
} else {
stopRecording();
}
}
private void startRecording() throws IOException {
stopRecording();
audioFileName = UUID.randomUUID().toString();
storePath = new File(mContext.getExternalFilesDir(null), "/images/"+ audioFileName+".3gp").getAbsolutePath();
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
recorder.setOutputFile(storePath);
recorder.prepare();
recorder.start();
}
private void stopRecording() {
if (isRecording && recorder != null) {
try {
recorder.stop();
recorder.release();
} catch (RuntimeException e) {
recorder.release();
Log.d(TAG, e.toString());
}
recorder = null;
isRecording = false;
}
}
public File getAudioOutputPath() {
return new File(storePath);
}
}
Uses:
Start Record : soundManager.onRecord(true);
Stop Record : soundManager.onRecord(false);
get sound file path : soundManager.getAudioOutputPath();
Add audio permission in your Manifest:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
`
Recorder = new MediaRecorder();
Recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
Recorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
Recorder.setOutputFile(FileName);
Recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
this is my Code and i am not able to record the voice of other person.so what should i use instead of AudioSorce.MIC.
plz help me
Sorry to disappoint you, but you can't, not in the general case. Most Android running phones have the wiring in hardware/firmware so that the media of the call does not pass through the application processor at all - it goes from the audio to the DSP and vice versa, so you cannot access it.
You can catch the audio of the person using the phone, but not the other way around, disregarding silly hacks like asking the person to use the speakers and recording the sound from there via the phone mic...
class MyPhoneStateListener extends PhoneStateListener implements SensorEventListener {
Context context;
AudioManager audioManager;
MediaRecorder recorder;
private SensorManager mSensorManager;
private Sensor myLightSensor;
private boolean CallState;
private float sensorState;
public MyPhoneStateListener(Context context) {
this.context = context;
mSensorManager = (SensorManager) this.context.getSystemService(Context.SENSOR_SERVICE);
myLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
audioManager = (AudioManager) this.context.getSystemService(Context.AUDIO_SERVICE);
if (myLightSensor == null){
Log.i("On Receive", "Not Support");
}else{
mSensorManager.registerListener(this,myLightSensor,SensorManager.SENSOR_DELAY_NORMAL);
}
}
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
System.out.println("My Call IDLE");
CallState = false;
StartAudioSpeacker();
StopRecording();
System.out.println("Is phone speaker : "+ audioManager.isSpeakerphoneOn());
if (audioManager.isSpeakerphoneOn()) {
audioManager.setSpeakerphoneOn(false);
mSensorManager.unregisterListener(this);
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
System.out.println("My Call OFFHOOK");
CallState = true;
StartAudioSpeacker();
StartRecording();
System.out.println("Is phone speaker : "+ audioManager.isSpeakerphoneOn());
break;
case TelephonyManager.CALL_STATE_RINGING:
System.out.println("My Call RINGING");
break;
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
if (sensor.getType() == Sensor.TYPE_PROXIMITY) {
Log.i("Sensor Changed", "Accuracy :" + accuracy);
}
}
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_PROXIMITY) {
Log.i("Sensor Changed", "onSensor Change :" + event.values[0]);
sensorState = event.values[0];
StartAudioSpeacker();
}
}
public void StartAudioSpeacker(){
if (CallState && sensorState == 1.0) {
audioManager = (AudioManager) this.context.getSystemService(Context.AUDIO_SERVICE);
audioManager.setSpeakerphoneOn(true);
audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC,AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);
audioManager.setStreamVolume(AudioManager.MODE_IN_CALL, audioManager.getStreamMaxVolume(AudioManager.MODE_IN_CALL), 1);
System.out.println("Is phone speaker : "+ audioManager.isSpeakerphoneOn());
}else{
audioManager = (AudioManager) this.context.getSystemService(Context.AUDIO_SERVICE);
audioManager.setSpeakerphoneOn(false);
audioManager.setStreamVolume(AudioManager.MODE_IN_CALL, audioManager.getStreamMaxVolume(AudioManager.MODE_IN_CALL), 1);
System.out.println("Speaker Volume :"+ audioManager.getStreamMaxVolume(AudioManager.MODE_IN_CALL));
System.out.println("Is phone speaker : "+ audioManager.isSpeakerphoneOn());
}
}
public void StartRecording(){
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(this.getFullSdPath());
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 is now started
Log.i(this.getClass().getName(), "Start Recording");
}
public void StopRecording(){
recorder.stop();
recorder.reset();
recorder.release();
Log.i(this.getClass().getName(), "Stop Recording");
}
public String getFullSdPath(){
File sdCard = new File(Environment.getExternalStorageDirectory() + "/RecordMyVoice");
if (!sdCard.exists()) {
sdCard.mkdir();
}
File file = new File(Environment.getExternalStorageDirectory()+"/RecordMyVoice/",new Date().getTime()+".3gp");
System.out.println("Full path of record sound is : "+file.getAbsolutePath());
return file.getAbsolutePath();
}
}
As I known and I have finshed this kind of job.I mean both the user's voice and the other people's voice.We used the customized ROM of one phone provided by the specificated factory and they also have modificated some security mechanism of the ROM.Another way you can try this:
https://github.com/FR13NDS/call-recorder-for-android
Try This code to record call.
AudioManager audioManager;
private MediaRecorder myAudioRecorder;
//Myservice m=new Myservice();
private String outputFile = null;
String uid=null;
String no=null;
String rname=null;
public void record(Context c,String no, String ser){
try{
this.no=no;
uid=ser;
rname=String.format("%d.mp3", System.currentTimeMillis());
//rname="/#"+uid+"#"+rname;
outputFile = Environment.getExternalStorageDirectory().toString() + "/Android/free"+"/#"+uid+"#"+no+"#"+rname;
StartAudioSpeacker();
myAudioRecorder=new MediaRecorder();
myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
myAudioRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
myAudioRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
myAudioRecorder.setOutputFile(outputFile);
}catch(IllegalStateException e){e.printStackTrace();}
try {
myAudioRecorder.prepare();
myAudioRecorder.start();
} catch (IllegalStateException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void getc(Context c) {
// TODO Auto-generated method stub
this.c=c;
}
public void st()
{ //Toast.makeText(;, "recorded",Toast.LENGTH_LONG).show();
try{
myAudioRecorder.stop();
myAudioRecorder.release();
myAudioRecorder=null;
}
catch(IllegalStateException e)
{
e.printStackTrace();
}
Handler h=new Handler();
h.postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
try{
uprecord ur=new uprecord("/#"+uid+"#"+no+"#"+rname);
ur.tt();
}catch(IllegalStateException e){e.printStackTrace();} }
}, 1000);
}
public void StartAudioSpeacker(){
audioManager = (AudioManager) c.getSystemService(Context.AUDIO_SERVICE);
audioManager.setSpeakerphoneOn(false);
audioManager.setStreamVolume(AudioManager.MODE_IN_CALL, audioManager.getStreamMaxVolume(AudioManager.MODE_IN_CALL), 1);
System.out.println("Speaker Volume :"+ audioManager.getStreamMaxVolume(AudioManager.MODE_IN_CALL));
System.out.println("Is phone speaker : "+ audioManager.isSpeakerphoneOn());
}
}
I didnt try it on Phone, but according doc MediaRecorder.AudioSource you should use
MediaRecorder.AudioSource.VOICE_CALL
instead of
MediaRecorder.AudioSource.MIC
Hopes that works
If you are trying to store the audio file to sdcard, try this code. It will work fine.
protected void startRecording() {
mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
mFileName += "/audiorecordtest.3gp";
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setOutputFile(mFileName);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
mRecorder.prepare();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
mRecorder.start();
}
}