Android MediaPlayer: How to stop if another audio file is being loaded? - java

I have a problem with the Android MediaPlayer. As soon as a new sound file is clicked by user input, the old one does not stop, so all audio files overlap.
I already tried common methods like MediaPlayer.stop(); and
MediaPlayer.release();
These methods always result in an app crash, although they are called in the correct order
public void Abspielen(String Datei) {
try {
AndreasPlayer = MediaPlayer.create(MainActivity.this, getResources().getIdentifier(Datei, "raw", getPackageName()));
AndreasPlayer.start();
} catch (Exception e) {
Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_LONG).show();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Abspielen("filename");
}

I worked out the following solution:
public void Abspielen(String Datei) {
try {
stopKnopf = findViewById(R.id.fab2);
stopKnopf.show();
try {
if (AndreasPlayer.isPlaying()) {
AndreasPlayer.reset();
}
} catch (Exception ex) {
}
AndreasPlayer = MediaPlayer.create(MainActivity.this, getResources().getIdentifier(Datei, "raw", getPackageName()));
AndreasPlayer.start();
stopKnopf.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
AndreasPlayer.reset();
stopKnopf.hide();
}
});
AndreasPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
AndreasPlayer.reset();
stopKnopf.hide();
}
});
} catch (Exception e) {
Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_LONG).show();
}
}

Related

How do I connect my floating action button to an activity inside my Android project

I am not sure where I have missed something, I expect the playPauseButton to respond when I click it but nothing happens when I do. I have noticed some errors in my debug console log, which are mostly related to mediaPlayer, but I don't exactly know what they mean, since an quite new to android programming! Below is my debug console log, and a bit of related code:
// Removed Logcat!!
Some code related from a class Player.java:
import android.media.MediaPlayer;
import android.media.AudioManager;
import android.util.Log;
import java.io.IOException;
public class Player {
// Creating new MediaPlayer
MediaPlayer mediaPlayer = new MediaPlayer();
// Creating a public static player as reference to this Player class
public static Player player;
String url = "";
public Player () {
this.player = this;
}
public void playStream (String url) {
if (mediaPlayer != null) {
try {
mediaPlayer.stop();
} catch (Exception e) {
}
// Releasing everything from the mediaPlayer
mediaPlayer = null;
}
// Creating new Media Player
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
// Try & Catch errors
try {
mediaPlayer.setDataSource(url);
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();
}
});
mediaPlayer.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
}
public void pausePlayer () {
try {
mediaPlayer.pause();
} catch (Exception e) {
Log.d("EXCEPTION", "Failed to pause Media Player");
}
}
public void playPlayer () {
try {
mediaPlayer.start();
} catch (Exception e) {
Log.d("EXCEPTION", "Failed to start Media Player");
}
}
public void togglePlayer () {
try {
if (mediaPlayer.isPlaying())
pausePlayer();
else
playPlayer();
} catch (Exception e) {
Log.d("Exception", "Failed to toggle Media Player");
}
}
}
the other related code from MainActivity.java
public class MainActivity extends AppCompatActivity {
static FloatingActionButton playPauseButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
playPauseButton = (FloatingActionButton) findViewById(R.id.fab);
playPauseButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
// Songs location on our server
String url = // "*My website/file.mp3";
// Passing above url to our MediaPlayer
if (Player.player == null)
new Player();
Player.player.playStream(url);
}
public static void flipPlayPauseButton (boolean isPlaying) {
if (isPlaying) {
playPauseButton.setImageResource(android.R.drawable.ic_media_pause);
} else {
playPauseButton.setImageResource(android.R.drawable.ic_media_play);
}
}
Try for example:
playPauseButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(video.isplaying()){pause function()}
else{play function()}
}
});
Okay, I'd like to thank MohammadMoeinGolchin, who has helped me figure this out. It so happen's that I did not complete my function inside of my public void onClik(View view) function. But you will see that is is written somewhere in a separate Player.java class. So to resolve this, what I did instead, is to call the togglePlayer() function inside my onClick(View view) like this:
#Override
public void onClick (View view) {
Player.player.togglePlayer();
}

