I'm from Taiwan and my English is pretty basic, thanks for your forgiveness.
I built a iPad app and published to App Store, which is a kind of communicating board (AAC for the person who has difficult on speaking). It has several buttons on main view and when user touch up one, the app will play a mp3 sound corresponding to that button. I've put all mp3 files on a folder and determining which one to play dynamically at run-time.
Recently I'm working on build the Android version of this app, but I meet a problem that is when I touch up one button on the view, the MediaPlayer play not only the corresponding one but keep playing all the rest mp3 files on the folder continuously. It doesn't happen on the development of iPad version. Any one can help me to resolve this problem and set the MediaPlayer up to working appropriately?
PS. I put all MP3 files on some sub-folders and put them on the "assets" folder. It because for some reasons, all mp3 files are using numeric file name (ex. 0123223.mp3), and which MP3 to play is according to which button user touched up, so I can't use R.raw.0123223 not only because the R class can't has a member named in numeric, but also the target mp3 file can only determining at run-time instead of compile-time, so I can't use the res/raw folder.
My code is as following:
private void PlayMP3(String mp3File) throws IOException {
AssetFileDescriptor afd = this.getAssets().openFd(mp3File);
MediaPlayer player = new MediaPlayer();
player.setOnCompletionListener(new OnCompletionListener(){
public void onCompletion(MediaPlayer mp) {
System.out.println(mp.getAudioSessionId() + " finished.");
}
});
player.setDataSource(afd.getFileDescriptor());
player.setLooping(false);
player.prepare();
player.start();
}
the parameter "mp3file" of PlayMP3 is a concatenated string of mp3 file path, according to the button user touched up.
Many thanks!
Your version would work if you had only that one file in the assets directory. The asset directory contents are put together one after another. So, if you do not specify where to start and how many bytes to read, the player will read up to the end as if they are one file.
You can accomplish what you want by using setDataSource with more arguments:
player.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
This will allow you to define the limits of the player and only play the song you specify in your string mp3File.
You did not post some code.
First step is to insert your sound file into the raw folder
Then, you need only a few lines of code:
MediaPlayer mediaPlayer = null;
mediaPlayer = MediaPlayer.create(getBaseContext(), R.raw.mysoundfile);
mediaPlayer.start();
When the application is closing, dont forget to "release" your media player:
mediaPlayer.release();
mediaPlayer = null;
Related
I completed my first app and could not publish it because the file size was to big (lots of sound files). I followed the Play Asset Delivery (https://developer.android.com/guide/app-bundle/asset-delivery/build-native-java) and it looks I got everything configured correctly (it builds and app loads but no sounds) but need help pointing to the sound files in the code. The sound files were in res>raw are now in assetpack\src\main\assets
When the sound files were in res>raw. I used this code to point to the sound file
if (sound == 1) { mp = MediaPlayer.create(this#MainActivity, R.raw.sound_1) }
Now I cannot point to the sound files in assets and I think its because it does not see it or knows that the folder exist.
When I change the left panel view to Project I see the list below and assetpack is there
Project
App name
.gradle
.idea
app
assetpack
build
gradle
play-core-native-sdk
other files
When I change the left panel view to Android I see the below list and assetpack is not part of it
Android
app
manifests
java
java (generated)
cpp
res
raw
I don't understand how this works and tried searching here and google with no help
Can you help me point to assetpack\src\main\assets sound files?
Thanks!
You can use the following code to play a specific audio file (i.e your_file.mp3) in your assets folder with:
MediaPlayer mediaPlayer = new MediaPlayer();
AssetFileDescriptor afd = context.getAssets().openFd("your_file.mp3");
mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
afd.close();
mediaPlayer.prepare();
mediaPlayer.start();
I am new to android. I am going to develop a simple mp3 application. There will be some mp3 tones in my app. I want to play the tones on click in the list item. Now my question is Which is the best way to store the mp3 files in my app.
1) SQLite
2) XML
3) folder
Please let me some good idea to me.
Thanks in advance.
You have to store them in a folder. There must be any resource the sqlite entrys refer to, because this is just a database. So storing them in a folder is not a question I think...
And XML is used to define UI Things like the interface.
This is because of the Model-View-Controller pattern if you want to know more about that look here
If you safed it in the raw folder(it´s located in the res folder, if you dont have one-> create one) of your project than this should be suitable for you
MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1);
mediaPlayer.start();
If you got it somewhere else this should fit your needs
Uri myUri = Uri.parse("/path/to/file.mp3"); // initialize Uri here
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(getApplicationContext(), myUri);
mediaPlayer.prepare();
mediaPlayer.start();
For more informations about MediaPlayer see here and here
I have an expansion file with a series of sound files. The longer ones are .mp3 files while the shorter sound effects are .wav files. I pack them in a .zip file with no compression. I use the Zip File reader and downloader library provided by Google.
I'm opening the sound files like so:
MediaPlayer mPlayer;
...
AssetFileDescript asd = expansionFile.getAssFileDescriptor(fileName);
FileDescriptor soundFile = asd.getFileDescriptor();
mPlayer = new MediaPlayer();
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mPlayer.setDataSource(soundFile);
mPlayer.prepare();
mPlayer.start();
The odd thing is that it plays the same sound file every single time. It seems to be whatever it finds first. The byte size for asd.getDeclaredLength() and asd.getLength() is exactly what it should be. This means the file descriptor is at least finding the file, but for some reason the MediaPlayer plays whatever random file it decides.
What exactly am I missing here? Any help would be greatly appreciated.
Thanks.
The first approximation is correct, except for when the zip file contains more than one file, then you should use:
mPlayer.setDataSource(asd.getFileDescriptor(), asd.getStartOffset(), asd.getLength());
You can get more information from this other question:
Play audio file from the assets directory
Please, also remember to close the AssetFileDescriptor just after setDataSource to media player:
asd.close();
http://developer.android.com/reference/android/media/MediaPlayer.html#setDataSource%28java.io.FileDescriptor,%20long,%20long%29
Hi there I'm an android and java newbie and is wondering if there is a better way of doing the following:
I currently have 250 short audio files (.3gp) that i put inside my res/raw folder and based on a certain condition, I want to play certain audio file. For example if the text of the button that is being clicked is the word "and", I want to play the and.3gp sound file.
The following is the code that I use to accomplish what I want to do:
if(word.equals("No"))
{
MediaPlayer mp = MediaPlayer.create(HomeActivity.this,R.raw.no);
mp.start();
mp.setOnCompletionListener(listener );
}
else if(word.equals("And"))
{
MediaPlayer mp = MediaPlayer.create(HomeActivity.this,R.raw.and);
mp.start();
mp.setOnCompletionListener(listener );
}
.....
The above code is working fine so far but I'm wondering if I can do this without having a 250 else if condition. Is there a way to pass in the audio file to MedialPlayer.Create by file name via Uri? If yes, how do I do it? Thank you.
You can make a hash function that maps a string key to the uri
Loop through all your files in your raw folder and remove the file extension, then test against that.
I'm new in Java/Android programming, so please have patience with me.
I try to play a mp3 which is locate und the assets folder. I know there is another way with the /res/raw/ folder, but use the assets-folder because later I'll try to access the file by String.
This code works to play a mp3-file:
try
{
MediaPlayer mp = new MediaPlayer();
FileDescriptor sfd = getAssets().openFd("song.mp3").getFileDescriptor();
mp.setDataSource(sfd);
mp.prepare();
mp.start();
}
catch(Exception e) {}
Now the problem: In the same assets-folder is another mp3 file stored. Though I specify the name of the mp3 to use it take the one which comes first in alphabet. E.g. the other file is named "music.mp3" it plays this one. Renaming it to "worldmusic.mp3" it will play "song.mp3". Rerename "worldmusic.mp3" back to "music.mp3" it will take this mp3 again. Another test: Renaming "song.mp3" to something other so the application can find whats specify by the code above will result that no song is played. So this means the songname have to exist, although it take arbitrary the song first in alphabet.
I'm testing with the AVD emulator of eclipse. But I think the behaviour would be the same on a real device.
Have someone an idea about this problem?
I don't believe using FileDescriptor is the right way to do this. Try using .create() and a Uri instead:
MediaPlayer mp = MediaPlayer.create(getBaseContext(), songUri);
mp.start();
Not sure why, but the URI syntax doesn't seem to work for the assets. Try getting the AssetFileDescriptor instead, as answered in the related question:
Play audio file from the assets directory