I have a problem with resume Activity. I have a MainActivity which contains other activities. Each one contains a radio station. I have a button (Play) in each activity, and when the user clicks on it, the button changes its function to Stop, so it turns to Stop button. My problem is that when I go for example from Activity(B) to MainActivity and then return to Activity(B) instead of the Stop button, it shows again the Play button, and if the button is pressed, the player plays the same station again at the same moment. I tried to resume the activity using flag, but that didn't work.
My code looks like this:
if (position == 3) {
Intent intent = new Intent(RadioActivity.this, Taraf.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
}
And the manifest looks like this:
<activity
android:name=".SettingsActivity"
android:launchMode="singleTop"
android:screenOrientation="portrait">
</activity>
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:launchMode="singleTop">
</activity>
You should save the status of your button in sharedPreferences, and retrive it when you return to Activity(B), then reset your button according to status of the button saved in sharedpreferences.You can refer to this documentation.
you have to save the state somewhere whether in shared preferences or any other storage.
An d when you are returning to your activity you can retrieve this data.
Related
In my app, I want to prevent the user from going back to login activity after logging in, but I don't want to close the app. For example if the previous activity is login activity, I don't want to do anything when the user presses back, just stay in the current activity/fragment.
add finish(); in login activity and add onBackPressed in your next activity
#Override
public void onBackPressed() {
}
Add android:noHistory="true" in the manifest of your LoginActivity
<activity android:name=".LoginActivity" android:noHistory="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
The correct way to do this is to call finish() in the Login activity when it completes and launches the next activity. For example:
Intent intent = new Intent(LoginActivity.this, NextActivity.class);
startActivity(intent);
finish();
This would prevent the user from going back from NextActivity to LoginActivity since calling finish() destroys LoginActivity and removes it from the back stack.
There is no need to remove onBackPressed from NextActivity, and that may have unintended consequences (for example, if they navigate from Login -> Next -> Other -> Next then click back, they would expect to go back to Other). Disabling onBackPressed in Next would prevent that.
From my MainActivity (Launcher Activity) I press a button to start my GameActivity. I have it so when I hit the Back button in Game Activity, I don't return to my MainActivity and instead return to my home screen. Now when I resume my app it goes to MainActivity instead of returning to GameActivity despite being shown.
Goal
Main Activity -> Game Activity -> Home -> Game Activity
Current Result
Main Activity -> Game Activity -> Home -> Home Activity
A couple things..
It works perfectly when I navigate with my home and menu buttons.
I have no launchMode in my Manifest
So let us see what I have done!
Main Activity Button Click
Button startButton = findViewById(R.id.buttonStart);
startButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, GameActivity.class);
//stops back button to return to add player screen
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
});
Manifest Simplified
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".MainPage.MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar"
android:screenOrientation="portrait"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".GamePage.GameActivity"
android:label="#string/title_activity_game"
android:theme="#style/AppTheme.NoActionBar"
android:screenOrientation="portrait" />
</application>
In that case, just call finish() right after launching you GameActivity.
Button startButton = findViewById(R.id.buttonStart);
startButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, GameActivity.class);
startActivity(intent);
finish();
}
});
Edit: Update launchMode for your GameActivity also:
<activity android:name=".GameActivity" android:launchMode="singleInstance">
when you tap on the back button of device the method onBackPress is called, you can override him to redirect user according your necessity, which mean you can change the action for the Back Button, Code:
//When Back Button on click, it will come to this method.
#Override
public void onBackPressed() {
//Do anything you want here,
}
It doesn't seem like this is possible to do using the conventional back-stack mechanism. You can't return to the home screen using the back button without popping off all the Activities in your back-stack first (hence destroying them, if you have no memory leaks).
Then, when you click the menu button, a screenshot of your last displayed Activity should be shown, but since all of your Activities are destroyed your launcher Activity is loaded.
One way you can handle re-entering the app at the point of your choosing is by implementing a navigation Activity (in many cases this is a splash screen) as the launcher Activity. In this Activity, you would determine (using persistent storage i.e. SharedPreferences) which Activity/back-stack state the app should be set to.
For this example, you could store a boolean with key isInGame in SharedPreferences when you enter GameActivity. Then in the navigation activity, you can retrieve the value and launch GameActivity if true. Obviously, for handling game/app state you will have to store a lot more, but this demonstrates simple navigation.
Hi I have 2 activities,
Activity A and Activity B,
So its Activity A and on a Button click I go to Activity B.
Now I press home button and go and do somany other things. Because of memory issue the task is closed by android. Now when I try to open it again it starts from Activity B. Is this expected?
If yes is there a way to prevent it?
Below is the part of AndroidManifest where both activities are defined
Activity A = MenuActivity, Activity B = AndroidLauncher
<activity
android:name=".AndroidLauncher"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:label="#string/app_name"
android:finishOnTaskLaunch="true"
android:screenOrientation="portrait" >
</activity>
<activity
android:name=".MenuActivity"
android:clearTaskOnLaunch="true"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Also I am putting the code of onCreate of Activity B
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game_view);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
int gameType = getIntent().getIntExtra("GAME_TYPE", 0);
GDXtoAndroidInterface.sharedInstance().activity = this;
TurnBasedHelper.sharedInstance().listener = this;
FrameLayout lg=(FrameLayout)findViewById(R.id.layout);
lg.addView(initializeForView(new LetterPress(GDXtoAndroidInterface.sharedInstance(),gameType), config));
busyDialog = new ProgressDialog(this);
busyDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
busyDialog.setCanceledOnTouchOutside(false);
busyDialog.setCancelable(false);
showBusy("Setting up..");
Log.d("MSG", "on create called launcher");
}
Also the reason why I need this is Activity A is like a login screen and Activity B is based on it. Activity B cannot work alone. User has to move from Activity A to Activity B
Thanks
when I try to open it again it starts from Activity B. Is this expected?
yes, this is the expected behavior.
when you press the home button (not the "back button") the entire task is sent by default to background, and when re-launching it (from recent tasks screen or the app icon at the home screen) it coming back by default to foreground with the same stack state as it was. same behavior applies also if your app was killed by the system while it was in background to preserve memory. the operating system will store the state of each activity in the stack, an restore it when it need to re-created (see this post)
you can think of the home button in relation to Activity like the relation in Windows OS terms as the "minimize" window button, and back button would be like the "close window" (x) button.
there a way to prevent it?
assuming you have good reason to do so and break this consistence expected behavior, you can use all kind of combinations between activity launch mode and intent flags that will give you the behavior you want..
I am developing simple application with only two activities.
Activity C configures application
Activity A for interaction with user when some event occur
It is not possible for user to navigate from the one to the other - this is why I call them independent activities. Further more activity A is being invoked only form event, there is no way for user to do it manually.
Problem. Let's assume that application is properly configured. Some event occurs in the system, so application A is being shown to the user. The user interact with it and activity goes to background. Then the user decides to launch configuration activity C. Activity C is shown to the user. The user uses back button to "close" activity, but instead of android launcher or desktop the user is being shown activity A (taken from history).
Similar scenario might happen the other way. C is being used by user, then taken to background. Some event shows activity A and user using back button goes to C instead of closing activity A.
I have solved the problem, but the solution is pretty dirty. Is there any clean or standard way of solving such problem?
Part of my solution includes what was suggested in one answer:
snippet from AndroidManifest.xml:
<activity
android:name=".C"
android:clearTaskOnLaunch="true"
android:excludeFromRecents="false"
android:launchMode="singleTask"
...
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:exported="false"
android:name=".A"
android:excludeFromRecents="true"
android:noHistory="true"
android:launchMode="singleInstance"
android:clearTaskOnLaunch="true"
....
>
</activity>
snippet from activity A:
public boolean onKeyUp(final int p_keyCode, final KeyEvent p_event) {
switch(p_keyCode) {
case KeyEvent.KEYCODE_ENDCALL:
case KeyEvent.KEYCODE_HOME:
case KeyEvent.KEYCODE_BACK:
case KeyEvent.KEYCODE_MUTE:
case KeyEvent.KEYCODE_POWER:
this.finish();
break;
....
}
return super.onKeyUp(p_keyCode, p_event);
}
snipped from event handler:
public class H extends BroadcastReceiver {
...
Intent intent = new Intent(p_context, A.class);
intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
p_context.startActivity(intent);
...
}
It works for my application. However I want application (activity C) to appear in Recent application. But once activity A is invoked application is removed from Recent.
I don't know if this is the cleanest way to do this, but you can override the void onBackPressed() activity method. This way you can mannually move your activity to the background, like this, and prevent the previous activity from popping in:
public void onBackPressed () {
moveTaskToBack (true);
}
Edit: Turns out there's a better way to do this:
Open your AndroidManifest.xml, and inside each declaration put the following: `android:noHistory="true"``. Doing so will tell Android that your activity does not leave a history, and therefore, when the user hits back Android will quit the application, since there's no other activity for it to return to.
I have two activities, Activity1 and Activity2. Activity1 is launcher activity which starts at the beginning. Now when I'm pressing Home button from activity2 and again opening the app from all apps then Activity1 is opening. I want to open the same activity that was opened at the time of pressing the home button. I need to save state of activity2, but how I don't have any clue.
I looked at this and this but still I didn't got the clear picture on how to do this. Please help me as I'm new to android.
When you pressed "home" button, your activity goes to onPause().
So I personally recommend you to override the onPause() method which can not only handle the "home" button pressed but also other circumstances.
In your case, it is only onPause() and onResume() related, so you can try put the state into SharedPreferences or Internal/External storage.
say:
in your onPause() method, do something like:
// Use Shared Preferences to save data
SharedPreferences previewSizePref = getSharedPreferences("PREF",MODE_PRIVATE);
SharedPreferences.Editor prefEditor = previewSizePref.edit();
prefEditor.putInt("x", somethingA);
prefEditor.putInt("y", somethingB);
prefEditor.commit();
and in your onResume(), retrieve the saved data like:
SharedPreferences previewSizePref = getSharedPreferences("PREF",MODE_PRIVATE);
if (previewSizePref.contains("x") && previewSizePref.contains("y")) {
//your saved data exists, do something
} else {
// handle the circumstances that the saved data doesn't exist
}
For saving state in onPause() and restore in onResume() you can have a look at this answer:
Saving Activity State in the onPause
And for SharedPreferences, you can have a look at API document: Data Storage - Shared Preferences
What you're describing should be standard for behaviour for Android, and if it isn't doing what you describe then you've probably overwritten this behaviour somewhere else, probably in your manifest.
If you create a new Android application and make a simple two page app, with Activity A as the launcher and Activity B as the second page, then your manifest will look like the following and the app will display the behaviour you describe.
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".ActivityA"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ActivityB"
android:label="#string/title_activity_main" >
</activity>
</application>
Double check that your manifest looks similar to this- Activity B has no flags and is just a declaration that it exists in your manifest.