My android application cannot play again when clicking button - android-mediaplayer

I'm new in android programming. My first application is an android mediaplayer.
I built two buttons : one to play a song, and another to stop it.
My application is running correctly ; the problem is that i can play and stop it, but I cant play the song again.
I tried to use setDataSource() but it triggers an error.
Here's the code ; the file is in raw/song.mp3
package com.example.test6;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity {
MediaPlayer mp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mp = MediaPlayer.create(this,R.raw.song);
setContentView(R.layout.activity_main);
final Button btnPlay = (Button)this.findViewById(R.id.button1);
final Button btnStop = (Button)this.findViewById(R.id.button2);
btnPlay.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
mp.start();
}
});
btnStop.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
mp.stop();
mp.reset();
if(mp.isPlaying()){
mp.stop();
}else{
mp.setDataSource("res/raw/song.mp3");
mp.prepare();
mp.start();
}
});
}
}

First of all, you don't need to set the data source manually if you're doing the creation like this: MediaPlayer.create(this, R.raw.song); Also, in that case, you don't need to call prepare() because MediaPlayer.create() does that for you.
I would suggest this kind of approach (assuming you don't want the start button to do anything if it's already playing):
Start button listener:
if (mp==null) {
mp = MediaPlayer.create(this, R.raw.song);
}
if (!mp.isPlaying()) {
mp.start();
}
Stop button listener:
if (mp!=null) {
if (mp.isPlaying()) {
mp.stop();
}
mp.release();
mp = null;
}
I didn't test this, so I'm looking forward to your response

Related

RecyclerView and Item Position and click on particular item

This is the interface of my application, my question is, if I click on "video lecture" then it should go to Video Lecture Activity and if i click on "Detail Notes" then it should go in Detail Notes Activity. Similarly, i want to do with all recyclerView items.
This is my Adapter code
package com.example.motionofknowledge;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.motionofknowledge.databinding.ActivityMaterialsBinding;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.EventListener;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.FirebaseFirestoreException;
import com.google.firebase.firestore.QuerySnapshot;
import java.util.ArrayList;
public class Materials extends AppCompatActivity {
ActivityMaterialsBinding binding;
FirebaseFirestore database;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMaterialsBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
getSupportActionBar().hide();
String head = getIntent().getStringExtra("subName");
TextView textView = findViewById(R.id.headingMat);
textView.setText(new String(head));
database = FirebaseFirestore.getInstance();
ArrayList<MatModel> materials = new ArrayList<>();
MatAdapter adapter = new MatAdapter(this,materials);
String subId = getIntent().getStringExtra("subId");
database.collection("subjects")
.document(subId)
.collection("mat")
.orderBy("index")
.addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#Nullable QuerySnapshot value, #Nullable FirebaseFirestoreException error) {
materials.clear();
for (DocumentSnapshot snapshot:value.getDocuments()){
MatModel model = snapshot.toObject(MatModel.class);
model.setMatId(snapshot.getId());
materials.add(model);
}
adapter.notifyDataSetChanged();
}
});
binding.matList.setLayoutManager(new GridLayoutManager(this,2));
binding.matList.setAdapter(adapter);
binding.matHome.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(Materials.this,MainActivity.class);
startActivity(intent);
}
});
}
}
This is my adapter code
package com.example.motionofknowledge;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
public class MatAdapter extends RecyclerView.Adapter<MatAdapter.MatViewHolder>{
Context context;
ArrayList<MatModel> matModels;
public MatAdapter(Context context, ArrayList<MatModel> matModels){
this.context = context;
this.matModels = matModels;
}
#NonNull
#Override
public MatViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_category,null);
return new MatViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MatViewHolder holder, int position) {
MatModel model = matModels.get(position);
holder.textView.setText(model.getMatName());
Glide.with(context)
.load(model.getMatImage())
.into(holder.imageView);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context,Chapters.class);
intent.putExtra("matId",model.getMatId());
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return matModels.size();
}
public class MatViewHolder extends RecyclerView.ViewHolder{
ImageView imageView;
TextView textView;
public MatViewHolder(#NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.image);
textView = itemView.findViewById(R.id.category);
}
}
}
You did not post your adapter code, but your activity code. Anyway: I understand that you have a recyclerView with different kind of items in it (Video Lecture, Detail Notes, and more). Depending on which item the user clicks, you want to do different things.
This is done by using the onBindViewHolder method in your MatAdapter. This method does not only bind the data to the UI layout, but it should also be used to bind a click listener to the UI layout.
If you have only a few items in your RecyclerView, you could use the getItem(position) method of your adapter to find out what specific item you are dealing with within onBindViewHolder. As soon as you know what kind of item the Adapter wants to bind, you can set the according click listener.
See this suggestion:
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = null
if (model.type == VIDEO) {
intent = new Intent(context,Video.class);
} else if (model.type == DETAILS) {
intent = new Intent(context,Details.class);
} else {
...
}
intent.putExtra("matId",model.getMatId());
context.startActivity(intent);
}
});
model is the current MatModel that you want to bind.
model.type is any way to distinguish the different items. I do not know the details of the MatModel class, but you somehow need to be able to distinguish the different models, of course.

