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);
}
Related
In my app, there are so many activities which are referred to as levels. And one activity is Reward activity. when i win level-1, reward activity opens. Now i want to replay the level-1. For this i have used getExtra(). My app crashes when i click the replay button.
Houselevel1.java
public void getReward(){
if(count == 3) {
Intent intent = new Intent("com.creatives.arfa.revealthesecretsgame.Reward");
intent.putExtra("activity", "level1");
startActivity(intent);
}
}
HouseLevel2.java
public void getReward(){
if(count == 3) {
Intent intent = new Intent("com.creatives.arfa.revealthesecretsgame.Reward");
intent.putExtra("activity", "level2");
startActivity(intent);
}
}
Reward.java
public void replayLevel() {
replay = (ImageButton) findViewById(R.id.replay);
Intent intent= getIntent();
activity = intent.getStringExtra("activity");
replay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View paramView) {
if(activity.equals("level2")){
Intent intent = new Intent("com.creatives.arfa.revealthesecretsgame.HouseLevel2");
startActivity(intent);
}
if(activity.equals("level1")){
Intent intent = new Intent("com.creatives.arfa.revealthesecretsgame.Houselevel1");
startActivity(intent);
}
}
});
}
With the java code you've posted, in the Reward.java file, you're trying to create another Intent Object with the same name as the one declared in the scope right above it. Because of this, the build will never be successful.
Also, when you declare intents, you MUST pass on the activity_name.class file.
Something you can try:
1) HouseLevel1.java
public void getReward(){
if(count == 3) {
Intent intent = new Intent(getApplicationContext(), com.creatives.arfa.revealthesecretsgame.Reward.class);
intent.putExtra("activity", "level1");
startActivity(intent);
}
}
2) HouseLevel2.java
public void getReward(){
if(count == 3) {
Intent intent = new Intent(getApplicationContext(), com.creatives.arfa.revealthesecretsgame.Reward.class);
intent.putExtra("activity", "level2");
startActivity(intent);
}
}
3) Reward.java
public void replayLevel() {
replay = (ImageButton) findViewById(R.id.replay);
Intent intent= getIntent();
activity = intent.getStringExtra("activity");
replay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View paramView) {
if(activity.equals("level2")){
Intent intent = new Intent(getApplicationContext(), com.creatives.arfa.revealthesecretsgame.HouseLevel2.class);
startActivity(intent);
}
else if(activity.equals("level1")){
Intent intent = new Intent(getApplicationContext(), com.creatives.arfa.revealthesecretsgame.Houselevel1.class);
startActivity(intent);
}
}
});
}
Also, if you're simply using the Reward.java file to get the previous intent's data, perform some calculation, and send some data back to the calling, or parent activity, then you can simply use the startActivityForResult() method, which takes care what what you're trying to do manually.
Here's a small article that might be able to help you with the problem
http://www.vogella.com/tutorials/AndroidIntent/article.html#retrieving-result-data-from-a-sub-activity
If all you want is go from Activity 1 or to 2 to a Reward activity grab something and send that something back to either activity.
What you do is startActivityForResult You pass an Id (constant number) do what you do on the Reward activty, pack what you need to return in a Bundle, and set ActivtyResult to OK and close your activity.
Your app will go back to the Activity1 or 2 whoever call it. On those activties you override the method onActivityResult There you check if the id on which the result is coming from is the Id you sent on the startActivityForResult and if the status is OK.
Then you have whatever was set on the Reward activity. The Reward activity don't need to know from where it came from if only will grab some data. So you can later have an Activity3 that calls the Reward activity and you do not need to modify the Reward activity.
It is explain here check the accepted answer.
How to manage `startActivityForResult` on Android?
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"/>
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 have developed application that consists of A activity (luncher), B activity (second), C activity (third),
what i have tried is :
when the screen is locked or turned off as you are away from the device or have pressed the power button to locked it, my goal is C activity finished and when you turn the screen on again A activity start.
Note : i'm new to android and java development .
i think we can use onPause(), method or onStop(), method for that purpose, but it acually does not work with me as below code in C activity :
protected void onPause(){
super.onPause();
Intent i = new Intent(this,A activity);
startActivity(i);
}
when i lock screen and it become black then open again it still has C activity there.
any advice to get that with onPause(), method or onStop(), method or other ways to get it, thanks
in C Activity - onPause method you can try using this code:
new Handler().post(new Runnable() {
#Override
public void run()
{
Intent intent = new Intent(this,A activity);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
overridePendingTransition(0, 0);
finish();
overridePendingTransition(0, 0);
startActivity(intent);
}
this will close current activity and open selected activity.
Hope it helps.
I am not sure but try this way:-
protected void onPause()
{
Intent i = new Intent(this,A activity);
startActivity(i);
super.onPause();
}
example scenario is:
from login screen - main screen - then when i clicked a hide button the app will go to home screen, and when im going to click the app again the main screen would be called
Fire an intent when you want to display the home screen
Intent setIntent = new Intent(Intent.ACTION_MAIN);
setIntent.addCategory(Intent.CATEGORY_HOME);
setIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(setIntent);
So this will be fired on the pressing of your hide button
I think you can use you can use FLAG_ACTIVITY_CLEAR_TOP
FirstActivity is the first activity in the application:
public static void home(Context ctx) {
if (!(ctx instanceof FirstActivity)) {
Intent intent = new Intent(ctx, FirstActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
ctx.startActivity(intent);
}
}
And If you want to exit from the whole application,this help you in that.
public static void clearAndExit(Context ctx) {
if (!(ctx instanceof FirstActivity)) {
Intent intent = new Intent(ctx, FirstActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Bundle bundle = new Bundle();
bundle.putBoolean("exit", true);
intent.putExtras(bundle);
ctx.startActivity(intent);
} else {
((Activity) ctx).finish();
}
}
i Really Hope this helps.