I get error (1, 19) when tapping on multiple buttons that play sound

It works for a few buttons, but when I tap about 6 then only some of them work. The ones that don't work give the error (1, -19). I do the media player state wrapper set up, so if I need to use that to get states of my "mp"s, let me know.
public class SoundFile {
public SoundFile(final Activity activity, final String soundfile, int imgButtonId, ArrayList<MediaPlayerStateWrapper> mps) {
this.mp = new MediaPlayerStateWrapper();
try {
this.afd = activity.getAssets().openFd(soundfile + ".mp3");
} catch (IOException e) {
e.printStackTrace();
}
this.allMps = mps;
mps.add(this.mp);
this.position = (ImageButton) activity.findViewById(imgButtonId);
this.position.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
mp.reset();
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
mp.prepareAsync();
mp.start();
}catch (Exception ex){
ex.printStackTrace();
}
....
You have to add an onPreparedListener. Here is what I did and it worked.
try {
mp = new MediaPlayer();
mp.reset();
try {
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
} catch (IOException e) {
e.printStackTrace();
}
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
mp.release();
}
});
mp.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mpm) {
mpm.start();
mp.start();
}
});
mp.prepareAsync();
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
}
}

MediaPlayer stream from url

I have a simple app and I want to play a mp3 from a url.
when I add this code to OnCreate, the app crashes at opening:
try {
mediaPlayer.setDataSource("http://www.freesfx.co.uk/rx2/mp3s/9/10183_1367780535.mp3");
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
Why? What's wrong with this part of the code?
Complete code:
public class MediaStreamTest extends AppCompatActivity {
ImageButton bPlay;
ImageButton bStop;
MediaPlayer mediaPlayer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_media_stream_test);
bPlay = (ImageButton)findViewById(R.id.btnPlay);
bStop = (ImageButton)findViewById(R.id.btnStop);
try {
mediaPlayer.setDataSource("http://www.freesfx.co.uk/rx2/mp3s/9/10183_1367780535.mp3");
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
bPlay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mediaPlayer.isPlaying()) {
bPlay.setBackgroundResource(R.drawable.ic_play_arrow_24dp);
mediaPlayer.pause();
}
else {
bPlay.setBackgroundResource(R.drawable.ic_pause_24dp);
mediaPlayer.start();
}
}
});
}
}
The issue is because the MediaPlayer is not being initialized. That's why you are getting a null pointer exception when trying to use it.
Just add:
mediaPlayer = new MediaPlayer();
Before calling MediaPlayer.setDataSource method

Unable to stop MusicPlayer even after finishing an Activity.

