Converted blob to Mp3 but File is unplayable - java

This is my function for converting blob to mp3:
private void convertByyeToMP3(byte[] bytearray,String trackName) {
try {
ContextWrapper c = new ContextWrapper(getApplicationContext());
File directory = new File(c.getFilesDir().getAbsolutePath()
+ "/Music");
if (!directory.exists()){
directory.mkdir();
}
File tempMp3 = File.createTempFile(trackName, ".mp3",
directory);
FileOutputStream fos = new FileOutputStream(tempMp3);
fos.write(bytearray);
fos.close();
Log.d("Byte array to mp3 conversion: ", "successfull");
} catch (Exception ex) {
Log.d("In convertToByteToMp3 Function:", ex.toString());
}
}
When I execute this function ,I can see the created mp3 files in my app folder but when I try to play them Using my own code or using ES File Explorer, they both can't play it.
This is the function I use play my music:
private MediaPlayer mp = new MediaPlayer();
private void playSong(String songPath) {
try {
mp.reset();
mp.setDataSource(songPath);
mp.prepare();
mp.start();
} catch (IOException e) {
Log.v(getString(R.string.app_name), e.getMessage());
}
}
And I use this sample code to play the track:
ContextWrapper c = new ContextWrapper(getApplicationContext());
File directory = new File(c.getFilesDir().getAbsolutePath() + "/Music");
playSong(directory.getPath() + File.separator + "kurchina");
This is where I read database and send the blob:
cursor = mDbHelper.GetTables();
byte[] blob = null;
DATAS data = new DATAS();
while (cursor.moveToNext()) {
blob = cursor.getBlob(cursor.getColumnIndex("data"));
if (blob != null) {convertByyeToMP3(blob,data_MusicName);}
db.addDATAS(data);
}
FYIs:
-Read and Write permissions added to manifest.
-Path and filename are check and they exist
-blob byte is not corrupted

There are all sorts of things that might have gone wrong, either in the code that you have shown us or elsewhere. So you need to do your own troubleshooting. Methodically.
Figure out if the problem is with the song file you have extracted or the way you are playing it. For example, try to play the extracted file using a free-standing mp3 player utility.
Assuming that the problem is the extracted file, the next thing is to figure out if the file is the same as the one that you originally inserted into the database. Compare the file sizes and the checksums using the relevant external applications.
and so on.

Found the problem.
It didn't play because the music files were stored in my app folder which is only accessible using a rooted device.
When I copied the music to my sdcard they played well, but in my app folder using rooted nexus 7 I couldn't play it even with an mp3-player app.

Related

How to save an audio file in storage in Android Studio? [duplicate]

The android application I am working on; it has an option of audio-recording; I want it to save a new audio recorded file in internal storage of a device so that no neither user nor other applications will be able to access to those recorded audio files, unless they open my application.
My main struggle is to be able to save that audio file in internal storage: I took my time to review in my android programming books and read some questions and answers here : How to save an audio file in internal storage android and https://developer.android.com/guide/topics/data/data-storage#filesInternal and https://www.tutorialspoint.com/android/android_internal_storage.htm but unfortnately things I am getting from there are not settling my problem at all.
The codes that I am using to record are here below :
private MediaRecorder rec;
private String file_folder="/scholar/";
String
file_path=Environment.getExternalStorageDirectory().getPath();
File file= new File(file_path,file_folder);
Long date=new Date().getTime();
Date current_time = new Date(Long.valueOf(date));
rec=new MediaRecorder();
rec.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
rec.setAudioChannels(1);
rec.setAudioSamplingRate(8000);
rec.setAudioEncodingBitRate(44100);
rec.setOutputFormat(MediaRecorder.AudioEncoder.AMR_NB);
rec.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
if (!file.exists()){
file.mkdirs();
}
/*the file here this one:File file= new File(file_path,file_folder);
it means the value of the outputfile is the one which will be provided by
rec.setOutputFile() method, so it will be saved as this name:
file.getAbsolutePath()+"/"+"_"+current_time+".amr"
*/
rec.setOutputFile(file.getAbsolutePath()+"/"+"_"+current_time+".amr");
try {
rec.prepare();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(Recording_Service.this,"Sorry! file creation failed!",Toast.LENGTH_SHORT).show();
return;
}
rec.start();
rec.stop();
rec.reset();
Unfortunately what I am doing there, is saving my file on external storage, it means after recording, the file is visible to everyone in a device file explorer, they can even delete the file.
So! Please, I need your help guys, if any help, I will appreciate it. Thanks!
I had found the answer of this question, I used getFilesDir();
private MediaRecorder rec;
String file_path=getApplicationContext().getFilesDir().getPath();
File file= new File(file_path);
Long date=new Date().getTime();
Date current_time = new Date(Long.valueOf(date));
rec=new MediaRecorder();
rec.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
rec.setAudioChannels(1);
rec.setAudioSamplingRate(8000);
rec.setAudioEncodingBitRate(44100);
rec.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
rec.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
if (!file.exists()){
file.mkdirs();
}
String file_name=file+"/"+current_time+".3gp";
rec.setOutputFile(file_name);
try {
rec.prepare();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(Recording_Service.this,"Sorry! file creation failed!"+e.getMessage(),Toast.LENGTH_SHORT).show();
return;
}
rec.start();
rec.stop();
rec.reset();
Thanks for everyone who tried to help me for the answer. Let's continue to enjoy coding to make our world more sweet pleasant and enjoyable.

