java.lang.IllegalStateException in MediaPlayer - java

This is my code:
final MediaPlayer[] threeSound = new MediaPlayer[1];
threeSound[0] = new MediaPlayer();
final CountDownTimer playThreeSound = new CountDownTimer(1000, 1) {
boolean timerStarted = false;
#Override
public void onTick(long millisUntilFinished) {
torgText.setText("3...");
if (!timerStarted) {
timerStarted = true;
threeSound[0] = MediaPlayer.create(PlayActivity.this, R.raw.three);
try {
threeSound[0].prepare();
threeSound[0].start();
} catch (IOException e) {
e.printStackTrace();
Log.e("IOE", "Something went wrong");
}
}
}
#Override
public void onFinish() {
if (threeSound[0].isPlaying()) {
threeSound[0].stop();
}
playTwoSound.start();
}
};
It throws IllegalStateException. These are logs:
FATAL EXCEPTION: main
Process: testapplication.android.com.guesstune_v2, PID: 3641
java.lang.IllegalStateException
at android.media.MediaPlayer._prepare(Native Method)
at android.media.MediaPlayer.prepare(MediaPlayer.java:1351)
at testapplication.android.com.guesstune_v2.PlayActivity$6.onTick(PlayActivity.java:316)
at android.os.CountDownTimer$1.handleMessage(CountDownTimer.java:133)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:7007)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
What is wrong with preparing MediaPlayer? What should I add to the code? I'm a newbie, sorry for a probably stupid question and for bad English.

The documentation for MediaPlayer states:
MediaPlayer create (Context context, int resid)
Convenience method to create a MediaPlayer for a given resource id. On success, prepare() will already have been called and must not be called again.
https://developer.android.com/reference/android/media/MediaPlayer.html#create(android.content.Context, int)
So your IllegalStateException occurs because prepare() requires the MediaPlayer to be in either a Initialized or Stopped state, but when create(Context context, int resid) is invoked, it calls prepare() resulting in the MediaPlayer being in the Prepared state which it must not be when prepare() is invoked.
In short: remove the prepare() call and the IllegalStateException should no longer occur.
A full State Diagram and list of valid states is presented in the documentation.

Related

How to get Activity/getWindow() from services java class?

I'm trying to run a function that requires passing it a screen capture. When I run this from the main activity, I can run the code like this:
SendScreenFunction(getWindow().getDecorView().getRootView(), getApplicationContext());
I'm not trying to call this function from a service and I can't access the getWindow() function because it requires an activity (which isn't available in the service). I was looking around online and someone suggested a function to get the activity so I can use the function. My current code looks like this:
public class ASTasks extends Service {
// This method run only one time. At the first time of service created and running
#Override
public void onCreate() {
HandlerThread thread = new HandlerThread("ServiceStartArguments",
Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
Log.d("onCreate()", "After service created");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Entered Timer!", Toast.LENGTH_SHORT).show();
Activity main_activity = getActivity(getApplicationContext());
try {
Log.i("Services", "Before crash");
SendScreenFunction(main_activity.getWindow().getDecorView().getRootView(), getApplicationContext());
Log.i("Services", "After crash");
} catch (IOException e) {
e.printStackTrace();
}
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// We don't provide binding
return null;
}
public void SendScreenFunction(View view, Context context){
// Function goes here
}
public static Activity getActivity(Context context) {
if (context == null) return null;
if (context instanceof Activity) return (Activity) context;
if (context instanceof ContextWrapper) return getActivity(((ContextWrapper)context).getBaseContext());
return null;
}
}
Unfortunately, that solution doesn't seem to work and it's crashing. The Logcat error is shown below:
Process: com.example.ASservice:remote, PID: 15966
java.lang.RuntimeException: Unable to start service com.example.ASservice.ASTasks#6e7fed5 with Intent { cmp=com.example.ASservice/.ASTasks }: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.Window android.app.Activity.getWindow()' on a null object reference
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:5110)
at android.app.ActivityThread.access$2100(ActivityThread.java:310)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2319)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8680)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.Window android.app.Activity.getWindow()' on a null object reference
at com.example.ASservice.ASTasks.onStartCommand(ASTasks.java:41)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:5092)
at android.app.ActivityThread.access$2100(ActivityThread.java:310) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2319) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loopOnce(Looper.java:226) 
at android.os.Looper.loop(Looper.java:313) 
at android.app.ActivityThread.main(ActivityThread.java:8680) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135) 
Any ideas on the best way to take the screen capture from within the service (or even a way to pass a flag back to main to process it there)?
Any suggestions would be greatly appreciated. Thanks!

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.media.MediaPlayer.start()' on a null object reference [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 2 years ago.
When i try to click on the button several time then i encountered this error.
Below are the error in logcat:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.huiiy.myapplication, PID: 3933
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.media.MediaPlayer.start()' on a null object reference
at com.example.huiiy.myapplication.Activity9$13.onClick(Activity9.java:288)
at android.view.View.performClick(View.java:5712)
at android.view.View$PerformClick.run(View.java:22514)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6141)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Below are the coding of my application:
iv_33.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
MediaPlayer ivbsound = new MediaPlayer();
ivbsound = MediaPlayer.create(Activity9.this,R.raw.ivbutton);
// MediaPlayer ivbsound = MediaPlayer.create(Activity9.this,R.raw.ivbutton);
ivbsound.start();
int theCard = Integer.parseInt((String) view.getTag());
doStuff(iv_33, theCard);
}
});
Hi try to create player with another audio file.
Maybe the ivbutton file is corrupt
[UPDATE]
If you are reusing it declare lazy property of this sound player and on every click play it
class MyActivity extends AppCompatActivity {
private MediaPlayer soundPlayer = null;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
soundPlayer = MediaPlayer.create(this, R.raw.ivbutton);
iv_33.setOnClickListener(view -> {
soundPlayer.start();
int theCard = Integer.parseInt((String) view.getTag());
doStuff(iv_33, theCard);
});
}
}
It means that the creation of your MediaPlayer failed (maybe you have warn/debug messages about it).
It's useless to create a new MediaPlayer and then replace it by a new one.
Check if R.raw.ivbutton exist and correspond to a good media (which can be runned).
Personnally, this is how I do:
File mediaFile = obj.getFile();
MediaPlayer mediaPlayer = new MediaPlayer();
try {
mediaFile.setReadable(true); // be sure that the program have access to the media content
// this try/catch is to support multiple Android version
try {
mediaPlayer.setDataSource(mediaFile.getAbsolutePath());
} catch (Exception e) {
mediaPlayer.setDataSource(context, Uri.fromFile(mediaFile));
}
mediaPlayer.prepare(); // prepare it, after you can change volume ...
} catch (Exception e){
e.printStackTrace();
}
mediaPlayer.start(); // finally start the media
please make sure that your sound file format you try to play is supported one check list from here. as the MediaPlayer.create returns null in case of the file is not supported which cause you null pointer exception. besides i recommend to check if(ivbsound != null) before calling ivbsound.start();

