Android event listeners for audio - android

I'm playing around with Android to learn the API and I'm trying to code an activity which can listen for changes in audio events. For example, the activity I created plays a random ringtone when you press a button. The button displays a text saying "Random Ringtone", but when you press the button it says "Stop" and pressing it will, of course, stop playing the ringtone.
However, the problem is that when the ringtone stops playing on its own, the button still says "stop".
I've looked around to try to find an event listener that could listen for when the ringtone stops playing, but I can't seem to find one. I've seen some info out there about creating your own listeners, but I'm not interested in doing that (a little advanced for me right now).
Does an event listener of this type exist?

I may be wrong but I think the only audio class which raises an event when it finishes playing is the MediaPlayer class. Something like this should work...
public class MyActivity extends Activity
implements MediaPlayer.OnCompletionListener {
MediaPlayer player = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
player = new MediaPlayer();
player.setOnCompletionListener(this);
...
}
#Override
public void onCompletion(MediaPlayer mp) {
// Called when playback is complete
...
}
}

Related

Android MediaController Play/Pause button and Seekbar doesn't Refresh

I am using MediaController.MediaPlayerControl in order to display a MediaController at the bottom of my Custom View but I can't get it to work properly. When I play music for first time then there should be pause button visible but instead there is play and when I press that button then the music is paused correctly and state remains the same and after that its working properly. Also when I play next song, the old MediaController widget gets overlapped with the new one. And sometimes the progress/seek bar doesn't refresh while the music is playing. It just updates itself when something on the MediaController is pressed (Play/Pause, forward, etc).
I found these questions similar to mine but I don't think the answers they got will solve my problem.
Android mediacontroller Play Pause controls not refresh properly
Android MediaController seekbar not refreshing
Android VideoView Playback Controls Show "Play" Initially Instead of "Pause" Even Though File is Already Playing
This is how I initialize the controller:
private void setController()
{
controller = new MusicController(this);
controller.setPrevNextListeners(new View.OnClickListener() {
#Override
public void onClick(View v) {
playNext();
}
}, new View.OnClickListener() {
#Override
public void onClick(View v) {
playPrev();
}
});
controller.setMediaPlayer(this);
controller.setAnchorView(findViewById(R.id.song_list));
controller.setEnabled(true);
}
This is how I show controller:
public void playMusic()
{
musicSrv.playSong(); //Play song in a service
setController();
controller.show(0);
controller.requestFocus();
}
I had exactly this problem. Don't know if you still need help, but I thought I'd post anyway. For posterity, are you following this tutorial?
First, the easy problem: you're getting multiple instances of your controls because of repeated calls to setController(). Change the first line of your function to:
if (controller == null) controller = new MusicController(this);
With regards to the play button malfunctioning, I believe it's because you're showing it before the music player has been prepared (disclaimer: I'm a newbie to Android myself, and the following are the things I've found to have worked).
Set up a broadcast from your music-playing service to notify your music-controlling activity when the musicplayer has been prepared. Append the following function in your music-playing service to broadcast intent:
#Override
public void onPrepared(MusicPlayer player) {
// Do some other stuff...
// Broadcast intent to activity to let it know the media player has been prepared
Intent onPreparedIntent = new Intent("MEDIA_PLAYER_PREPARED");
LocalBroadcastManager.getInstance(this).sendBroadcast(onPreparedIntent);
}
Set up a broadcast receiver in your music-controlling activity to receive the intent broadcast by your service. Add the following class to your activity:
// Broadcast receiver to determine when music player has been prepared
private BroadcastReceiver onPrepareReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context c, Intent i) {
// When music player has been prepared, show controller
controller.show(0);
}
};
Register your receiver in your activity's onResume() method:
// Set up receiver for media player onPrepared broadcast
LocalBroadcastManager.getInstance(this).registerReceiver(onPrepareReceiver,
new IntentFilter("MEDIA_PLAYER_PREPARED"));
Depending on the structure of your code, you'll have to do some general tidying up. In my code, I've only called setController() twice: from the onCreate() and onResume() methods in my activity. I also only call controller.show(0) from my broadcast receiver, and my onResume() method.

Android Media Player doesn't play after app has been left for a while in the background

Bit of a strange one this and I can't work out what's happening.
When I launch my app (a game) the music starts playing. I have a button which turns the music on and off. The settings are saved to shared prefs so they are retained.
All works well, you can press the home key, re-invoke the app, leave it in the background while doing other things etc. However, if the app is left in the background for a while (say, overnight), and then re-invoked. Everything works apart from the music.
You can go into the main menu, hit the 'music on/off' button multiple times, but get nothing.
The only way to start the music is to kill the app (or exit correctly, ie, press the 'back' key from the main menu) and then relaunch it so everything is re-created from scratch.
I've confirmed that the 'music' object is still valid and the 'music on/off' button presses are being registered.
Has anyone has similar issues with Media Player? I can't work out what I am (or am not doing) to cause this.
Code
This is my media player class:
public class MusicMan implements MediaPlayer.OnPreparedListener {
MediaPlayer musicPlayer;
MusicMan(Context myContext){
musicPlayer = MediaPlayer.create(myContext, R.raw.music);
musicPlayer.setVolume(.6f, .6f);
}
public void listener(){};
public void start(){
musicPlayer.setLooping(true);
musicPlayer.start();
}
public void stop(){
musicPlayer.stop();
}
public void pause(){
musicPlayer.pause();
}
public int getPos(){
return musicPlayer.getCurrentPosition();
}
public void skipTo(int position){
musicPlayer.seekTo(position);
}
#Override
public void onPrepared(MediaPlayer arg0) {
}
}
And then I simply crate an object like so:
MusicMan music = new MusicMan(view.getContext());
And then I just start and stop the music using the methods in the MusicMan class:
music.start();
You need to use
musicPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
Use this where you set new MediaPlayer player. It sets the wake lock to MediaPlayer and don't let CPU go sleep till you yourself didn't kill or stop application.

