I am totally new in Android and learning,and i noticed OnBackPressed takes you to the previous layout in the game, now i added this code which closes the app at OnBackPressed
#Override
public void onBackPressed() {
Intent homeIntent = new Intent(Intent.ACTION_MAIN);
homeIntent.addCategory( Intent.CATEGORY_HOME );
homeIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(homeIntent);
super.onBackPressed();
}
My problem is when you start the game again it takes you back to the previous layout not the main layout. Take for example you have 4 activities, when i start the game it takes me to activity 3 how can i avoid this?
<application
android:allowBackup="true"
android:icon="#mipmap/icon1"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name"
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=".StartGame"
android:label="#string/app_name"
android:screenOrientation="portrait"/>
<activity
android:name=".MathQuestions"
android:label="#string/app_name"
android:screenOrientation="portrait"
/>
<activity android:name=".HighScores"
android:label="#string/app_name"
android:configChanges="keyboardHidden|orientation|screenSize"/>
<activity android:name=".HowToPlay" >
</activity>
</application>
You're not really closing you app. With that code, you're simply minimizing your app (mimicing the HOME button behavior). I believe, if you call finish()after the startActivity(homeIntent) call, it will work as you want it to.
modify flags:
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
and call finish() instead of super.onBackPressed();
I did some reading and found this:
This launch mode can also be used to good effect in conjunction with FLAG_ACTIVITY_NEW_TASK: if used to start the root activity of a task, it will bring any currently running instance of that task to the foreground, and then clear it to its root state. This is especially useful, for example, when launching an activity from the notification manager.
From documentation for CLEAR_TOP
EDIT: Another solution.
Well this isn't working for you, let's do it this way:
Create a custom class that extends application, you don't need this most of the time but will help here. Call it MyApp.java
public class MyApp extends Application {
private HashSet<Activity> mActivities;
#Override
public void onCreate(){
super.onCreate();
mActivities = new HashSet<Activity>();
}
public void addActivity(Activity activity){
if(!mActivities.contains(activity))
mActivities.add(activity);
}
public void removeActivity(Activity activity){
if(mActivities.contains(activity))
mActivities.remove(activity);
}
public void close(){
for(Activity activity : mActivities){
activity.finish();
}
}
And add this to your android manifest in the application tag (keep rest the same):
<application
android:name=".MyApp"
...
...
Now, in every activity call the following:
#Override
public void onStart(){
super.onStart();
((MyApp) getApplication()).addActivity(this);
}
So now every activity is stored in your own HashSet can be gracefully finished when you need it to be.
Instead of calling the intent, you would now just do:
#Override
public void onBackPressed(){
((MyApp) getApplication()).close();
}
All activities are finished, resources released and when you come back to the app it will be at your Home Activity. Now, you may/may not need the removeActivity call for cases where an activity is destroyed or stopped, but this solution should work. Like I said, it's a little more work but would solve your problem.
Related
My app contains only one activity and ads activity. It works well, but when I press "Back" button my application is closed and I can see, instead of wallpaper, black background which is partly rolled down. I can see all icons as well. Then black part of screen disappears and I can see my normal screen wallpaper. It takes only less than a second but it is annoying. I can't found what the problem is it.
My activity has only horizontal orientation and has correct life cycle (onPause-onStop-onDestroy) after pressing back button. Ads activity is not launched at all.
I did not override onPause() onStop() onDestroy().
My Manifest
<application
android:allowBackup="true"
android:icon="#mipmap/icon_transp_bkg"
android:label="#string/app_name"
android:largeHeap="true"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name="MainActivity"
android:screenOrientation="sensorLandscape"
android:configChanges="orientation|screenSize"
android:theme="#style/PlayTheme2">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
android:theme="#android:style/Theme.Translucent" />
</application>
Could it be related to back stack and trying to search some previous activity?
Please, put me on the right way to solve the problem. Thanks a lot in advance.
You can use OnBackPressed
#Override
public void onBackPressed() {
// what you want to do when back button is pressed
}
You can override the OnBackPressed method in the activity
#Override
public void onBackPressed(){
finish();
}
And call on the FINISH method, this will properly close both your activity and app.
Keep the Back-Stack and Trying to search some previous activity.
Ovverride the onBackPressed with a Call to Finish to End Both.
public void onBackPressed(){
finish();
}
I have a overlay view over all apps. I want to close the overlay view from screen on soft key press (home, back and recent). I have a transparent activity with no content which is starting a service having overlay view.
public class SampleOverlayShowActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startService(new Intent(this, SampleOverlayService.class));
}
#Override
protected void onPause() {
SampleOverlayService.stop();
finish();
super.onPause();
}
}
Inside manifest
<activity
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:name="SampleOverlayShowActivity"
android:excludeFromRecents="true"
android:theme="#android:style/Theme.Dialog" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Everything is working fine expect recent apps. Activity still show up on recent application button press. It got removes when I again press recent application button.
This should be much simpler than trying to override soft key behaviour to do clean up. Instead make sure the activity is launched so that it has no recents trace. From the manifest that means adding noHistory and excludeFromRecents
<activity android:excludeFromRecents="true"
android:noHistory="true"
android:name=".."
...>
<intent-filter>
...
</intent-filter>
</activity>
Note that android:excludeFromRecents works for the task only, so you probably want to make sure that activity is a new task too, using the appropriate flags (android:launchMode="singleTask")
#Override
public void onStop() {
Intent intent = new Intent(this, StatusActivity.class);
startActivity(intent.setAction(AppConstants.ACTION_DISPLAY).addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK));
super.onStop();
}
This does not work why?
the StatusActivity does not receive the intent in onCreate or onNewIntent
if I put the code anywhere else then it works but not in onStop or onPause
It seems that the intent is sent correctly but StatusActivity is not receiving it right away. It does receive it only if I send another intent from another place and then receive them both at the same time.
For testing I sent 10 intents in on start and then after few secconds I sent another intent from a service and the StatusActivity received 11 intents all at once.
<activity
android:name=".MainActivity"
android:excludeFromRecents="false"
android:label="#string/app_name"
android:launchMode="singleTask"
android:taskAffinity=".MainActivity"
android:windowSoftInputMode="stateHidden|adjustResize" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".StatusActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:excludeFromRecents="true"
android:label="#string/app_name"
android:launchMode="singleInstance"
android:taskAffinity=".StatusActivity" >
Try this way,hope this will help you to solve your problem.
Intent intent = new Intent(this, StatusActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
I have test your code and find out that when I press back button, activity B will be called, but when I press home button, it doesn't.
I guess the reason is that when home pressed, system call launcher apk by component or action(I'm not sure), but back pressed didn't. And your activity B is hidden by launcher.
I don't think call activity B in onStop method is a suitable way, becz you can't control the invoke time. But I find a another way to acheive that:
protected void onStop() {
finish();
super.onStop();
}
public void finish() {
startActivity(your intent);
super.finish();
}
It is just a workaround, not a good solution.
Hope it helps.
In my App I have:
-SplashScreen (SSc) preparing the application (starting services and so on)
-MainActivity (MA) the most relevant part of the app handling most actions
-and some other activities which are not that relevant
For my App I'd like to have the behavior like launchMode singleTask, so that my App is always started as a new Task, even when opened through a link click in SMS/EMail app. The best would be to have only one Instance of my Activities as they are all serially navigable.
However when I start SSc as singleTask it is the root of the stack and navigating to the MainActivity, pressing home, click on the Launcher icon again the app is fully restarted. So SSc is shown again and so on. In this Situation, I would like the MainActivty to be brought to the front instead.
my wish would be:
launcherclick -> SSc ->MA ->HOME -> launcherclick -> bring MA to front -> HOME-> relaunch from recents -> bring MA to front
Click on link ->SSc/MA (whether it is first start) with the same instances
In my App it does not make sense to have multiple instances, as the background service only handles one MainActivity at a time because it polls data frequently just for the seen "Thing".
Do you have any recommendations to achieve this goal?
my first idea was a LauncherActivity with launchMode singletask without layout to route the intents to the other activities (which most likely will be singleTop !?, because its only in one task then) like:
public class LauncherActivity extends Activity {
private boolean firstStart = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
protected void onResume() {
super.onResume();
if(firstStart){
startActivity(new Intent(this, SplashScreen.class));
firstStart = false;
} else {
Intent i = new Intent(this, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(i);
}
}
}
Manifest xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="x.startintenttest">
<application
android:allowBackup="true"
android:allowTaskReparenting="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name">
<activity
android:name="x.startintenttest.MainActivity"
android:label="#string/app_name"
android:launchMode="singleTop"></activity>
<activity
android:name="x.startintenttest.MainActivity2"
android:label="#string/title_activity_main_activity2"></activity>
<activity
android:name="x.startintenttest.SplashScreen"
android:label="#string/title_activity_splash_screen"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="*.xyz.de"
android:pathPattern="/...-........."
android:scheme="https" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Its simple, I also did the same. I was using singleTask for my splash and the main activity. So that I faced the same issue(Splash was showing at every wakeup). But I solved this by removing the singleTask from the splash and kept it for the MA alone(I used to finish the splashActivity when the MA starts). Try this trick.
The solution provided Sripathi fixes the issue, but you end up with the link-opening-app having the splash screen layout in its preview. My solution to this is to have a LinkEntryPointActivity with no layout that then delegates the received intent to the splash screen.
class LinkEntryPointActivity : MyBaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val intentClone = intent.clone() as Intent
val componentName = intentClone.component
val newComponentName = ComponentName(componentName.packageName, SplashActivity::class.java.name)
intentClone.component = newComponentName
startActivity(intentClone)
finish()
}
}
And declare it in AndroidManifest.xml as
<activity android:name=".ui.LinkEntryPointActivity"
android:launchMode="singleTask" <-- This forces to open the link in a new task
android:screenOrientation="portrait">
<!-- Intent filters here -->
</activity>
The original splash screen activity should still be handling the MAIN action in the LAUNCHER category as usual.
The MainActivity contains some buttons. Each button opens a new activity via an intent. These activities then have a button to return to the MainActivity via an intent.
But when I press a button to return to the MainActivity, I get some sort of menu on the screen! Someone who knows what could be wrong? Preciate some help! Thanks!
EDIT: The return button in one of the other activities:
Button btnReturn1 = (Button) findViewById(R.id.btnReturn1);
btnReturn1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
Intent returnBtn = new Intent("android.intent.action.MAIN");
startActivity(returnBtn);
}
});
The Manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.kullaberg.test02"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="15" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
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=".Activity1"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.ACTIVITY001" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".Activity2"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.ACTIVITY002" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".Activity3"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.ACTIVITY003" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
why don't you call finish();
when you want to return to MainActivity
btnReturn1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
finish();
}
});
Here's why you saw the menu with the code you listed in your onClick method:
You were creating an Intent with the constructor that takes a string for the action parameter of the Intent's IntentFilter. You passed "android.intent.action.MAIN" as the argument to that constructor, which specifies that the Intent can be satisfied by any Activity with an IntentFilter including <action="android.intent.action.MAIN">.
When you called startActivity with that Intent, you effectively told the Android OS to go find an Activity (in any app installed on the system) that specifies the android.intent.action.MAIN action. When there are multiple Activities that qualify (and there are in this case since every app will have a main Activity with an IntentFilter including the "android.intent.action.MAIN" action), the OS presents a menu to let the user choose which app to use.
As to the question of how to get back to your main activity, as with most things, it depends on the specifics of your app. While the accepted answer probably worked in your case, I don't think it's the best solution, and it's probably encouraging you to use a non-idiomatic UI in your Android app. If your Button's onClick() method contains only a call to finish() then you should most likely remove the Button from the UI and just let the user push the hardware/software back button, which has the same functionality and is idiomatic for Android. (You'll often see back Buttons used to emulate the behavior of an iOS UINavigationController navigationBar which is discouraged in Android apps).
If your main activity launches a stack of Activities and you want to provide an easy way to get back to the main activity without repeatedly pressing the back button, then you want to call startActivity after setting the flag Intent.FLAG_ACTIVITY_CLEAR_TOP which will close all the Activities in the call stack which are above your main activity and bring your main activity to the top of the call stack. See below (assuming your main activity subclass is called MainActivity:
btnReturn1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent i=new Intent(this, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
)};
use
Intent returnBtn = new Intent(getApplicationContext(),
MainActivity.class);
startActivity(returnBtn);
make the main activity's launchmode to singleTask in Android Manifest if you don't want to create new one every time.
android:launchMode="singleTask"
I'm used it and worked perfectly...
startActivity(new Intent(getApplicationContext(),MainActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
because Finish() use for 2 activities, not for multiple activities
This usually works as well :)
navigateUpTo(new Intent(getBaseContext(), MainActivity.class));
instead of starting MainActivity again via startActivity, call finish() instead in the other activities to get back to MainActivity... as MainActivity is already in stack
Use this code on button click in activity and When return back to another activity just finish previous activity by setting flag in intent then put only one Activity in the Stack and destroy the previous one.
Intent i=new Intent("this","YourClassName.Class");
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
I highly recommend reading the docs on the Intent.FLAG_ACTIVITY_CLEAR_TOP flag. Using it will not necessarily go back all the way to the first (main) activity. The flag will only remove all existing activities up to the activity class given in the Intent. This is explained well in the docs:
For example, consider a task consisting of the activities: A, B, C, D.
If D calls startActivity() with an Intent that resolves to the component of
activity B, then C and D will be finished and B receive the given Intent,
resulting in the stack now being: A, B.
Note that the activity can set to be moved to the foreground (i.e., clearing all other activities on top of it), and then also being relaunched, or only get onNewIntent() method called.
Source
I just do this way
public void retorna(View view)
{
Intent muda = new Intent(getApplicationContext(),MainActivity.class);
muda.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(muda);
}