Cannot get next song to play after onCompleteListener

I have read numerous different responses on this matter but I just wanted to clarify one thing about the onCompletionListener method for MediaPlayer. I have a configuration that is currently working and playing a song after it completes the first one, but after the second one ends it will not play another song from the array. It will also not display the metadata for the new track either. My guess is that the onCompletionListener only runs once and doesn't transfer to the newly created MediaPlayer instance. More Specifically the answer I'm looking for is can the onCompleteListener run more than once? Or is it a non looping function?
Video demonstrating the issue: https://youtu.be/WXDtCktTh3M
Here is what I have for my listener block:
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer arg0) {
if (chosenPath == null) {
seekBar.setProgress(0);
mediaPlayer.seekTo(0);
} else {
songOrderCounter += 1;
System.out.println("SONG_ITERATOR_COUNT: " + songOrderCounter);
try {
/*handler.removeCallbacks(moveSeekBarThread);
songUpdateTimeHandler.removeCallbacks(updateSongTime);*/
Log.d("PATH_WORKING", allMusicFiles[songOrderCounter].toString());
mediaPlayer.stop();
mediaPlayer.reset();
mediaPlayer.release();
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(allMusicFiles[songOrderCounter].toString());
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();
metaRetriever();
seekBar.setProgress(0);
seekBar.setMax(mediaPlayer.getDuration());
trackTime();
}
});
mediaPlayer.prepareAsync();
metaRetriever(); /* Moved inside onPrepared*/
} catch (Exception e) {
System.out.println("NEXT_SONG_FAILED: " + e);
}
}
}
});
UPDATE
The reason this is not working is because I have created a new MediaPlayer Instance in the onCompletion() function so the listener will not associate with the newly created MediaPlayer instance. Therefore it will not listen for the completion of the newly created MediaPlayer. I removed the new MediaPlayer section of code from the setOnCompleteListener() function and now there are issues with the runnable threads that are keeping track of seekbar and time progress causing it to crash when it reaches the end of the file
D/PATH_WORKING: /storage/emulated/0/Music/01 Control.mp3
I/System.out: NEXT_SONG_FAILED: java.lang.IllegalStateException
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.macyg.androidmediaplayer, PID: 12784
java.lang.IllegalStateException
at android.media.MediaPlayer.getCurrentPosition(Native Method)
at com.example.macyg.androidmediaplayer.MainActivity$12.run(MainActivity.java:596)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
And the Runnable causing the crash:
private Runnable moveSeekBarThread = new Runnable() {
public void run() {
if(mediaPlayer.getCurrentPosition() <= mediaPlayer.getDuration()) {
int mediaPos_new = mediaPlayer.getCurrentPosition();
int mediaMax_new = mediaPlayer.getDuration();
seekBar.setMax(mediaMax_new);
seekBar.setProgress(mediaPos_new);
handler.postDelayed(this, 100); //Looping the thread after 0.3 second
// seconds
}else{}
}
};

