I have three activities A,B & C.
A is Started screen / B is Login screen / C is Main tab bar screen
On A, I can push to B
On B, I can push to C and go back to A
On C, I want to avoid it go back to A, but can push to A (Means logout)
A <---> B ---> C ---> A
How I can achieve that?
A.activity
Intent i = new Intent(StartedActivity.this, LoginActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
StartedActivity.this.startActivity(i);
//finish(); //if i put finish() B cannot go back to A
B.activity
Intent i = new Intent(LoginActivity.this, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
LoginActivity.this.startActivity(i);
finish();
C.activity
//This code is for logout, push to A.activity
Intent i = new Intent(MainActivity.this, StartedActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
MainActivity.this.startActivity(i);
finish();
So now the problem is I can press go back to A. How can i avoid it?
A.activity
Intent i = new Intent(StartedActivity.this, LoginActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
StartedActivity.this.startActivity(i);
B.activity
Intent i = new Intent(LoginActivity.this, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
LoginActivity.this.startActivity(i);
C.activity
Intent i = new Intent(MainActivity.this, StartedActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
MainActivity.this.startActivity(i);
and override method onBackPressed on B.activity
#Override
public void onBackPressed() {
Intent i = new Intent(MainActivity.this, StartedActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
MainActivity.this.startActivity(i);
super.onBackPressed();
}
so now you can apply flow A <---> B ---> C ---> A
one issue here is A will be reset when back from B
hope this helps
Register a BroadcastReceiver in Activity A, and call finish() when you logged in.
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if ("your-action-string".equals(intent.getAction())) {
finish();
}
}
};
Register it in your onCreate method:
#Override
protected void onCreate(Bundle savedInstanceState) {
// ...
LocalBroadcastManager.getInstance(this).registerReceiver(receiver,
new IntentFilter("your-action-string")); // define your own action
}
Unregister it in onDestroy:
#Override
protected void onDestroy() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
super.onDestroy();
}
if you want to go back to the Activity A from Activity C then you set into manifests file.
<activity
android:name=".C"
android:label="#string/appName"
android:parentActivityName=".A"/>
Related
I have created very simple project that contains 3 activities.
activity 1 have a button can go to activity 2
activity 2 have a button can go to activity 3
activity 3 have a button crash
on a crash button and I try set throw exception
buttonCrash.setOnclickListener (new View.OnClickListener() {
#Override
public void onClick(View v){
throw new NullPointerException();
}
});
After crash I click re-open, and activity go back to activity 2. how to every crash the app will restart or clear activity stack?
I try to make handle exception class:
public class MyExceptionHandler implements Thread.UncaughtExceptionHandler {
private Activity activity;
public MyExceptionHandler(Activity a) {
activity = a;
}
#Override
public void uncaughtException(Thread thread, Throwable ex) {
Intent intent = new Intent(activity, MainActivity.class);
intent.putExtra("crash", true);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_CLEAR_TASK
| Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(MyApplication.getInstance().getBaseContext(), 0, intent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager mgr = (AlarmManager) MyApplication.getInstance().getBaseContext().getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, pendingIntent);
activity.finish();
System.exit(2);
}
}
But it's suddenly restart the app, even though I need to show crash dialog first so I can click re-open to open again.
try define your mainactivity home and default. add below code in intent-filter in activity in manifest:
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
Add Activity clear task flag in every activity transition.
Intent intent = new Intent(this,yourclass.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
Add finish() function in your second activity
Try using checking pass through on activity 1
public static boolean DOING_PASS = false;
set DOING_PASS is true inside onStart on activity 1
#Override
void onStart(){
DOING_PASS = true;
}
so You can checking on every activity except activity 1 inside onCreate
if(Activity1.DOING_PASS){
// do normal
}
else{
Intent i = new Intent(this, Activity1.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP || Intent.FLAG_ACTIVITY_CLEAR_TASK || Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
I'm new to Android programming so I might miss something important.
What I want to do is to finish the current activity (ActivityB) and the previous activity (ActivityA).
And the users can switch between ActivityA and ActivityB using FLAG_ACTIVITY_REORDER_TO_FRONT. Now I want to finish ActivityB and the previous ActivityA and start new ActivityA.
However, seems like the previous ActivityA is still running even after finishing ActivityB.
Code is like this.
ActivityA
private void startActivityB() {
Intent intent =
new Intent(ActivityA.this, ActivityB.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
}
ActivityB
private void exitActivityB() {
Intent intent =
new Intent(ActivityB.this, ActivityA.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
#Override
private void onBackPressed() {
// finish ActivityB and the previous ActivityA
Intent intent =
new Intent(ActivityB.this, ActivityA.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
}
What am I wrong with this? How can I finish the previous ActivityA and start new ActivityA?
Try following way
Intent i = new Intent(ActivityB.this, ActivityA.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);
Try this one:
#Override
private void onBackPressed() {
// finish ActivityB and the previous ActivityA
Intent intent =
new Intent(ActivityB.this, ActivityA.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
Try this code
Intent i = new Intent(ActivityB.this, ActivityA.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK |Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
finish();
I have a MainActivity class with 3 Fragments (each in their own class)
My third fragment (LoginFragment) will allow Login a user and then go to a new activity (new Intent) with some info for that user like the product.
If I press back on that Intent will go back to the LoginFragment.
I override the #OnBackPressed to start the MainActivity:
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
this.finish();
I need to know how to replace that Fragment with the LauncherFragment (Fragment 1) in MainActivity.
I have this solution but it takes 0.5 sec to 1-2 sec based on device
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
startActivity(intent);
this.finish();
would be cool to go direct to Fragment 1 like to finish the third fragment thanks :)
I fixed the issue in this idea
onBackPressed() I call a new Intent but with extras
In the MainActivity that has the 3 fragments onRestart() I check if it coming from this class ( has that extras ) than go to this fragment (click,replace,delete)
#Override
public void onBackPressed() {
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra(Constants.Intents.NAVIGATE_BACK, true);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
this.finish();
}
on the MainActivity I got this
#Override
protected void onRestart() {
super.onRestart();
Intent intent = getIntent();
boolean navigate = intent.getBooleanExtra(Constants.Intents.NAVIGATE_BACK, false);
if (navigate) {
View homeView = bottomNavigationView.findViewById(R.id.home);
homeView.performClick();
intent.removeExtra(Constants.Intents.NAVIGATE_BACK);
}
}
If you want it to be as fast as possible, use one activity and fragments to vary the contents. Adding a fragment doesn't create a new window, whereas an activity does.
Also look at your application logic in fragment / activity startup (onCreate(), onResume(), etc). That's going to be the main factor.
I'm trying to build a simple login & registration application in android. My problem is that I want to handle backpressed() but it is not working.
Example: I'm having 3 activities: signin, register and verify. What I need is if we back click on register or verify, the navigation should go to signin and if we back click on signin, the application should close.
I have tried these lines of code but they are not working. They will navigate to previously visited activity.
This code is of signin activity
#Override
public void onBackPressed() {
Intent i = new Intent();
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
finish();
}
This code is of register activity
#Override
public void onBackPressed() {
Intent i = new Intent(getBaseContext(), LoginActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
What I need is that if we back click on register or verify, the
navigation should go to signin and if we back click on signin, the
application should close.
To go to SignInActivity onBackpressd() from Verify and RegisterActivity:
#Override
public void onBackPressed() {
Intent i = new Intent(this, SignInActivity.class);
finishAffinity();
startActivity(i);
}
In SignInActivity:
#Override
public void onBackPressed() {
finish();
}
Hope this helps.
If you're building for API>16
#Override
public void onBackPressed(){
finishAffinity();
super.onBackPressed();
}
This works for sure!!
#Override
public void onBackPressed() {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finishAffinity();
System.exit(0);
}
Finish will always go to the previous activity on the stack. The intent flags need to be set when your activity is LAUNCHED, not when your activity is being killed.
I have a stack of activities like A->B->C->D... Back function is enabled on all activities. Now on a specific action on activity D, I would like to move to activity B i.e. D&C gets finished now and activity B is resumed. How to achieve such transition ?
From Activity D, call Activity B with proper flags in the Intent. Intent.FLAG_ACTIVITY_CLEAR_TOP should do it.
Example code:
Intent intent = new Intent(this, B.class)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
finish();
If you want to follow proper and ideal flow , go for "onActivityResult" method. Suppose for your example when B goes to C, at that time it will start activity C using startActivityForResult and when C goes to D then again C will use statActivityForResult to go do D.
For your case,
public class B extends Activity
{
public static int RESULT_CODE=111;
public void onCreate(Bundle SavedInstance)
{
...
....
Intent intent = new Intent(B.this,C.class);
startActivityForResult(intent,REQUEST_CODE);
}
public void onActivityResult(int requestCode,int resultCode,Intent data)
super.onActivityResult(requestCode, resultCode, data);
if(requestcode == C.RESULT_OK)
{
//do you work when D is finished and comes back to B
}
}
public class C extends Activity
{
public static int RESULT_CODE=222;
public void onCreate(Bundle SavedInstance)
{
...
....
Intent intent = new Intent(C.this,D.class);
startActivityForResult(intent,REQUEST_CODE);
}
public void onActivityResult(int requestCode,int resultCode,Intent data)
super.onActivityResult(requestCode, resultCode, data);
if(requestcode == D.RESULT_OK)
{
setResult(RESULT_OK);
}
}
public class D extends Activity
{
public static int RESULT_CODE=333;
public void onCreate(Bundle SavedInstance)
{
...
....
}
//your back click function
public void onBackClick(View v)
{
setResult(RESULT_OK);
}
Just to clarify, use this API < 11:
Intent intent= new Intent(this, Login2.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK |Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(Intent);
In API level 11 a new Intent Flag was added just for this: Intent.FLAG_ACTIVITY_CLEAR_TASK
Intent intent= new Intent(this, Login2.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(Intent);
Try adding this code inside some action of D Activity
C close = new C();
close.finish();
D.this.finish();
And in activity tag of manifest file add this attribute
android:launchmode="singleTop" //Or singleTask
So that you can close both c and D activity and resume into B.