I've set MediaPlayer to play different songs. However, when I try to close the Application, the Activity gets closed, but the song still run in the Background. Here is how I've coded it!
try {
mp.setDataSource(text);
mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
mp.prepare();
mp.setVolume(0.4f, 0.4f);
songPlayer.setDataSource(song);
songPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer songPlayer) {
songPlayer.start();
}
});
songPlayer.prepare();
songPlayer.setLooping(true);
voicePlayer.setDataSource(voice);
voicePlayer.setLooping(true);
voicePlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer voicePlayer) {
voicePlayer.start();
}
});
voicePlayer.prepare();
voicePlayer.setVolume(0.5f,0.5f);
}
catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
catch (IllegalMonitorStateException e)
{
e.printStackTrace();
}
//THIS IS WHERE I THINK THE ERROR IS :
//WHERE `mp` IS LOOPED WITH DELAY OF 5000ms
try {
final Handler hlr = new Handler();
final Runnable looper = new Runnable() {
#Override
public void run() {
if (mp != null) {
if (mp.isPlaying()) {
mp.stop();
}
}
mp.start();
}
};
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
hlr.postDelayed(looper, 5000);
}
});
}
catch(IllegalStateException e)
{
e.printStackTrace();
}
}
}
And there is also One method which restarts the activity after a specified time. And the code for that Activity is :
public void snoozeup(View view)
{
SharedPreferences sa = getSharedPreferences("SnoozeList", Context.MODE_PRIVATE);
int snox = sa.getInt("SnoozeX",0);
if(snox==2) {
Handler handler = new Handler();
Runnable x = new Runnable() {
#Override
public void run()
{
Intent intent = new Intent(Time_Date.this, Time_Date.class);
intent.putExtra("finisher", state);
startActivity(intent);
}
};
handler.postDelayed(x, 120000);
}
else
{
Handler handler = new Handler();
Runnable x = new Runnable() {
#Override
public void run() {
startActivity(new Intent(Time_Date.this, Time_Date.class));
}
};
handler.postDelayed(x, 180000);
}
try
{
if (mp != null && mp.isPlaying())
{
Log.d("TAG------->", "mp is running");
mp.stop();
Log.d("TAG------->", "mp is stopped");
mp.reset();
mp.release();
Log.d("TAG------->", "mp is released");
mp=null;
}
if (voicePlayer != null && voicePlayer.isPlaying()) {
Log.d("TAG------->", "voiceplayer is running");
voicePlayer.stop();
Log.d("TAG------->", "voiceplayer is stopped");
voicePlayer.release();
Log.d("TAG------->", "voiceplayer is released");
}
if (songPlayer != null && songPlayer.isPlaying()) {
Log.d("TAG------->", "songplayer is running");
songPlayer.stop();
Log.d("TAG------->", "songplayer is stopped");
songPlayer.release();
Log.d("TAG------->", "songplayer is released");
}
}
catch(Exception e)
{
e.printStackTrace();
}
finish();
}
The problem is with mp . Other instances of MediaPlayer gets stopped. But not mp. And sadly, Can't see any error in logcat as well. So where am I doing wrong? Any help will be appreciated.
In order to stop the music you should put this code in the onPause() method.
This method can be overrided from your class that inherite from Activity
#Override
protected void onPause() {
super.onPause();
mp.stop
}
You can also take a look at Managing the Activity Lifecycle to better understand how an activity is managed by Android.
You are destroying your activity, but you need to stop/destroy your media player too. Please write down the following code in your activity.
#Override
public void onDestroy() {
super.onDestroy();
if (mp!= null) {
//destory ur object here.
}
}
Put in either onPause() or onDestroy() Example:
#Override
protected void onPause() {
super.onPause();
mp.stop();
}

AdMob Interstitial ads not clickable

