I've created a class that contains a method to play a sound.
import android.content.Context;
import android.media.MediaPlayer;
public class Sounds {
private Context context;
public void Sound(Context context) {
this.context = context;
}
void hydrogen() {
final MediaPlayer mp = MediaPlayer.create(context, R.raw.hydrogen);
mp.start();
}
}
I want to play the sound upon a button click using this code:
public void onClick(View view){
Sounds s = new Sounds();
s.hydrogen();
}
When I click the button, the program crashes.
The sound plays fine when I use code in MainActivity rather than calling a method from a separate class.
I suspect the issue has something to do with retrieving the sound file from the res folder, but I don't know how to fix it.
I created a separate class with a method that just defines variables and I was able to call that method without any problems.
Logcat makes reference to this line with purple highlighting on the word "create"
final MediaPlayer mp = MediaPlayer.create(context, R.raw.hydrogen);
Does anyone know what the problem is?
This is the stacktrace
E FATAL EXCEPTION: main
Process: com.xxmassdeveloper.soundtest, PID: 14132
java.lang.IllegalStateException: Could not execute method for android:onClick
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:473)
at android.view.View.performClick(View.java:7870)
at android.widget.TextView.performClick(TextView.java:14970)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1219)
at android.view.View.performClickInternal(View.java:7839)
at android.view.View.access$3600(View.java:886)
at android.view.View$PerformClick.run(View.java:29363)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:7948)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:468)
at android.view.View.performClick(View.java:7870)
at android.widget.TextView.performClick(TextView.java:14970)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1219)
at android.view.View.performClickInternal(View.java:7839)
at android.view.View.access$3600(View.java:886)
at android.view.View$PerformClick.run(View.java:29363)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:7948)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
at android.media.MediaPlayer.create(MediaPlayer.java:1002)
at android.media.MediaPlayer.create(MediaPlayer.java:981)
at com.xxmassdeveloper.soundtest.Sounds.hydrogen(Sounds.java:15)
at com.xxmassdeveloper.soundtest.MainActivity.onClick(MainActivity.java:48)
at java.lang.reflect.Method.invoke(Native Method)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:468)
at android.view.View.performClick(View.java:7870)
at android.widget.TextView.performClick(TextView.java:14970)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1219)
at android.view.View.performClickInternal(View.java:7839)
at android.view.View.access$3600(View.java:886)
at android.view.View$PerformClick.run(View.java:29363)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:7948)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)
2023-01-27 10:29:00.836 14132-14132 Process com.xxmassdeveloper.soundtest I Sending signal. PID: 14132 SIG: 9
2023-01-27 10:29:00.912 3675-4184 WindowManager pid-3675 E win=Window{57fa696 u0 com.xxmassdeveloper.soundtest/com.xxmassdeveloper.soundtest.MainActivity EXITING} destroySurfaces: appStopped=false win.mWindowRemovalAllowed=true win.mRemoveOnExit=true win.mViewVisibility=0 caller=com.android.server.wm.AppWindowToken.destroySurfaces:1200 com.android.server.wm.AppWindowToken.destroySurfaces:1181 com.android.server.wm.WindowState.onExitAnimationDone:5030 com.android.server.wm.-$$Lambda$01bPtngJg5AqEoOWfW3rWfV7MH4.accept:2 java.util.ArrayList.forEach:1262 com.android.server.wm.AppWindowToken.onAnimationFinished:3549 com.android.server.wm.AppWindowToken.commitVisibility:860
Thanks
CodePudding user response:
The constructor of your Sounds
class is not correct.
public class Sounds {
private Context context;
// You should have a constructor here, not a function
// So, void should be removed. And you should have name same as the class name
public Sounds(Context context) {
this.context = context;
}
// Better to make is public so that you can call it in other packages
public void hydrogen() {
final MediaPlayer mp = MediaPlayer.create(context, R.raw.hydrogen);
mp.start();
}
}
And therefore when you try to call this Sounds
class, you should do something like this:
public void onClick(View view) {
// As you are inside an Activity, you can pass this
Sounds s = new Sounds(this);
s.hydrogen();
}
CodePudding user response:
You don't need to pass the context as part of the Sounds constructor. Instead I would pass the context to hydrogen. You should also make the hydrogen method public so it can be accessed from elsewhere:
public void hydrogen(Context context)
{
final MediaPlayer mp = MediaPlayer.create(context, R.raw.hydrogen);
mp.start();
}