I have an application installed in my device. I am trying to launch this application A from the buttonclick of another application B using the following code:
Button buttonStart = (Button)findViewById(R.id.buttonStart);
buttonStart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setClassName("co.abc.android.test",
"co.abc.android.test.Abc");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
});
Following is my issue:
I launch application A
I press home button
From application B's button onclick, I launch app A again
Press return button to exit application A, which was now launched
from app B
Eventhough I exit the application A on pressing return button, I am again taken to the main activity of app A, which I had launched initially.
On referring for this issue, I have read in many places that using Intent.FLAG_ACTIVITY_CLEAR_TOP would resolve this. But since I call app A's intent from a place in which I have no access to its context, it gives me the following error.
01-01 00:09:54.694: ERROR/AndroidRuntime(283): *** FATAL EXCEPTION IN SYSTEM PROCESS: WindowManagerPolicy
android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
at android.app.ContextImpl.startActivity(ContextImpl.java:884)
at com.android.internal.policy.impl.LockScreen$DialerMethods.onTrigger(LockScreen.java:218)
at com.android.internal.widget.multiwaveview.Dialer$2.run(Dialer.java:366)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at com.android.server.wm.WindowManagerService$PolicyThread.run(WindowManagerService.java:752)
How can I resolve this issue, such that when I press the return button, I do not see the same activity(if launched before) again?
Any help is much appreciated.
Try adding inside onClick method:
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
The best way to launch another application is like this:
Intent intent = new Intent();
intent.setClassName("co.abc.android.test", "co.abc.android.test.Abc");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
startActivity(intent);
This simulates what Android does when the user selects the application from the list of available apps.
Assuming that "co.abc.android.test.Abc" is the root activity of that application (ie: the one with intent-filter ACTION_MAIN/CATEGORY_LAUNCHER) this will either start the application (if it isn't already running) or just bring the application from the background to the foreground (if it is already running).
Related
I have two applications, A and B. In app A I've added a button which opens app B.
When the button is clicked I want to open App B if it's not already running, otherwise I want to bring the app to the front.
This is the code I use:
Intent intent = getPackageManager()
.getLaunchIntentForPackage(
"com.myapp.something");
if (intent != null) {
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
The code seems to work, but the problem is that if I open app B from app A (using this code) and then click directly the icon of App B, I get two instances of the app, which is undesired.
How can I open the app, as the code does, but also get the same instance even if the app's icon is clicked?
Add Intent.FLAG_ACTIVITY_CLEAR_TOP
Hi I am stuck with this issue.
I have my app which has 3 activities:
SplashScreenActivity, LoginScreenActivity, ViewPagerActivity(which houses 3 fragments).
When I put the apk in the mobile sdcard and install and open using the packagemanager. My App starts up just fine.
Issue - But, now if I press the Home Button and again launch the app from the Apps drawer/Homescreen. The App seems to relaunch and I have to go through the entire flow of Splash and LoginScreen.
This issue does not occur if I launch the App the first time itself from the Apps drawer itself./If I long press the Home Button and select the App from recent apps list the app is resumed properly as well.
For Reference I launch activities using these flags
Splash->Login
Intent intent=new Intent(SplashScreen.this, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
LoginActivity->ViewPagerActivity
Intent intent = new Intent(context, ViewPagerActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
Home screen icon launches whatever activity you have declared as the MAIN ... LAUNCHER activity in your manifest. Generally, the launch activity in manifest should be the main activity of your app. From there you can invoke splash screens and login activities when needed.
remove these flags or the complete line of code
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
This seems to be an issue when launching with package manager.
https://code.google.com/p/android/issues/detail?id=2373
if (!isTaskRoot()) {
Intent intent = getIntent();
String action = intent.getAction();
if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) && action != null && action.equals(Intent.ACTION_MAIN)) {
finish();
return;
}
}
my Main launcher activity (the one that has android.intent.action.MAIN as its action) is Login page.
After successful login I started HOME activity and finish() the LOGIN one to prevent users returning to that page by pressing BACK button.
When I press SIGN OUT button, I want the app to return to Login page. But I can't find a way to do it. Here's the sign out code:
//This method is in HOME activity
private void signOut(){
Intent i = new Intent("android.intent.action.MAIN");
startActivity(i);
finish();
}
That code will open dialog box listing all applications in my phone for me to choose. I tried putting the package name + class name (com.example.test.Login) as the Intent but keep getting this error:
android.content.ActivityNotFoundException: No Activity found to handle Intent
I know I can trick this problem by using Splash screen as Main activity. But If there is another better solution, I want to know it.
Thanks
Use
Intent i = new Intent(this, LoginPage.class);
startActivity (i);
finish();
I have one activity which can be launched from several other activites, along with url filter intents.
On this activity I use the home icon in the actionbar as a back button, bringing the user back to the previous activity (and not as a "home" action). For now I do this by calling the finish() function. This works fine when working from within the application.
However, if launching the activity by an url filter intent, I want the home icon to bring the user to the main activity. Obviously, calling finish() will just close the activity.
So my question is, is there a way to check whether my application stack is empty and then launch the main acivity if true? Or am I attacking this the wrong way?
If your app is launched via url intent filter and it creates its own task, then you can use
if (isTaskRoot()) {
// This activity is at root of task, so launch main activity
} else {
// This activity isn't at root of task, so just finish()
}
EDIT: Added another possible method
If your app is launched into an existing task when it is launched via URL intent filter, then you can do something like the following:
When you launch your activity from other activities in your application, add an EXTRA to the Intent like this:
Intent intent = new Intent(this, MyActivity.class);
intent.putExtra("internal", "true");
startActivity(intent);
When your activity gets launched it can then check for the presence or absence of the EXTRA in the Intent to determine whether it was launched internally or via URL intent-filter, like this:
Intent intent = getIntent();
if (intent.hasExtra("internal")) {
// Launched internally
} else {
// Launched via intent-filter
}
I am trying to test drive an application feature using Robotium. One of the features is that when my initial activity is launched from a view on top of the activity stack it should clear the top of the stack and reuse the existing Activity i.g.("MainActivity").
Flow:
FirstScreen -> LoginActivityScreen -> RegistrationScreen -> FirstScreen
The solution is simple enough:
Intent intent = new Intent(getBaseContext(), FirstScreen.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
By setting the flag Intent.FLAG_ACTIVITY_CLEAR_TOP puts FirstScreen back on the top of my application stack.
The Test I am trying to write is to confirm that when the Hardware Back Button is pressed then the app is gone and the native Home(Launcher) application is the current Activity.
My Instrumentation TestCase:
#Smoke
public void testshouldBeOnLauncherHomeScreen() {
// Monitor the Home (Launcher) Activity being Launched
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.MAIN");
filter.addCategory("android.intent.category.HOME");
ActivityMonitor monitor = getInstrumentation().addMonitor(filter, null, false);
// go back to the launcher home
robotium.goBack();
assertEquals(1, monitor.getHits());
}
I would prefer to assert that the activity of the Launcher app is the current activity. Any ideas or suggestions would be much appreciated.
I have was able to solve this using ActivityUnitTestCase rather than InstrumentationTestCase2. I trust the android OS to bring my FirstScreen to the top by adding the flag. Validating that the flag is set when issuing the intent to start my first screen is enough to give me confidence that my code is doing what I expect.
Public void testThatStartedIntentHasClearTopFlag() {
Activity activity startActivity(new Intent(), null, null);
activity.findViewById(R.id.button).performClick();
Intent intent = getStartedActivityIntent();
assertEquals(Intent.FLAG_ACTIVITY_CLEAR_TOP, intent.getFlags());
}