I successfully implemented AdMob interstitial ads into my application but the only problem is that they are not clickable.
Here is my AdMob.java class:
import android.app.Activity;
import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.InterstitialAd;
public class Admob extends AdListener{
private Activity ctx;
//Admob
private InterstitialAd interstitial;
private AdRequest adRequest;
private String unitId;
public static boolean fromAdmob = false;
public Admob(Activity ctx, String unitId)
{
this.ctx = ctx;
this.unitId = unitId;
try{
this.interstitial = new InterstitialAd(this.ctx);
interstitial.setAdUnitId(unitId);
interstitial.setAdListener(this);
adRequest = new AdRequest.Builder().build();
}
catch (Exception e){
e.printStackTrace();
}
}
public void loadAd()
{
try{
interstitial.loadAd(adRequest);
}
catch (Exception e){
e.printStackTrace();
}
}
#Override
public void onAdLoaded() {
try{
fromAdmob = true;
interstitial.show();
}
catch (Exception e){
e.printStackTrace();
}
}
#Override
public void onAdFailedToLoad(int errorCode)
{
}
#Override
public void onAdClosed() {
fromAdmob = false;
}
}
And the MainPageActivity.java file:
public class MainPageActivity extends Activity implements IGameListener, IEventDelegate{
//Tags
private static final String TAG = "bubblesMainPage";
//Context
public static Activity instance;
//Media
private MediaPlayer mp;
//Ads
private Admob admob;
//TapSDK
private Tap tap;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_page_activity);
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
tr
Tap.establish(this);
tap = new Tap(this, "xxxx");
}
catch (Exception e){
e.printStackTrace();
}
//Admob
this.admob = new Admob(this, "ADMOB_ID");
//Context
instance = this;
//Media
mp = MediaPlayer.create(getApplicationContext(), R.raw.background_music);
mp.setLooping(true);
//Set activity properties
try {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
} catch (Exception e) {
e.printStackTrace();
}
//Intents & Listeners
final Intent gamePlayActivity = new Intent(this, BubbleShooterActivity.class);
BubbleShooterActivity.listener = this;
//Animations
Animation scaleUpAnim = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.scale_up);
findViewById(R.id.play_button).startAnimation(scaleUpAnim);
//UI Events
findViewById(R.id.play_button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new Thread(new Runnable() {
#Override
public void run() {
try {
startActivity(gamePlayActivity);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
});
findViewById(R.id.more_games_button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
tap.showMoreGamesWithViewControllerAndAppID((IEventDelegate)instance);
}
});
}
/*
Game methods - start
*/
#Override
public void onGameStart() {
Log.i(TAG, "onGameStart");
}
#Override
public void onLevelFailed() {
//Level failed window
try{
Intent i = new Intent(this, LostActivity.class);
startActivity(i);
}
catch (Exception e){
e.printStackTrace();
}
Log.i(TAG, "onLevelFailed");
}
#Override
public void onLevelUp() {
Log.i(TAG, "onLevelUp");
if(admob != null){
runOnUiThread(new Runnable() {
#Override
public void run() {
try{
admob.loadAd();
}
catch (Exception e){
e.printStackTrace();
}
try{
Intent i = new Intent(instance, WonActivity.class);
startActivity(i);
}
catch (Exception e){
e.printStackTrace();
}
}
});
}
}
#Override
public void onGameEnd() {
Log.i(TAG, "onGameEnd");
}
/*
TapSDK methods - start
*/
#Override
public void viewDidAppear() {
Log.i(TAG, "TapSDK: viewDidAppear");
}
#Override
public void viewDidDisappear() {
Log.i(TAG, "TapSDK: viewDidDisappear");
}
#Override
public void viewConnectFail(String s) {
Log.i(TAG, "TapSDK: viewConnectFail " + s);
}
#Override
public void conversion() {
Log.i(TAG, "TapSDK: conversion");
}
#Override
public void onOfferComplete(int score) {
Log.i(TAG, "TapSDK: onOfferComplete " + score);
}
/*
Activity methods start
*/
#Override
public void onBackPressed() {
Log.i(TAG, "onBackPressed");
try{
Intent exitScreen = new Intent(this, ExitActivity.class);
startActivity(exitScreen);
}
catch (Exception e){
e.printStackTrace();
Log.e(TAG, "onBackPressed: " + e.getMessage());
}
}
#Override
protected void onStart() {
super.onStart();
// Monitor launch times and interval from installation
RateThisApp.onStart(this);
// If the criteria is satisfied, "Rate this app" dialog will be shown
RateThisApp.showRateDialogIfNeeded(this);
}
#Override
protected void onResume()
{
super.onResume();
if(tap != null)
tap.onResume();
mp.seekTo(0);
mp.start();
}
#Override
protected void onPause()
{
if(tap != null)
tap.onPause();
mp.pause();
super.onPause();
}
#Override
protected void onDestroy()
{
mp.stop();
mp = null;
if(tap != null)
tap.onDestroy();
super.onDestroy();
}
}
I couldn't figure out how to show the interstitial ad when the user levels up and presses the play button (which will lead him to the next level). The interstitial ad show up when he presses the home button which will take him to the MainActivity screen.
Can someone help me to make the ads clickable? Also, any suggestions on how to add the interstitial ad after each completed level? When someone has finished a level and presses the play button, an interstitial ad should appear and when that is closed he should be able to play the next level.
I really appreciate your help!
A number of issues:
Don't call interstitial.show() from onAdLoaded. Call show() when the user presses the play button for your next level (but only if an ad is available).
Get rid of public static Activity instance; Never hold a static reference to an Activity. You will just leak context everywhere.
Instead of calling admob.loadAd() from onLevelUp() call it as soon as you create your Activity (it takes times to load an ad from the network). NB you don't need to call it from runOnUIThread()
Call admob.loadAd() again after each time you show the ad to the user.

Categories

Resources