Android exit app on close - java

Hi in my android app I included a splash screen after this activity whenever I pressed the back button it is going to the previous pages of MainActivity. But I needed to exit from application if user press back button from MainActivity. But now currently mainactivity is not the start activity and splash screen is the activity. So i checked some methods and I saw
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
this will clear the previous activities.. But in MainActivty why I need an intent.. I gave
finish();
in every intent of each activity so the activity will be cleared. But that is affecting my app's entire structure .. whenever user press back button app is going to home page. So any one suggest a solution.. so that I can exit directly from MainActivity if user presses a back button.
this is my backpress code for mainActivity
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
finish();
}
and my splashscreen
WebView wv;
// Splash screen timer
private static int SPLASH_TIME_OUT = 4000;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_flash);
wv = (WebView) findViewById (R.id.webView1);
wv.setHorizontalScrollBarEnabled(false);
wv.loadUrl("file:///android_asset/Finally-320.gif");
new Handler().postDelayed(new Runnable() {
/*
* Showing splash screen with a timer. This will be useful when you
* want to show case your app logo / company
*/
#Override
public void run() {
// This method will be executed once the timer is over
// Start app main activity
Intent i = new Intent(SplashScreen.this, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
// close this activity
finish();
}
}, SPLASH_TIME_OUT);
}
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
finish();
}
}

for your query:
But I needed to exit from application if user press back button from MainActivity.
For that you need to write this in MainActivity
#Override
public void onBackPressed() {
finish();
}
Update:
put this line to exit from app:
moveTaskBack(true);

use System.exit(0) in onBackPressed() like this:
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
System.exit(0);
}

Related

How to disable On Click Listener created in onCreate, in onPause? (In Android Studio)

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.

Handle calls of onStart and onStop only from outside my app

I want to make a cloud synchronization everytime my app is brought to front and a second time if the app disappears in background.
So I overwrote the onStart and onStop event methods of my activity:
#Override
protected void onStart() {
super.onStart();
doSync();
}
#Override
protected void onStop() {
doSync();
super.onStop();
}
Ok, that works fine for me but I found out that these methods are also called if I start a new activity (f.e. SettingsActivity.class) within my app (onStop) and come back to the main activity (onStart).
Is there a good way to ignore the calls of my own activities and only react on calls from "outside", f.e. I only want to synchronize if the user stops the app by pressing the home button and I also want to synchronize only if the user returns to the app by starting it from the app dreawer or app switcher?
+++ SOLUTION +++
Now I found a solution for my problem and I want to share it. Maybe it's not the best way because it's no SDK-based functionality but it works and it's quite simple.
I declared a flag, set it to false when the activity is created. Everytime I start another activity in the same app, I will set the flag to true and check its state in onPause and onResume.
public class MainActivity extends Activity {
private boolean transition;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
transition = false;
}
private void startSettingsActivity() {
transition = true;
Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
}
private void doSync() {
// all steps for the cloud synchronization
}
#Override
protected void onResume() {
super.onResume();
if (!transition) {
// this is the case the user returns from
// the app drawer or app switcher or starts
// the app for the first time, so do sync
doSync();
} else {
// this is the case the user returns from another
// activity, so don't sync but reset the flag
transition = false;
}
}
#Override
protected void onPause() {
if (!transition) {
// this is the case the user presses the home button or
// navigate back (leaves the app), so do final sync
doSync();
} else {
// this is the case the user starts another activity, but
// stays in the app, so do nothing
}
super.onPause();
}
}

onBackPressed() not working while coming from another activity

