I have spent almost the day trying to figure it out and yet could not manage to achieve it. I basically have two activities, MainActivity.java and GameActivity.java. The music stops but after going back to MainActivity.java and coming back to GameActivity.java using ImageView several times.
MainActivity.java
public class MainActivity extends AppCompatActivity {
ImageView iv;
public static final String BG_SOUND_CHECK = "background playing!";
// public static MediaPlayer backgroundSound;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Handler handler = new Handler();
final MediaPlayer backgroundSound = MediaPlayer.create(this, R.raw.background_music);
handler.postDelayed(new Runnable() {
#Override
public void run() {
backgroundSound.setLooping(true);
backgroundSound.start();
Log.v(BG_SOUND_CHECK, "After loop Started!");
}
}, 3000);
getSupportActionBar().hide();
iv = (ImageView)findViewById(R.id.playImage);
iv.setOnClickListener(new View.OnClickListener(){
public void onClick(View view1){
// backgroundSound.setLooping(false);
backgroundSound.pause();
// Log.v(BG_SOUND_CHECK, "Playing After Play Button Click");
Intent myIntent = new Intent(MainActivity.this, GameActivity.class);
// myIntent.putExtra("backgroundSoundObj",backgroundSound);
startActivity(myIntent);
// Log.v(BG_SOUND_CHECK, "After Game Scene");
}
});
}
}
GameActivity.java
public class GameActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
// MainActivity.backgroundSound.pause();
// Rest of the code
}
}
I tried putting the music onPause(); in
1) ImageView onClick();
2) As soon as the GameActivity.java is loaded
but both ways end up pausing it only after I try coming back to MainActivity.java and going to GameActivity.java several times.
Do you see how you put your backgroundSound.start() inside the postDelayed-3000 ?
backgroundSound.pause() anytime before that 3000ms is not going to do anything.
It has nothing to do with going back and forth between your two activities, it just so happens that doing that takes up more than 3000ms, so when you do click for pause(), 3000ms has passed.
What you can do, to fit your current code, is to separate that into a Runnable.
Runnable bgSound = new Runnable() {
#Override
public void run() {
backgroundSound.setLooping(true);
backgroundSound.start();
Log.v(BG_SOUND_CHECK, "After loop Started!");
}
}
Use it with handler.postDelayed(bgSound, 3000)
In your onClick, if you want to stop it from playing before it starts, can use handler.removeCallbacks(bgSound), to stop it after it plays, your pause(). If you don't care to know if it has or hasn't started, you can do both alongside each other, should work fine too.
(if you don't want the music to play after you've left your main activity, you should also do the same actions in your onDestroy and/or onPause)
Related
In Android Studio, I am trying to open the second activity when corresponding button is pressed.However, I cannot reach that listener that I create in "onCreate" from onPause. I am following an approach like this:
public class MainActivity extends Activity {
private View.OnClickListener openSecondPage = new View.OnClickListener() {
#Override
public void onClick(View v) {
Button button_newPage = findViewById(R.id.button_newpage);
button_newPage.setText("Clicked");
Intent secondPage = new Intent(getApplicationContext(), SecondActivity.class );
startActivity(secondPage);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button_newPage = findViewById(R.id.button_newpage);
button_newPage.setOnClickListener(openSecondPage);
}
public void onPause(){
super.onPause();
Button button_newPage = findViewById(R.id.button_newpage);
//Destroy the on click listener
button_newPage.setOnClickListener(null);
}
}
Also user will be able to come back to main activity and then go back to the second activity again. In that case I don't want to open a new activity. Instead I want to open previously created activity. For that case should I create a onResume() method and in that, call startActivity(secondPage). But in that case, since the secondPage is declared in onStart I won't be able to use in onResume. How can I handle that situation?
So there are actually 2 questions.. sorry about that, I didn't want to open 2 different questions for it.
Put Button button_newPage = findViewById(R.id.button_newpage); and button_newPage.setOnClickListener(openSecondPage); inside onResume instead of onCreate, like so:
#Override
protected void onResume() {
super.onResume();
Button button_newPage = findViewById(R.id.button_newpage);
button_newPage.setOnClickListener(openSecondPage);
}
That should solve at least part of your problem.
I`m trying to build an app, and one activity is "Radio" where I have a streaming online Radio. If i click play, everything works fine, it plays, when I click stop, it stops. But the problem is when I change the activity, ex: from "Radio" to "Home", or "Contact" and come back to "Radio", radio still runs, and if I want to stop it, doesn't work. but if I hit play, the music duplicates and therefore I have the same radio open two times. It looks like the application doesn't know that Radio already runs. Do I need a service object, or what? If I need a service can someone explain me where exactly in the code should I implement it? Here is my Java code:
public class radioActivity extends AppCompatActivity {
int length;
Button b1;
private Button Button1;
private Button Button2;
private String STREAM_URL = "http://192.99.35.93:6370/;stream.mp3";
private MediaPlayer mPlayer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_radio);
Button button1 = (Button) findViewById(R.id.buttonpredica1);
Button button2 = (Button) findViewById(R.id.buttonpredica2);
mPlayer = new MediaPlayer();
mPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
WifiManager.WifiLock wifiLock = ((WifiManager) getSystemService(Context.WIFI_SERVICE))
.createWifiLock(WifiManager.WIFI_MODE_FULL, "mylock");
wifiLock.acquire();
wifiLock.release();
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
mPlayer.reset();
mPlayer.setDataSource(STREAM_URL);
mPlayer.prepareAsync();
mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mPlayer) {
mPlayer.start();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
});
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mPlayer.stop();
}
});
Your MediaPlayer is being created each time you click on start button, so multiple instance of MediaPlayer are playing Radio
If you dont want your MediaPlayer to be running when you switch Activities you can call mPlayer.stop(); in onPause() of your Activity
You can have a couple of options here, one would be to create a Singleton Instance of your MediaPlayer object so when you go to and fro from your RadioActivity, the same instance of the MediaPlayer Object is being used which will help you control the MediaPlayer
Singleton design pattern in Java. Singleton Pattern says that just"define a class that has only one instance and provides a global point of access to it". In other words, a class must ensure that only single instance should be created and single object can be used by all other classes.
Is it possible to create a background thread using andriodannotations thats starts in one activity and finish in another activity.
here is what i thought migh have worked
ActivityA
public static LoadingDialog LoadingScreen = new LoadingDialog();
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//.....
LoadingScreen.CreateDialog(context);
}
Background Class
public class LoadingDialog
{
private Dialog loader_dialog;
#Background
public void CreateDialog(Context mContext)
{
loader_dialog = new Dialog(mContext,android.R.style.Theme_Black_NoTitleBar_Fullscreen);
loader_dialog.setContentView(R.layout.loading_screen);
loader_dialog.show();
}
public void Remove()
{
loader_dialog.dismiss();
}
}
the dialog displays correctly but when I finish() activityA to start activityB the thread appears to be killed to and i get a black screen. Any help on this would be much appreciated.
I have two simple activities MainActivity and ThreadActivity. I call ThreadActivity from MainActivity.
The code ofMainActivity:
public class MainActivity extends Activity {
private Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button)findViewById(R.id.btn2);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, ThreadActivity.class);
startActivity(intent);
}
});
}
}
And the code of ThreadActivity:
public class ThreadActivity extends Activity{
private Thread myThread=null;
Button btn;
int i = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.custom);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
runThread();
}
});
}
void runThread(){
myThread = new Thread() {
public void run() {
while (i++ < 1000) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
btn.setText("#" + i);
Log.d("Thread", "I am running " + i);
}
});
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
return;
}
}
}
};
myThread.start();
}
}
When I start ThreadActivity I run a simple thread and change button text.
My Problem
When I loose focus from application, i.e when application becomes partially visible, and I come back I am redirected to ThreadActivity and the thread is still running.
When I leave application running and open a new application, and then come back, I am again redirected to ThreadActivity.
The problem is when I press back button, I am being redirected to first activity MainActivity. But instead when back button is being pressed I want my application to exit. In a few words MainActivity should not exist in the stack.
I tried setting android:noHistory="true" for MainActivity but I could not keep the behavior explained in bullet points working. I mean when I pause the application and restore it back, it redirected me to MainActivity instead of ThreadActivity.
Just call finish() when starting the ThreadActivity:
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, ThreadActivity.class);
startActivity(intent);
finish();
}
});
BUT there is a problem with your app. Use a Timer to set the text of the Button! By using a Thread like you do you are creating a memory leak and that is very bad. Try this:
private int i = 0;
private Timer timer;
private final TimerTask timerTask = new TimerTask() {
#Override
public void run() {
btn.post(new Runnable() {
#Override
public void run() {
btn.setText("#" + i++);
}
});
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.custom);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
timer = new Timer();
timer.schedule(timerTask, 300, 300);
}
});
}
#Override
public void onPause() {
super.onPause();
if(timer != null) {
timer.cancel();
}
}
From your comments to other peoples' answers, it seems like you want the ThreadActivity to always be resumed instead of the MainActivity when your thread is running.
Do the thread in a Service - the service will mean your application's VM is likely to be kept alive longer. An app with no foreground activities can be killed off quite quickly (even if it has background threads running).
You need to persist that the thread is running, and the progress (if, in the real code that is applicable). Currently you could persist the value of i in your while loop.
Your application's default launcher activity (MainActivity) will launch when you click on it from your launcher. Check if the persisted value has been set, and act as though the user started the ThreadActivity in onCreate, if you finish() in onCreate, the user won't see any UI from the MainActivity
Depending on what you're actually trying to do, you might be able to resume the thread depending on the progress persisted - in this example, you could start from the persisted value of i (instead of 0).
What I had to is set android:noHistory="true" for MainActivity and in the ThreadActivity I had to add the solution mention by #NeTeInStEiN in this quesiotn
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
moveTaskToBack(true);
return true;
}
return super.onKeyDown(keyCode, event);
}
I tried making my first android app. It works well but strangely when I pause then resume the main activity (basically when showing the settings menu) the application FPS decrease a lot, and I've no clue why.
Here is my structure:
DrawView is a class implementing the View class with an "update" method which does the stuff at each frame (calculating and drawing).
The main activity create a DrawView (as content view) and with a Handler and a Runnable requests it to refresh every 10ms.
Here is the (simplified) code of Main.java:
public class Main extends Activity {
DrawView drawView;
private Handler myHandler;
private Runnable myRunnable = new Runnable() {
public void run() {
drawView.update();
myHandler.postDelayed(this, 10);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
drawView = new DrawView(this);
setContentView(drawView);
myHandler = new Handler();
myHandler.post(myRunnable);
}
#Override
protected void onPause() {
super.onPause();
if(myHandler != null) myHandler.removeCallbacks(myRunnable);
}
#Override
protected void onResume() {
super.onResume();
if(myHandler != null) myHandler.post(myRunnable);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId())
{
case R.id.menu_close:
finish();
break;
case R.id.menu_settings:
Intent settingsActivity = new Intent(getBaseContext(), Preferences.class);
startActivity(settingsActivity);
}
return super.onOptionsItemSelected(item);
}
}
By implementing a FPS counter in the DrawView.update method, I noticed that the FPS drop from 100+ at the begining to a ceiling of 60 after opening then closing the preferences Activity.
I don't understand where is my mistake.
The reason is simple: you post your Runnable object twice (in onCreate and onResume methods) and DrawView.update() actually will be called more often than once per 10 ms.
When Activity is paused you call myHandler.removeCallbacks(myRunnable) and it removes BOTH previously added objects. After Activity is resumed you post the Runnable again but only once (because 'onCreate' is not called).