Android Studio :: Want to list files saved in default location

I'm new to Android Studio 3.0, emulating on a Nexus 4, Marshmallow. I'm trying to build simple "Save File" and "Load File" parts of my app. Here's the "Save File" part:
String filename = "myFile01"; // Then "myFile02", "myFile03", etc...
String userData = "Some useful data here...";
try {
// Adapted from: https://www.youtube.com/watch?v=_15mKw--RG0
FileOutputStream fileOutputStream = openFileOutput(filename, MODE_PRIVATE); // creates a file with given filename
fileOutputStream.write(userData.getBytes()); // puts userData into the file
fileOutputStream.close();
Toast.makeText(getApplicationContext(), "File saved!", Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
The above code will be called again and again as the user creates and saves additional files. Later, the user may want to view all the saved files and load one. I'll have a ListView displaying all the files... but I need help reading the current directory to get that list.
I thought I read somewhere that in Android, there's one flat directory for your app to save and retrieve files. So I was hoping if I saved a bunch of files and then called a read() method, all my saved files would simply be in the default directory, no need to search. That seems to be a bad assumption; here's why:
Here's my code looking in the default directory and listing all the files found within there. First, I need the path of said default directory:
// Get current directory adapted from: https://stackoverflow.com/questions/5527764/get-application-directory
String packName, currDir;
PackageManager m = getPackageManager();
packName = getPackageName();
PackageInfo p = null;
try {
p = m.getPackageInfo(packName, 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
currDir = p.applicationInfo.dataDir;
And then I open "currDir," and store the names of all the local files in an array:
// get list of files adapted from: https://stackoverflow.com/questions/9317483/showing-a-list-of-files-in-a-listview#9317583
File dir = new File(currDir);
File[] filelist = dir.listFiles();
String[] fileArr = new String[filelist.length];
for (int i = 0; i < fileArr.length; i++) {
fileArr[i] = filelist[i].getName();
}
The plan from here is to load the "fileArr" into a ListView and go from there. But when I step through the debugger, I see this as the contents of "fileArr":
"cache"
"code_cache"
"files"
This is true no matter how many files I've saved previously.
BTW, in the debugger, the assignments for packName and currDir look 100% correct:
packName = com.mydomain.myapp
currDir = /data/user/0/com.mydomain.myapp
So... I'm kinda assuming that my saved files are actually here:
/data/user/0/com.mydomain.myapp/files
And therefore, I should append this to my "get current directory" code:
// Get current directory adapted from: https://stackoverflow.com/questions/5527764/get-application-directory
String packName, currDir;
...everything from before...
currDir = p.applicationInfo.dataDir+"/files"; // <---- appending "+"/files"
Or am I way off? Any advice will be appreciated, thanks!
First of all, if you want to save your files in the app's directory, then you should call create a directory,
File directoryDefault = new File(Environment.DIRECTORY_DOCUMENTS, "YOUR_FOLDER_NAME");
if (!directoryDefault.exists()) {
directoryDefault.mkdir();
}
Then you have to save whatever files you have to save in the above mentioned default directory. Afterwards, when you want to list all the files available in that directory, you should call,
private ArrayList<String> fileNames() {
ArrayList<String> namesArray = new ArrayList<>();
File[] arrayFiles = directoryDefault.listFiles();
for (File file : arrayFiles) {
namesArray.add(file.getName());
}
return namesArray;
}

Edited ID3 tags not showing in windows explorer

I am working on a program that looks at an mp3 file and checks if it has it's ID3 data. If some data is missing it will query EchoNest (music database) for more data.
My problems is that when I update the ID3 tags Windows Explorer doesn't seem to recognize it (ie when the files are in the "Details" view the Artist, Title, Album columns are blank).
When I run my program a second time on the file my program finds the metadata just like it would find in a file that has all of it's data at first.
I am using the ID3 tag library found here:
http://javamusictag.sourceforge.net/
Is there something I am missing?
public void writeData(boolean pForce)
{
if (mIsUpdated || pForce)
{
try
{
File file = new File(mPath);
RandomAccessFile destFile = new RandomAccessFile(file, "rw");
ID3v1 tag = new ID3v1();
tag.setAlbum(mAlbum);
tag.setArtist(mArtist);
tag.setTitle(mTitle);
tag.write(destFile);
}
catch (FileNotFoundException ex)
{
System.out.println("No File Found At " + mPath);
}
catch (IOException ex)
{
System.out.println("Error when writting to file: " + mPath);
}
}
}
Just as a not I know that there are programs out there that do this same thing but I'm looking to add this as a function of my program. It's not so much about the functionality as it is about the learning how to make a program that does this.
Have you tried using ID3v2 tags, because when I was reading tags (with that library) from music files in windows, only v2 seemed to work. Hope it helps
EDIT:
If that doesn't work, I found this on another question using mp3agic: (the image stuff is to do with album artwork)
Mp3File song = new Mp3File(filename);
if (song.hasId3v2Tag()){
ID3v2 id3v2tag = song.getId3v2Tag();
byte[] imageData = id3v2tag.getAlbumImage();
//converting the bytes to an image
BufferedImage img = ImageIO.read(new ByteArrayInputStream(imageData));
}

download the files from Gdrive to local system by using java

Drive Quickstart: Run a Drive App in Java example works for uploading files fine. I want to download the files from Gdrive to local system by using java.
For download they are given a method
private static InputStream downloadFile(Drive service, File file) {
if (file.getDownloadUrl() != null && file.getDownloadUrl().length() > 0) {
try {
HttpResponse resp =
service.getRequestFactory().buildGetRequest(new GenericUrl(file.getDownloadUrl())).execute();
return resp.getContent();
} catch (IOException e) {
// An error occurred.
e.printStackTrace();
return null;
}
} else {
// The file doesn't have any content stored on Drive.
return null;
}
}
The above method,how can i give inputs? and from where i give the inputs? Can anyone give a complete code for download like Quickstart upload class.
any help will be appreciated.
you can use google drive api and send Http get request, you can see this tutorial
https://developers.google.com/drive/manage-downloads
Thanks Hanan it works fine.By using the retrieveAllFiles() i can list all the documents.And i have stored the retrieved documents in my local by using this below code.Is it a correct way to download.
for(File f:result){
i++;
System.out.println("File Name==>"+f.getTitle());
System.out.println("File Id==>"+f.getId());
System.out.println("File ext==>"+f.getFileExtension());
System.out.println("File size==>"+f.getFileSize());
InputStream in = downloadFile(service,f);
byte b[] = new byte[in.available()];
in.read(b);
java.io.File ff = new java.io.File("/home/test/Desktop/gdocs/"+f.getTitle());
FileOutputStream fout = new FileOutputStream(ff);
fout.write(b);
fout.close();
}
It stores all the documents in local. The text (.txt) files are open properly in my local, but the image files or pdf files are not open properly.It gives some error messages like file corrupted. There is no content in the image or pdf documents how can i get content and store it. Any suggestions

Can Android MediaPlayer play audio in a zipped file?

CODE EDITED:
I am developing a dictionary app for Android. I have been succeeding in making the app pronounce each word being looked up. Here is the code:
btnPronounce.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//Log.i(MAIN_TAG,"Start pronounciation ...");
btnPronounce.setEnabled(false);
String currentWord = edWord.getText().toString().toLowerCase();
try {
ZipFile zip = new ZipFile("/sdcard/app_folder/sound/zip_test.zip");
ZipEntry entry = zip.getEntry(currentWord);
if (entry != null) {
InputStream in = zip.getInputStream(entry);
// see Note #3.
File tempFile = File.createTempFile("_AUDIO_", ".wav");
FileOutputStream out = new FileOutputStream(tempFile);
IOUtils.copy(in, out);
// do something with tempFile (like play it)
File f = tempFile;
try {
if (f.exists())
{
Log.i(MAIN_TAG,"Audio file found!");
MediaPlayer mp = new MediaPlayer();
mp.prepare();
mp.setLooping(false);
mp.start();
while (mp.getCurrentPosition() < mp.getDuration());
mp.stop();
mp.release();
Log.i(MAIN_TAG,"Pronounciation finished!");
}
else
{
Log.i(MAIN_TAG,"File doesn't exist!!");
}
}
catch (IOException e)
{
Log.i(MAIN_TAG,e.toString());
}
btnPronounce.setEnabled(true); }
else {
// no such entry in the zip
}
} catch (IOException e) {
// handle your exception cases...
e.printStackTrace();
}
}
});
But the problem is that there are too many WAV files in one folder, and all these files are treated as music files by Android devices. As a result, it takes ages to index such files. In addition, indexing and user browsing sometimes force the app to crash.
Therefore, I just wonder if the following could be programmatically done:
Can Android MediaPlayer play WAV/MP3 files zipped or wrapped in a single file? I mean I want to zip or wrap the audio files (or do something alike) so that they appear as one single file to Android devices but MediaPlayer can still play each individual WAV file inside.
If the above is impossible, can you guys suggest a solution to the problem?
EDIT:
Are there any other ways/solutions that allow audio files to be simply put into one big file (an image, zip or the like...) and then let MediaPlayer read individual files in it?
Thank you very much.
You can use a combination of ZipFile or ZipInputStream and java.io file operations to read the necessary data from the zip, create temp files and play those using MediaPlayer.
Alternatively, you could just use a TTS engine and not pass out a 50-bagillion-byte APK.
Edit - Example by request:
try {
ZipFile zip = new ZipFile("someZipFile.zip");
ZipEntry entry = zip.getEntry(fileName);
if (entry != null) {
InputStream in = zip.getInputStream(entry);
// see Note #3.
File tempFile = File.createTempFile("_AUDIO_", ".wav");
FileOutputStream out = new FileOutputStream(tempFile);
IOUtils.copy(in, out);
// do something with tempFile (like play it)
} else {
// no such entry in the zip
}
} catch (IOException e) {
// handle your exception cases...
e.printStackTrace();
}
Notes:
I didn't include any safe file handling practices here. That's up to you.
This isn't the way to do it, only a way to do it. There are probably 100 other ways, some of which may be better suited to what you need. I didn't use ZipInputStream simply because there's a little more logic involved and I was going for brevity. You have to check every entry to see if it's what you're looking for with ZipInputStream, whereas ZipFile allows you to just ask for what you want by name. I'm not sure what (if any) performance implications using either over the other would have.
By no means are you required to use temp files (or files at all, really), but Android's MediaPlayer doesn't really like streams, so this is probably the easiest solution.
An alternative you should consider is to download the individual sound files when the user want to listen to a pronunciation. This should reduce the file size although it does mean that you can't listen to a pronunciation when there is no Internet.

Categories