I have three activities: First, Second and Third. I used this method in Second activity:
public void onBackPressed() {
super.onBackPressed();
finish();
}
and this on Third activity:
public void onBackPressed() {
super.onBackPressed();
Intent i = new Intent(Third.this, Second.class);
startActivity(i);
finish();
}
The problem is when I press back button after coming from the Third activity, I am going into First activity instead of finish(). I am successfully exiting the application when I click back button right after coming from first activity but not after coming from Third activity.
How to solve this problem?
EDIT: Thanks for the answers guys,the answer of "Ved Prakash" solved the problem for me.But i have a weird problem now.When i press back button the app is successfully exiting but the app which i minimized to Recent Apps button is coming on to the screen and exiting.For example,if i have opened Setting app before opening my app,when i press back button,my app is exiting and immediately Settings app is also opening and exiting itself.What might be the problem?
Your problem is that you don't seem to understand how Activities work. The finish() function ends the current Activity, and then you receive the previous Activity from the backstack.
My recommendation is that you should use a single Activity, and hold Fragments inside it. If you want it so that pressing the Back button ends the application at any screen that is displayed, you could do the following:
Activity XML:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/initial_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Activity that holds the Fragments:
public class InitialActivity extends FragmentActivity implements ReplaceWith
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_initial);
getSupportFragmentManager().addOnBackStackChangedListener(new OnBackStackChangedListener()
{
public void onBackStackChanged()
{
int backCount = getSupportFragmentManager().getBackStackEntryCount();
if (backCount == 0)
{
finish();
}
}
});
if (savedInstanceState == null)
{
getSupportFragmentManager().beginTransaction().add(R.id.initial_container, new FirstFragment()).commit();
}
}
#Override
public void replaceWith(Fragment fragment)
{
getSupportFragmentManager().beginTransaction().replace(R.id.initial_container, fragment).commit();
}
}
Example for a Fragment:
public class FirstFragment extends Fragment implements View.OnClickListener
{
private ReplaceWith activity_replaceWith;
private ImageView exampleImage;
public FirstFragment()
{
super();
}
#Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
try
{
activity_replaceWith = (ReplaceWith) activity;
}
catch (ClassCastException e)
{
Log.e(getClass().getSimpleName(), "Activity of " + getClass().getSimpleName() + "must implement ReplaceWith interface!", e);
throw e;
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.fragment_first, container, false);
exampleImage = (ImageView) rootView.findViewById(R.id.fragment_first_example_image);
exampleImage.setOnClickListener(this);
return rootView;
}
#Override
public void onClick(View v)
{
if(v == exampleImage)
{
activity_replaceWith.replaceWith(new SecondFragment());
//please note that this should be done only if you are planning
//only on single-screen applications
//with no other layouts based on orientation or size
//otherwise, the Activity needs to be responsible for this, not the Fragment
}
}
}
This way, when you press the Back button, your application would end from any displayed screen.
Ok your code is wrong.
If you will look at activity source, you see that activity.onBackPressed() is calling finish(). So if call super.onBackPressed() you don't need to call finish.
Finish() is not stopping your application, it's stopping current activity.
Your code on third activity very strange. You are trying to stop activity and start another same activity.
What exactly you want to achieve?
If you want to exit application from your third activity, you need to clear your backstack. But I think you have problem with structure of your app.
Ok. then you should finish your first activity when you go to second activity like this(If you are using intent for that):
Intent it=new Intent(FirstActivity.this,SecondActivity.class);
finish();
startactivity(it);
and same for Second Activity:
Intent it=new Intent(SecondActivity.this,ThirdActivity.class);
finish();
startactivity(it);
this done your work...when you are in third activity the above activities are finished..
and when you press backButton you will be exit from application..
Good luck.
You can use -
public static final int FLAG_ACTIVITY_CLEAR_TOP
If set, and the activity being launched is already running in the
current task, then instead of launching a new instance of that
activity, all of the other activities on top of it will be closed and
this Intent will be delivered to the (now on top) old activity as a
new Intent.
And here is how -
When the user wishes to exit all open activities, they should press a button which loads the first Activity that runs when your app starts, in my case "MainActivity".
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("EXIT", true);
startActivity(intent);
The above code clears all the activities except for LoginActivity. LoginActivity is the first activity that is brought up when the user runs the program. Then put this code inside the LoginActivity's onCreate, to signal when it should self destruct when the 'Exit' message is passed.
if (getIntent().getBooleanExtra("EXIT", false)) {
finish();
}
This explanation part is also introduced at exit-an-android-app.

android async splash screen not showing content view

in my app the main page contains, quite a few images to load on my upload manager activity so it can take a few seconds, depending on how many images there are. i planned on creating a splashscreen to do this loading while displaying an image which is not as bad as the default blank screen with title. i have done this, which should work and does, except the setcontentview() does run but does not display.
public class SplashScreen extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_screen);
load l=new load();
l.execute(this);
}
class load extends AsyncTask<Activity, Object, Object>{
#Override
protected Object doInBackground(Activity... a) {
// TODO Auto-generated method stub
Log.i("ss", "splash");
Intent intent = new Intent(a[0], UploadManager.class);
startActivity(intent);
a[0].finish();
return null;
}
}
}
does anybody have any suggestions?
and feel free to ask for details i don't think i have explained it all too well.
edit:
thank you guys for the quick responses.
however i believe the problem was that i wasn't using a splash screen for the correct purpose,
the processes involved in:
Intent intent = new Intent(a[0], UploadManager.class);
startActivity(intent);
a[0].finish();
seem to finish instantly, meaning the images in my onCreate method weren't executing until after the splash screen. what i did instead is changed the loading of my grid into an asynktask, as apposed to just doing my images in there.
i now have it loading fast with the images appearing after a few seconds. i shall be implementing a progress dialog of some sort.
anyone else with a similar problem should prioritize making the loading more efficient as i have.
You are passing Context as this in l.execute(this) and in class load you've passed Activity instance.
You can do it in this way and it works like a charm for me
public class SplashScreen extends Activity{
private static int SLPASH_TIME_OUT = 3000;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
Intent i = new Intent(SplashScreen.this, MainActivity.class);
startActivity(i);
finish();
}
}, SLPASH_TIME_OUT);
}
}
Override onPostExecute method in class load extends AsyncTask<Activity, Object, Object>{ class, which will run when your doInBackground method finishs image downloading.
In onPostExecute you can open your next activity
like
protected void onPostExecute(Void unused) {
Intent intent= new Intent(this, next.class);
startActivity(intent);
}

background music automatically stops

I have made an application with Splash Music. But whenever I go in preferences of app, the music automatically stops, and then never plays untill I restart the application. Same is the case when I open an activity, which tells whether phone is in "Normal" or in "Silent" Mode.
What is the reason for this weird behavior?
Here is the Splash music code where I check whether to play music or not..
public class SplashScreen extends Activity{
MediaPlayer mp;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.splashscreen);
mp= MediaPlayer.create(SplashScreen.this, R.raw.got);
SharedPreferences pref= PreferenceManager.getDefaultSharedPreferences(getBaseContext());
;
if(pref.getBoolean("music", true))
{
mp.start();
}
if(pref.getBoolean("loop", true))
{
mp.setLooping(true);
}
Thread timer= new Thread()
{
public void run()
{
try
{
sleep(5000);
Class ourclass = Class.forName("com.umer.practice2.Menu");
Intent myintent= new Intent(SplashScreen.this,ourclass);
startActivity(myintent);
}
catch(Exception e)
{
e.printStackTrace();
}
}
};
timer.start();
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
finish();
}
}
Thanks
It is because you are creating and playing your mediaplayer object on the main thread. When your activity is getting paused, you are finishing the activity which is stopping your mediaplayer. If you want to keep you music independent of the activity, offshore it to a service.
Running in a Service should help you.

Categories

Resources