java.lang.IllegalStateException MediaPlayer

In my application I use a VideoView where playing a MediaPlayer, and in some cases has released me this error:
java.lang.IllegalStateException
at android.media.MediaPlayer.prepareAsync(Native Method)
at android.widget.VideoView.openVideo(VideoView.java:350)
at android.widget.VideoView.setVideoURI(VideoView.java:256)
at android.widget.VideoView.setVideoURI(VideoView.java:239)
at com.wul4.paythunder.hologram.MainActivity.cargarVideo(MainActivity.java:261)
at com.wul4.paythunder.hologram.MainActivity$6.run(MainActivity.java:395)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5466)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
My function to load the video I start it is:
public static void cargarVideo(final String video){
Uri path = Uri.parse(video);
Video.setVideoURI(path);
if(video.contains(NetworkUtils.nombreVideo(prefs.getString("listen",""))) ||
video.contains(NetworkUtils.nombreVideo(prefs.getString("talk","")))) {
Video.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
Log.e("####", "onPrepared");
mp.setLooping(true);
}
});
Video.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
Log.e("####", "onCompletion");
cargarVideo(video);
}
});
}
Video.start();
}
This error does not know to be, so if someone knows or has occurred and you can lie down for a hand, he would appreciate it.
A greeting and thanks in advance
EDIT
I searched and read that the solution may lie in the method call setOnPreparedListener including within the function onPrepared the video initialization --> mp.start()
I tried it and now the same behavior seems, do not know if in the future again give the same error
Have you tried to take a look at the Life Cycle of a MediaPlayer Instance?
https://developer.android.com/reference/android/media/MediaPlayer.html
Basically from what I see, you did not properly 'reset' the MediaPlayer object so that it can properly rerun again.
Try having MediaPlayer.reset() and see if it works.
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
Log.e("####", "onCompletion");
// Reset the player here
cargarVideo(video);
}

Keep getting a NullPointerException for MediaPlayer [duplicate]

This question already exists:
MediaPlayer NullPointerException in local method [duplicate]
Closed 7 years ago.
There is an annoying bug in my code somewhere and I can't sleep because of it!
I kind of get why I might be getting it - I think something to do with onCreate method I think.
This is what I have:
public class PredefinedUserPlayer extends Activity {
MediaPlayer mediaPlayer;
String names;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.userdefplayer);
names = "http://X.X.X.X/musikz/musikz01.mp3";
mediaPlayer = new MediaPlayer();
}
public void playSelectedFile() {
mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(PredefinedUserPlayer.this, Uri.parse(names));
} catch (IOException e) {
e.printStackTrace();
}
try {
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.start();
}
}
The playSelectedFile() method is being called in another class and here is that bit of code here:
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
PredefinedUserPlayer predefinedUserPlayer = new PredefinedUserPlayer()
predefinedUserPlayer.playSelectedFile();
}
});
I can't really have the MediaPlayer stuff in the above class which is why I have had to instantiate the PredefinedUserPlayer class. This is the actual stack trace (maybe someone can help me debug and fix this annoying bug):
java.lang.NullPointerException
at android.content.ContextWrapper.getContentResolver(ContextWrapper.java:99)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:882)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:859)
at lukasz.musik.PredefinedUserPlayer.playSelectedFile(PredefinedUserPlayer.java:86)
at lukasz.musik.CustomMusicAdapter$ViewHolder$1.onClick(CustomMusicAdapter.java:85)
at android.view.View.performClick(View.java:4240)
at android.view.View$PerformClick.run(View.java:17721)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
You can't new activity by hand like this:
PredefinedUserPlayer predefinedUserPlayer = new PredefinedUserPlayer()
You can use Broadcast to achieve it,Like this:
**First,Register a BroadcastReceiver in PredefinedUserPlayer Activity:
public static String ACTION_PLAY = "ACTION_PLAY_FILE";
private final BroadcastReceiver mPlayFileReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (ACTION_PLAY.equals(action)) {
playSelectedFile();
}
}
};
IntentFilter intentFilter = new IntentFilter(ACTION_PLAY);
LocalBroadcastManager.getInstance(this).registerReceiver(mPlayFileReceiver,intentFilter);
Second,Send Broadcast with action ACTION_PLAY to inform the receiver to be invoked:
LocalBroadcastReceiver.getInstance(this).sendBroadcastSync(new Intent(PredefinedUserPlayer.ACTION_PLAY));

Categories