Intellij plugin development, how to prevent an action from occuring, like closing a tab

Is this possible?
I need to subscribe to the event somehow and possibly return false or similar, i am guessing. I have no idea how though.
What event is that?
Where do I register it?
Anyone?
EDIT:
I have tried this:
import com.intellij.openapi.components.ApplicationComponent;
import com.intellij.openapi.editor.impl.EditorComponentImpl;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
import java.awt.event.AWTEventListener;
import java.awt.event.KeyEvent;
public class MyPlugin implements ApplicationComponent {
static {
/*MessageBus bus = ApplicationManager.getApplication().get
MessageBusConnection connection = bus.connect();
connection.subscribe(AppTopics.FILE_DOCUMENT_SYNC,
new FileDocumentManagerAdapter() {
#Override
public void beforeDocumentSaving(Document document) {
// create your custom logic here
}
});*/
}
private final AWTEventListener listener;
public MyPlugin() {
System.out.println("111111111111111111");
listener = new AWTEventListener() {
#Override
public void eventDispatched(AWTEvent event) {
if ( event instanceof KeyEvent ) {
KeyEvent kv = (KeyEvent) event;
Component component = kv.getComponent();
if ( component instanceof EditorComponentImpl) {
EditorComponentImpl cp = (EditorComponentImpl) component;
}
System.out.println("3333333" + component.getClass());
}
System.out.println("aaaaaaa" + event.getClass());
}
};
}
#Override
public void initComponent() {
System.out.println("bbbbbbbbbbbbbbbbbbbbbbbbbbb");
Toolkit.getDefaultToolkit().addAWTEventListener(listener, AWTEvent.KEY_EVENT_MASK);
}
#Override
public void disposeComponent() {
Toolkit.getDefaultToolkit().removeAWTEventListener(listener);
}
#NotNull
#Override
public String getComponentName() {
return "temp";
}
}
But it does not work. I get events but the wrong kind.
Two plugins were developed in the end to accomplish this:
https://plugins.jetbrains.com/space/index?pr=idea&lg=opensource%40momomo.com

Cannot resolve Symbol variables - Tearing my hair out

I am trying to follow a tutorial and have got stuck with what I figure to be the last error before completion.
Can someone tell me what I am doing wrong with these variables?
Including both activities below, if any other code is applicable, I am happy to provide it.
Error codes read:
Error:(21, 56) error: cannot find symbol variable pickupLine
Error:(24, 9) error: cannot find symbol variable retryButton
Error:Execution failed for task ':app:compileDebugJavaWithJavac'.
Compilation failed; see the compiler error output for details.
MainActivity.java:
package io.wavey.pickuplesson1;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Grab clean button so we can do stuff with it!
Button cleanButton = (Button) findViewById(R.id.cleanButton);
final Button dirtyButton = (Button) findViewById(R.id.dirtyButton);
final String pickupLine = "You had me at hello world";
//This is a Callback.
cleanButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sendLine(pickupLine);
}
});
}
//Send to activity
private void sendLine(String pickupLine) {
Intent intent = new Intent(this, LineActivity.class);
intent.putExtra("Pickup Line", pickupLine);
startActivity(intent);
}
}
LineActivity.java:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_line);
Bundle pickupData = getIntent().getExtras();
if (pickupData == null) {
return;
}
String receivedPickupLine = pickupData.getString("Pickup Line");
TextView newLine = (TextView) findViewById(R.id.pickupLine);
newLine.setText(receivedPickupLine);
retryButton.setOnClicklistener (new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
}
LineActivity.java:

Confused with NullPointerException

I know that i am probably missing something simple but i am getting this error when i try to load my second activity and i have no idea why, I understand (Or iv'e been told) That it happens when your code doesn't point to anything, But iv'e checked it and it points to the correct location.
ResultText
package com.example.mdpmk1;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class ResultText extends Activity {
Button button;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addListenerOnButton();
//Points /\
}
public void addListenerOnButton() {
final Context context = this;
button = (Button) findViewById(R.id.returnHome);
button.setOnClickListener(new OnClickListener() {
//Points /\
#Override
public void onClick(View arg0) {
Intent intent = new Intent(context, MainActivity.class);
startActivity(intent);
}
});
String result=getIntent().getStringExtra("resultText");
setContentView(R.layout.result_text);
TextView tv=new TextView(this);
tv.setTextSize(20);
String str=result;
tv.setText(str);
setContentView(tv);
}
}
If you require any more of the files feel free to ask.
Sorry if its a noob question and thanks for the help in advance.
call setContentView(R.layout.result_text); before calling addListenerOnButton();
Like:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.result_text);
addListenerOnButton();
}

JavaFX app in System Tray

