I want to save .3gp files permanently in Android. I wrote methods for this but if I close the app and restart it, my app crashes when I try to play my recorded sound.
Here's my record-method(note that I have to code the path this way since API 29):
public void startRecording(){
try {
f = new File(getExternalFilesDir(null), "recorded.3gp");
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);;
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
mediaRecorder.setOutputFile(f.getAbsolutePath());
mediaRecorder.prepare();
mediaRecorder.start();
} catch (IOException e) {
e.printStackTrace();
}
}
My stop-method:
public void stopRecording(){
try {
mediaRecorder.stop();
mediaRecorder.release();
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
My play-method:
public void playRecord(){
MediaPlayer mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(f.getAbsolutePath());
mediaPlayer.prepare();
mediaPlayer.start();
} catch (IOException e) {
e.printStackTrace();
}
}
In which folder can I find these recordings? I wanna get access later from app.
Thx
Related
I am busy developing a APP On Android Studio using the Flutter framework, that functions as follows,
The user can press press a button and it will take a picture without opening the camera view.
I have a MethodChannel between my Dart/Flutter and Android.Java ,I am able to press the button and the app takes a pic and saves it to gallery.
The issue I am having is that it closes the app afterwards with no error.
Could you please have a look at my code and see if you can help me.
MainActivity.Java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
new MethodCallHandler() {
#Override
public void onMethodCall(MethodCall call, Result result) {
if(call.method.equals("test"))
{
StartCameraFrontCamera();
}
else {
result.notImplemented();
}
}
});
}
public void StartCameraFrontCamera()
{
File directory = new File(Environment.getExternalStorageDirectory() + "/PicturesTest/");
if (!directory.exists()) {
directory.mkdir();
}
try {
ReleaseCamera();
mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
} catch (Exception e) {
Log.e(getString(R.string.app_name), "failed to open Camera");
e.printStackTrace();
}
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPictureFormat(ImageFormat.JPEG);
mCamera.setParameters(parameters);
SurfaceView mview = new SurfaceView(this);
SurfaceTexture surfaceTexture = new SurfaceTexture(0);
imageName = "fontcamera.jpg";
try{
//mCamera.setPreviewDisplay(mview.getHolder());
mCamera.setPreviewTexture(surfaceTexture);
//mCamera.setPreviewDisplay(null);
mCamera.startPreview();
mCamera.takePicture(null,null,photoCallback);
//mCamera.stopPreview();
}catch(IOException e) {
e.printStackTrace();
}
}
Camera.PictureCallback photoCallback=new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
try {
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/PicturesTest");
File file = new File (myDir, "image1.jpg");
FileOutputStream out = new FileOutputStream(file);
out.write(data);
out.flush();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e)
{
e.printStackTrace();
}
finish();
}
};
Background:
I am using three fragments and one activity in my application. Two fragments use recyclerViews and the other uses an expandableListView.
Problem:
I am trying to properly program the onPause(), onResume(), onStop(), and onRestart() methods to save the state of my application when the home, back, or switch views buttons are pressed.
To save the state of the program and load it when it comes back I have created the save() and load() methods in my one and only activity.
//from the end of onCreate
load();
}
#Override
protected void onStart() {
super.onStart();
mRef = new Firebase("https://sure-7856d.firebaseio.com/");
}
#Override
protected void onStop(){
super.onStop();
save();
}
#Override
protected void onPause(){
super.onPause();
save();
}
#Override
protected void onResume(){
super.onResume();
load();
}
#Override
protected void onRestart(){
super.onRestart();
load();
}
In the save method I get the adapters from my 2 recyclerViews and my expandableListView`s ArrayList that keeps track of which checkboxes are checked.
After that I put them each into a temporary Arraylist then I add each of those ArrayLists to a single arraylist that will be saved to the file.
private void save(){
//saved_data = new File("saved_data");
/*try {
if(saved_data.exists()==false){
//saved_data.createNewFile();
saved_data.setWritable(true);
}
} catch (IOException e) {
e.printStackTrace();
}*/
File myFile;
try{
myFile = new File(getFilesDir().getAbsolutePath(), "dir/save_data.bin");
myFile.mkdirs();
myFile.createNewFile();
FILENAME = myFile.getName();
}catch (IOException e){
e.printStackTrace();
}
OneFragment f20 = (OneFragment) frags.get(0);
TwoFragment f21 = (TwoFragment) frags.get(1);
ThreeFragment f22 = (ThreeFragment) frags.get(2);
ArrayList saveTasks = f20.adapter.getList();
ArrayList saveReqs = f21.adapter.getList();
ArrayList saveMap = new ArrayList<String>();
if(f22.listAdapter!=null) {
if (f22.listAdapter.getExport() != null) {
saveMap = f22.listAdapter.getExport();
}
}
ArrayList results = new ArrayList();
results.add(saveTasks);
results.add(saveReqs);
results.add(saveMap);
ObjectOutputStream oos1 = null;
FileOutputStream fos1 = null;
try {
fos1 = openFileOutput(FILENAME, Context.MODE_PRIVATE);
oos1 = new ObjectOutputStream(fos1);
oos1.writeObject(results);
oos1.close();
fos1.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(oos1 != null){
try {
oos1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
In the load code I get the object from the file and update the adapters to their previous state.
private void load(){
//saved_data = new File("saved_data");
ArrayList results = new ArrayList();
FileInputStream fis = null;
ObjectInputStream ois = null;
if(FILENAME==null){
return;
}
try {
fis = new FileInputStream(FILENAME);
ois = new ObjectInputStream(fis);
}catch (FileNotFoundException e) {
e.printStackTrace();
return;
}catch (IOException e) {
e.printStackTrace();
}
try {
while (true) {
results = (ArrayList)(ois.readObject());
}
} catch (OptionalDataException e) {
if (!e.eof) try {
throw e;
} catch (OptionalDataException e1) {
e1.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
ois.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
for(int i = 0; i < results.size();i++){
if(i == 0){
frags.set(0,results.get(i));
}
else if(i == 1){
frags.set(1,results.get(i));
}
else if(i == 2){
frags.set(2,results.get(i));
}
else{
}
}
}
When I press the square button at the bottom of the emulator and go back to it one of a few things happen
It crashes saying the file could not be found
W/System.err: Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
And this error points to the load method as the point of failure specifically
FileInputStream fis = null;
When I hit the triangle button nothing happens in logcat, everything is gone upon returning, and the app loses its functions of adding strings to lists on both recyclerViews and displaying both lists in the expandableListView.
Hitting the center circle button and going back to the app is fine nothing breaks.
Since Im getting a file not found error I think that the file isnt getting written
I have searched Stack for a solution and I am new to File IO and fragments, so I have no idea where to go from here.
so I'm implementing like music playlist app, my audios are uploaded to Parse.com as mp3 , I want to retrieve those audios ..
final Button btn = (Button) v.findViewById(R.id.button);
final ParseFile fileObject = object.getParseFile("music");
if (fileObject != null) {
fileObject.getDataInBackground(new GetDataCallback() {
#Override
public void done(byte[] bytes, com.parse.ParseException e) {
final String audioFileURL = fileObject.getUrl();
mediaPlayer = new MediaPlayer();
mediaPlayer.reset();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
btn.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
try {
mediaPlayer.setDataSource(audioFileURL);
mediaPlayer.prepare();
mediaPlayer.start();
} catch (IllegalArgumentException e1) {
e1.printStackTrace();
}//end catch
catch (IOException e1) {
e1.printStackTrace();
}
}//end on click
}//end listener
);
}//end done
});//end get data
}//end if
this is how I retrieve music from Parse.com but this is taking so much time specially that I have a list of audios .. I want a way to download group of the audios in the background .. so when I click the button, the music play so fast .. any help would be greatly appreciated.
I have no time right now to understand why your code doesn't work, but you can take my sample app on github (committed just now), you should solve your problem...if not, let me know. Please, take note of the README.md
https://github.com/fullwipe/ParseAudioFileExample
Hope it helps...
Edit This is the essential part of my repository. Record and save:
String outputFile = Environment.getExternalStorageDirectory().
getAbsolutePath() + "/rumor.mp3";
myRecorder = new MediaRecorder();
myRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
myRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
myRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
myRecorder.setOutputFile(outputFile);
Then, start recording...
try {
myRecorder.prepare();
myRecorder.start();
} catch (IllegalStateException e) {
// start:it is called before prepare()
// prepare: it is called after start() or before setOutputFormat()
e.printStackTrace();
} catch (IOException e) {
// prepare() fails
e.printStackTrace();
}
When you stop recording, save it on Parse.com in this way:
FileInputStream fileInputStream = null;
File fileObj = new File(outputFile);
byte[] data = new byte[(int) fileObj.length()];
try {
//convert file into array of bytes
fileInputStream = new FileInputStream(fileObj);
fileInputStream.read(data);
fileInputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
ParseFile parseAudioFile = new ParseFile("audiofile.mp3", data);
parseAudioFile.saveInBackground();
ParseObject parseObject = new ParseObject("AudioFileClass");
parseObject.put("audiofile", parseAudioFile);
parseObject.saveInBackground(new SaveCallback() {
public void done(ParseException e) {
if (e == null) {
Toast.makeText(getApplicationContext(),"Audio file saved successfully", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(),"Error: audio file not saved", Toast.LENGTH_SHORT).show();
}
}
});
Retrieve and play from Parse.com is very simple, I have used a ParseQueryAdapter. This is the part where you get the mp3 file and play it:
ParseFile descr = object.getParseFile("audiofile");
if (descr != null) {
String audioFileURL = descr.getUrl();
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mediaPlayer.setDataSource(audioFileURL);
mediaPlayer.prepare();
mediaPlayer.start();
}
...
...
I am using the MP4ParserMergeAudioVideo to add a new audio to an MP4 file. The library had said to use .wav file, if i keep a .wav file in the directory and give the name of the audiofile as example.m4a, I get a file not found exception. So I changed the file to a .m4a audio file. The code is given below.
findViewById(R.id.append).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
String root = Environment.getExternalStorageDirectory().toString();
Log.e("",""+root);
String audio = root + "/download/"+"mymovieaudio.m4a";
String video = root + "/download/"+"My_Movie.mp4";
String output = root + "/download/ouput.mp4";
mux(video, audio, output);
}
});
The mux function is like this
public boolean mux(String videoFile, String audioFile, String outputFile) {
Movie video;
try {
video = new MovieCreator().build(videoFile);
} catch (RuntimeException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
Movie audio;
try {
audio = new MovieCreator().build(audioFile);
} catch (IOException e) {
e.printStackTrace();
return false;
} catch (NullPointerException e) {
e.printStackTrace();
return false;
}
Track audioTrack = audio.getTracks().get(0);
video.addTrack(audioTrack);
Container out = new DefaultMp4Builder().build(video);
FileOutputStream fos;
try {
fos = new FileOutputStream(outputFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
}
BufferedWritableFileByteChannel byteBufferByteChannel = new BufferedWritableFileByteChannel(fos);
try {
out.writeContainer(byteBufferByteChannel);
byteBufferByteChannel.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
I successfully get the output.mp4 file in my download directory of my device. The problem is that it does not have any audio. Please help. Thanks in advance.
I want to use this MediaPlayer method from a number of fragment layouts.
How do I parse the raw resource ?
public void playSound(Uri path) throws IOException{
MediaPlayer player;
player = new MediaPlayer();
try {
player.setDataSource(path.getPath(), path);
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
}
player.prepare();
player.start();
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp){
mp.release();
}
});
}
I'm currently using this from my fragment to parse an mp3 file from the raw directory.
Btn_shou.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
Uri path = null;
switch (tone.getCheckedRadioButtonId())
{
case R.id.radioTone1:
path = Uri.parse("android.resource://" +getActivity().getApplicationContext().getPackageName() +"/"+R.raw.shou1);
try {
playSound(path);
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
break;
There's a problem with the 'path' variable. Android complains it cannot find the mp3 file.
I finally fixed this by :
Create my separate MediaPlayer class.
package com.example.FragmentTabsTutorial;
import android.content.Context;
import android.media.MediaPlayer;
import android.net.Uri;
import java.io.IOException;
public class plaSnd {
public void playSound(Uri path, Context context) throws IOException {
MediaPlayer player;
player = new MediaPlayer();
try {
player.setDataSource(context, path);
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
}
player.prepare();
player.start();
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
mp.release();
}
});
}
}
2.) From my fragment I created an object to plaSnd() class:
final plaSnd pla = new plaSnd();
3.) Created a variable to store context:
final Context context = getActivity().getApplicationContext();
4.) Set my path variable according to which button is clicked then parse 'context' and 'path' to my playSound() method in 'plaSnd' class:
Btn_o.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
Uri path = null;
switch (tone.getCheckedRadioButtonId())
{
case R.id.radioTone1:
path = Uri.parse("android.resource://" +getActivity().getApplicationContext().getPackageName() +"/"+R.raw.o1);
try {
pla.playSound(path, context);
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
break;
This has worked for me though I'm sure there's probably a better solution...
Try replacing this:
player = new MediaPlayer();
with this:
// context should be any context, e.g. your activity or getApplicationContext()
player = MediaPlayer.create(context, R.raw.shou1);