two media player played at once

i create an app, and in one layout (just call it layout A), i play the media player, then when i went to another layout (just call it Layout B), i want the sound from the Layout A is continue playing in Layout B, and when i went back to the Layout A, i also want the media player is still continuing the music that was played before.
In Layout A, i set this code in onCreate:
player = MediaPlayer.create(this, R.raw.sound);
if(!isMuted())
{
player.setLooping(true);
player.start();
}
...
btn.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View arg0)
{
// TODO Auto-generated method stub
Intent intent = new Intent(A.this, B.class);
stop=1;
startActivity(intent);
}
});
And this code:
#Override
protected void onPause()
{
super.onPause();
if (stop!=1)
{
//stop=1 if i go to another layout, for example when i want to go to Layout B
//if the device is automatically locked, i want the media player is paused and it resumed when i unlock the device, so i use stop!=1 to know whether the sound should be paused or not
player.pause();
length = player.getCurrentPosition();
}
}
#Override
protected void onResume()
{
super.onResume();
if(!isMuted())
{
//isMuted is method to know whether the sound is muted or not, if it isn't muted, then the sound is resumed
player.seekTo(length);
player.setLooping(true);
player.start();
}
}
In layout B, i used this code in onCreate:
player = MediaPlayer.create(this, R.raw.sound);
....
And this code:
protected void onPause()
{
super.onPause();
player.pause();
length = player.getCurrentPosition();
}
#Override
protected void onResume()
{
super.onResume();
if(!isMuted())
{
if(player.isPlaying())
{
}
else
{
player.seekTo(length);
player.setLooping(true);
player.start();
}
}
}
But this is the problem.
When i went to Layout B, the Media Player from Layout A and Media Player from Layout B is played in the same time, so the sound is played simultaneously at one time.
When i went back to the Layout A, the Media Player in Layout B is stopped and the Media Player in Layout A is stopped and played from the beginning again, it didn't continue the Media Player that was played before.
When the device is locked, the media player is still played although i have used the indicator whether is should be paused or not. Any correction to the code?
I would recommend that you use a Service to play and pause/stop your music. It is not recommended to use Activity to handle music that way. You can start a Service and then play music in it. Services run in background and don't get destroyed automatically too often as compared to Activity. Here's a sample app code that does similar to what you need media player sound continue in all activities
In Activity MediaPlayer can play far.
You should use Service to play MediaPlayer and control from anywhere in application.
I used this tutorial.
https://thenewcircle.com/s/post/60/servicesdemo_using_android_service

Android : stop and play sound on button click

I want to play a sound on button click in game.
I can easily do this using following code
mp = MediaPlayer.create(getApplicationContext(), R.raw.sound);
mp.start();
Issue is, my clicking rate is faster then playing duration of my sound clip.
How do I stop it and play again on my second or third click and so on.
I want to match sound play to match my clicking rate.
Thanks
Abhinav Tyagi
Firstly, you should use MediaPlayer only for large files, like music. For playing sound effects, SoundPool is the way to go.
An excellent tutorial on playing back media is available HERE.
On the click of your button, call soundPool.stop() and soundPool.play() immediately in sequence to stop and start your audio playback.
You can call MediaPlayer.Stop to stop it playing sounds. You can also call MediaPlayer.Reset to return it to the Idle state.
public class MainActivity extends AppCompatActivity {
MediaPlayer mplayer;
public void startPlay(View view) {
mplayer.start();
}
public void stopPlay(View view) {
mplayer.pause();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mplayer = MediaPlayer.create(this, R.raw.laugh);
}
}

Trouble with sound effects at Onclick (Null Pointer and MediaPlayer Warning

I have created a simple Ukulele tuner (The market I think lacks a visually pleasing and extremely simple tuner).
Any how, firstly, through the developer console I can see that there is a Null Pointer Exception at the Button Onclick Events. I have not been able to recreate this, however it has been reported four times.
Secondly, looking at the log while using the app I can see this warning;
E/MP3Extractor(68): Unable to resync. Signalling end of stream.
This entry here MediaPlayer array causing null pointer in Android seems to be along the same lines.
How it works.
Through the use of radio buttons the user selects either to play a single note or a continuous note. I have created a subroutine called StopMediaPlayer that stops, resets and instantiates the MediaPlayers again. This was used because I could never seem to stop the continuous play back but only pause it.
Is the warning and the NullPointerException related? Is there a more efficient/better means of stopping MediaPlayer that will mean that I wont have to re instantiate the notes every time.
Thank You
One of the offending Onclicks
Button gButton = (Button) findViewById(R.id.gButton);
gButton.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
if (singleRadio.isChecked() == true)
{
StopMediaPLayer();
gNote.setLooping(false);
gNote.start();
}
else if (contRadio.isChecked() == true)
{
StopMediaPLayer();
gNote.setLooping(true);
gNote.start();
}
}
});
Stop Media Player Subroutine
public void StopMediaPLayer()
{
Log.i("UkuleleTuner", "Stop Media Player");
gNote.setLooping(false);
cNote.setLooping(false);
eNote.setLooping(false);
aNote.setLooping(false);
gNote.stop();
cNote.stop();
eNote.stop();
aNote.stop();
gNote.reset();
cNote.reset();
eNote.reset();
aNote.reset();
gNote = MediaPlayer.create(this, R.raw.g_note);
cNote = MediaPlayer.create(this, R.raw.c_note);
eNote = MediaPlayer.create(this, R.raw.e_note);
aNote = MediaPlayer.create(this, R.raw.a_note);
}

Categories

Resources