I am Making a Simple App using JavaFX UI, The app simply just do that:
has a systray icon, which when clicked shows a window, when clicked again hides it, on rightclick shows a menu with 1 "exit" item
I already Made the UI and put the App in the Sys Tray, but i can't show/hide it using Normal Actionlistener method, but i got this error:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Not on FX application thread; currentThread = AWT-EventQueue-0
here is the Code:
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionListener;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class Main extends Application{
public static void main(String[] args) {
launch(args);
}
#Override
public void start(final Stage primaryStage) {
primaryStage.setTitle("Hello World!");
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
System.out.println("Hello World!"); }
});
StackPane root = new StackPane();
root.getChildren().add(btn);
primaryStage.setScene(new Scene(root, 300, 250));
primaryStage.show();
if (SystemTray.isSupported()) {
SystemTray tray = SystemTray.getSystemTray();
Image image = Toolkit.getDefaultToolkit().getImage("Germany-politcal-map.jpg");
PopupMenu popup = new PopupMenu();
MenuItem item = new MenuItem("Exit");
popup.add(item);
TrayIcon trayIcon = new TrayIcon(image, "Amr_Trial", popup);
ActionListener listener = new ActionListener() {
#Override
public void actionPerformed(java.awt.event.ActionEvent arg0) {
// TODO Auto-generated method stub
System.exit(0);
}
};
ActionListener listenerTray = new ActionListener() {
#Override
public void actionPerformed(java.awt.event.ActionEvent arg0) {
// TODO Auto-generated method stub
primaryStage.hide();
}
};
trayIcon.addActionListener(listenerTray);
item.addActionListener(listener);
try{
tray.add(trayIcon);
}catch (Exception e) {
System.err.println("Can't add to tray");
}
} else {
System.err.println("Tray unavailable");
}
//
}
}
Wrap the code in the actionListener which calls back to JavaFX in Platform.runLater. This will execute the code which interfaces with the JavaFX system on the JavaFX application thread rather than trying to do it on the Swing event thread (which is what is causing you issues).
For example:
ActionListener listenerTray = new ActionListener() {
#Override public void actionPerformed(java.awt.event.ActionEvent event) {
Platform.runLater(new Runnable() {
#Override public void run() {
primaryStage.hide();
}
});
}
};
By default the application will shutdown when it's last window is hidden. To override this default behaviour, invoke Platform.setImplicitExit(false) before you show the first application Stage. You will then need to explicitly call Platform.exit() when you need the application to really shutdown.
I created a demo for using the AWT system tray within a JavaFX application.
You should only modify the javafx classes on the javafx thread, the listeners on the tray icon are likely to be running on the swing thread. You can do this by posting a runnable to Platform#runLater like so:
Platform.runLater(new Runnable() {
public void run() {
primaryStage.hide();
}
});
The system tray is not supported in JavaFX yet. You could track the progress on this task under the following JIRA issue: https://bugs.openjdk.java.net/browse/JDK-8090475
The issue also provides a workaround, which could be used in JavaFX 8 to get the basic support.
The feature is not planned for JavaFX 8, so it might be released in one of the following updates or even in JavaFX 9.
Shameless self-plug, but I developed a small wrapper library for JavaFX icons that use the SystemTray called FXTrayIcon.
It abstracts away all of the nasty AWT bits and eliminates having to guess which thread you should be running code on. It's available as a dependency on Maven Central.
I resolved your issue. JavaFX with AWT. I have one example of a application that shows and hides when you make left clic. i really hope works for you
import java.awt.AWTException;
import java.awt.Image;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.URL;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class MainApp2 extends Application {
int stateWindow = 1;
#Override
public void start(final Stage stage) throws Exception {
//Check the SystemTray is supported
if (!SystemTray.isSupported()) {
System.out.println("SystemTray is not supported");
return;
}
URL url = System.class.getResource("/image/yourImage.png");
Image image = Toolkit.getDefaultToolkit().getImage(url);
//image dimensions must be 16x16 on windows, works for me
final TrayIcon trayIcon = new TrayIcon(image, "application name");
final SystemTray tray = SystemTray.getSystemTray();
//Listener left clic XD
trayIcon.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent event) {
if (event.getButton() == MouseEvent.BUTTON1) {
Platform.runLater(new Runnable() {
#Override
public void run() {
if (stateWindow == 1) {
stage.hide();
stateWindow = 0;
} else if (stateWindow == 0) {
stage.show();
stateWindow = 1;
}
}
});
}
}
});
try {
tray.add(trayIcon);
} catch (AWTException e) {
System.out.println("TrayIcon could not be added.");
}
stage.setTitle("Hello man!");
Button btn = new Button();
btn.setText("Say 'Hello man'");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
System.out.println("Hello man!");
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
stage.setScene(new Scene(root, 300, 250));
Platform.setImplicitExit(false);
stage.show();
}
/**
* The main() method is ignored in correctly deployed JavaFX application.
* main() serves only as fallback in case the application can not be
* launched through deployment artifacts, e.g., in IDEs with limited FX
* support. NetBeans ignores main().
*
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}