I have two exit scenarios in my application :-
1) whenever user enters wrong password for 3 consecutive times, my app should exit and gps notifications must start. For this i have written code as follows :-
if(value.length() >= authenticationCode.length() && !value.equals(authenticationCode))
{
dataEnteredEditText.setError("Invalid Code!!!");
dataEnteredEditText.setText(AntiTheftConstant.EMPTY_STRING);
countAttempts++;
if(countAttempts == 3)
{
SharedPreferences.Editor editor = sharedPref.edit();
editor.putBoolean(AntiTheftConstant.USER_AUTHENTICATION_STATUS, false);
editor.commit();
registerForLocationUpdates();
dataEnteredEditText.removeTextChangedListener(this);
startProcessForAuthenticationFailure();
moveTaskToBack(true);
}
}
moveTaskToBack() minimizes my activity and moves it to background. But i don't want this sort of behaviour. I want my application to completely exit with no acitivities in minimized state or in background.
2) User is asked for one time password(OTP) and if he enters correct password GPS notification should stop and my application should again exit. For this scenarion i have written following code:-
if((authenticationCode.equals(sharedPref.getString(AntiTheftConstant.GENERATED_PASSWORD, AntiTheftConstant.DEFAULT_APPLICATION_AUTHENTICATION_CODE))))
{
editor.putBoolean(AntiTheftConstant.USER_AUTHENTICATION_STATUS, true);
editor.commit();
stopService(new Intent(applicationContext, EmailMonitoringService.class));
stopService(new Intent(applicationContext, LocationDetector.class));
AlarmManager am=(AlarmManager)applicationContext.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(applicationContext, TheftAlarmReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(applicationContext, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
am.cancel(pi);
// Intent intent = new Intent(Intent.ACTION_MAIN);
//
// intent.addCategory(Intent.CATEGORY_HOME);
//
// intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// startActivity(intent);
this.finish();
}
I have tried both code blocks below:-
this.finish()
And
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
But none of them is working fine. Both code blocks above are moving my current activity to background but none of them makes my application exit gracefully.
If you see any problem with above approaches please do suggest. Thanks in advance.
finish() will push the application to the background. It doesn't "exit" the application per-se, it rather closes the current activity. If it's the only open activity, it "closes" the application.
Android decides when to actually release the resources associated with the activity and application and good practice says: "let Android decide when to drop the resources".
For more info, read this.
If you really have to clear the application completely (can be dangerous if you don't close certain resources and events first) it can technically be done using android.os.Process.killProcess(android.os.Process.myPid());
try this
You must call this.finish() after super.onCreate(...)
If you want to finish something in an Activity you should just use:
finish();
If you want to finish something in a Fragment you should use:
getActivity().finish();
Related
I'm trying to bring my app from background to foreground. In onHandleIntent() of my custom IntentService class, I have:
Intent intent = new Intent();
intent.setClass(getApplicationContext(), MainActivity.class); // Also tried with "this" instead of getApplicationContext()
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
startActivity(intent);
Now this code works at first sight but I found a scenario where it doesn't work. If you have the app opened and you put it to background via home button and execute startActivity() within ~5 second, there will be a delay before your app will come to foreground. This is a known implementation and you can find the topic discussed on stackoverflow. In this scenario, the app succeeded in coming from background to foreground.
If you repeat the same experiment above, but instead of waiting for the app to come to foreground, go browse (scroll, swipe, etc) around your phone (I was browsing around the google playstore). The result is that startActivity() will get called but the app will not come to the foreground.
I'm not asking for a solution but more of an explanation on why this is happening. Is this intended behavior?
Use the context of your class.
For instance :
Intent intent= new Intent(context, other.class)
Instead of getapplicationContext()
Use the code :
private void startMenuActivity() {
Intent i = new Intent(this, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
finish();
}
the below code works for me,
val login = Intent(applicationContext, SignInActivity::class.java)
login.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
login.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
applicationContext.startActivity(login)
I have an app that will have multiple activities open.
Activity A -> Activity B -> Activity C
I want to logout and close all open activities. I have read many different links that describes how to do this.
On logout, clear Activity history stack, preventing "back" button from opening logged-in-only Activites
Close all running activities in an android application?
The issue for this however is that the Intent Flags only work with API level 11 and above. I have an app that I would like to be made available for API level 8 and above. I know that it goes way back but what is the best way to accomplish this for API level 8?
Or should I just give in and make the minimum level 11?
Intent intent = new Intent(this, LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);``
Did you try this ?
void signOut() {
Intent intent = new Intent(this, HomeActivity.class);
intent.putExtra("finish", true);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // To clean up all activities *not necessary*
startActivity(intent);
finish();
}
from this answer
Okay, you can do one thing get ProcessID of your application and in onDestroy() kill that process. Thats it from this link How to force stop my android application programmatically?
int pid=android.os.Process.myPid();
android.os.Process.killProcess(pid);
you can use alternative told by one of user here using startActivityForResult() and onActivityResult() works fine even on API level 8.
For this u need to use
startActivityForResult() instead of startActivty. and onActivtyResult() for you work.
you say "I want to logout and close all open activities." , Intent.FLAG_ACTIVITY_CLEAR_TOP works on API Level 8 , I have incorporated Logout functionality ,that way in app that is already in store, but there is one difference if I understand you correctly , logout goes to LoginActivity , logout does not kill process or something as this goes against concept of Android. Anyway you can even do this also when you do this as suggested above:
void logout() {
Intent intent = new Intent(this, LoginActivity.class);
intent.putExtra("finish", true);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
And then in LoginActivity you can search for "finish" boolean in extra in onCreate method and finish that activity too.
#Override public void onCreate(Bundle state) {
super.onCreate(state);
if (getIntent().getBooleanExtra("finish", false)) finish();
}
I have an app that include both a complex service and activity UI. The app runs on multiple devices which communicate with each other over WIFI via the service.
Since the app is a prototype/in-development, I want to add support for a "force restart" that will kill the app and re-launch it clean. There is a lot of shared UI stuff that has gotten gummed up depending on the use case, and it would be easier during testing (I have multiple devices) if I could just touch a button to restart the app completely.
So, does anyone have any suggestions on how to:
1) Force close/stop/kill your own app, from within your app.
2) Set a timer/intent that tells the OS to launch your app before you close/stop/kill it.
Any tips would be appreciated! Thank you.
Use the below code for restart the app:
Intent mStartActivity = new Intent(HomeActivity.this, SplashScreen.class);
int mPendingIntentId = 123456;
PendingIntent mPendingIntent = PendingIntent.getActivity(HomeActivity.this, mPendingIntentId, mStartActivity,
PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager mgr = (AlarmManager) HomeActivity.this.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
System.exit(0);
As you can figure out, finish() is what you want to use in order to kill off an activity. A.C.R.'s way would work, however it will only restart your activity, not really kill off the process, and start it back up. If that's what you are looking for, instead of having a dummy Activity that restarts your original Activity, the correct way to do it would be to use flags.
Intent i = new Intent(this, WrapperActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
Those flags will clear your back stack all the way down to the first instance of whatever Activity you are creating, it will kill it, and then create a new one. This is essentially what A.C.R's example is doing, but it's much more concise.
If this isn't good enough for you, In order to do this properly, it's quite a bit of work, and requires more advanced knowledge of the Android system. You'd want to create a service that's running in the background (will need to be a separate process if you want the application level state killed) that you could startup when you wanted to kill the app, have the app kill itself, or have the service kill the app for you, and then have the service launch an intent that would start your activity/application back up.
Hope this helps! Best of luck!
To restart my app, I'm simple doing this and it's working:
Intent i = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
System.exit(0);
If I don't use both flags, it won't work.
(Using Android 11, API 30, Pixel 3 device)
Try the below code for restarting the application.
Intent i = getBaseContext().getPackageManager()
.getLaunchIntentForPackage(getBaseContext().getPackageName());
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
Here is what you need to do:
Create a sticky Service
Kill the app with killProcess call from the Service
The sticky Service will then restart, and you can open your app with an getLaunchIntentForPackage intent
I like to use a Handler to do this off the main UI thread:
private void scheduleForceClose() {
final Handler closeAppHandler = new Handler();
closeAppHandler.post(new Runnable() {
#Override public void run() {
prefs.edit().putBoolean(StringConstants.FORCE_CLOSED_APP, true).commit();
Log.i(TAG, "Gonna force kill the app process completely!");
System.exit(0);
android.os.Process.killProcess(android.os.Process.myPid());
}
});
}
private void scheduleForceOpen() {
final Handler openAppHandler = new Handler();
taskOpenApp = new TimerTask() {
#Override public void run() {
openAppHandler.post(new Runnable() {
#SuppressLint("ApplySharedPref") #Override public void run() {
Intent intent = getPackageManager().getLaunchIntentForPackage("com.company.yourpackagename");
// Reset the force-close flag so that the close timer can begin again
prefs.edit().putBoolean(StringConstants.FORCE_CLOSED_APP, false).commit();
startActivity(intent);
}
});
}
};
// Decide whether we already force-closed the app, so that we don't repeat it
boolean alreadyForceClosed = prefs.getBoolean(StringConstants.FORCE_CLOSED_APP, false);
if (alreadyForceClosed) {
Log.i(TAG, "App process has already been killed, so schedule app relaunch.");
Timer timerOpen = new Timer();
timerOpen.schedule(taskOpenApp, 5000 /* reopen the app after 5 sec */);
}
}
No can do. The operating system decides when to kill an application. Your app can come back to life whether it was truly dead or just hidden.
This is inconvenient, but the platform works like that. You can produce the same user-facing effect by managing your activities, which you can kill and restore.
There might be a more official way to do this, but here's how I would accomplish this.
For example I am going to pretend there are only two Activities, the one you're currently in (I'll call it FirstActivity), and another "helper" Activity (I'll call SecondActivity).
In the first one (the one you want to restart it from), you would have a button that initiates the restart of the app.
restartButton.setOnClickListener(new OnClickListener(){
#Override
onClick(View v){
//when clicked it starts the helper activity and closes the one you're in
startActivity(new Intent(this, SecondActivity.class));
finish(); //or you could use FirstActivity.onDestroy(); if you want it completely dead
}
});
Second Activity: It's entire purpose is so you can basically restart your app from your app (close everything else and then restart it in this)
Class SecondActivity extends Activity{
#Override
onCreate(Bundle savedInstanceState){
...
//it restarts the old activity so it's new and ends this one
startActivity(new Intent(this, FirstActivity.class));
finish(); //or you could use SecondActivity.onDestroy(); if you want it
}
}
That will completely restart the first activity. I'm not sure if it will be as thorough as you wish, but there really isn't another way to do this sort of thing AFAIK.
Is there any way to close android app ? I cannot use finish because it shows previous activity and I have lot off activities behind ( for example from 1st to 2nd .. to 10th and on 10th I want to exit from app ). How to achieve this ?
How about using android:noHistory
Whether or not the activity should be removed from the activity stack and finished (its finish() method called) when the user navigates away from it and it's no longer visible on screen — "true" if it should be finished, and "false" if not. The default value is "false".
A value of "true" means that the activity will not leave a historical trace. It will not remain in the activity stack for the task, so the user will not be able to return to it.
Intent intent1 = new Intent(context, Activity.class);
intent1.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent1);
CLEAR TOP clear your stack of activity and can finish the last activity you redirect
if your activity stack is proper clear top will work for you
OPTION 2:
using Borad cast receiver chk link
I also had the same question and did not find a way to definitelly KILL an app. But later I discovered it is due to the intrinsic nature which the system was designed of.
If you want to close an app, you just have to clear the Activity stack and free the usage resources. It seems strange, right? You should have the power to close your own app. But it is really not recommended on Android apps and it does not follow the Android guidelines. And also, do not provide exit options to users. For Android applications which needs to provide an "exit option" to user (for example, due to security reasons), we should provide a "logout option", clear the Activity stack, free resources and other stuff you want to do, but never kill the Main Activity.
The solutions to clear the Activity stack have been shown for other answers here: (1) to use Intent with flag FLAG_ACTIVITY_CLEAR_TOP or (2) to use Broadcast.
With FLAG_ACTIVITY_CLEAR_TOP, you put an Intent on the current Activity:
Intent intent = new Intent(getApplicationContext(), YourMainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
And the option with Broadcast, is to send a broadcast from the current Activity to all Activities you want to close.
For this, you have to SEND the broadcast (on the current Activity):
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("com.package.ACTION_SPECIFICNAME");
sendBroadcast(broadcastIntent);
finish();
And RECEIVE this broadcast on the others Activities (on each one you want to close):
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.package.ACTION_SPECIFICNAME");
registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("onReceive","Logout in progress");
finish();
}
}, intentFilter);
And that is it! I hope this answer helps you. Sorry for my english.
I know that it is not the answer you were waiting for, but I think that is the current (and the "correct") solution.
You can use (but it's not recommended)
System.exit(0);
or you can move your app in background (that is the way Android manages multitasking)
moveTaskToBack(true);
Place this code on exit button press
Intent intent = new Intent(ExitConfirmationActivity.this, FirstActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
And override the onResume of initial activity with a finish();
I want to quit application in Android. Just put a "quit" button, which kills my app.
I know I shouldn't do this. I know that this is not the philosophy of the OS.
If you know how it can be done, pls share.
In the app, I have many opened activities, so "finish()" will not do the job.
Thank you for your information in advance.
Danail
Way One
android.os.Process.killProcess(android.os.Process.myPid())
Way Two
System.exit(0);
Your answer helped me, Pentium10, but I needed to do one more thing :
I had to clear(close) all my previous activities with
Intent i = new Intent();
i.setClass(this, FirstActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
This means: every activity, started after FirstActivity, is closed. (In other words, this cleans the activity stack above FirstActivity). Then all I have to do is finish my FirstActivity.
Close all the previous activities as follows:
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("Exit me", true);
startActivity(intent);
finish();
Then in MainActivity onCreate() method add this to finish the MainActivity
setContentView(R.layout.main_layout);
if( getIntent().getBooleanExtra("Exit me", false)){
finish();
return; // add this to prevent from doing unnecessary stuffs
}