I have 2 apps, one of them is calling an activity from the second one through an intent filter like so:
Call in App1 (Parent app)
Intent openApp = new Intent("com.app.intent.Activity2");
startActivity(openApp );
Intent filter in App2 (child app)
<activity
android:name=".app.activity.Activity2"
android:label="#string/app_name"
android:launchMode="singleInstance"
>
<intent-filter>
<action android:name="com.app.intent.Activity2" />
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
At one point the Parent application has to close but the problem is the Activity2 from the second application gets killed as well. I can see that Activity2 is actually running under the same package, is there any way to have the Activity2 persist and run even after the parent applicaiton is closed ?
Thank you
This discussion seems to have what you need. Seems like you need to get the launch intent from the package you want to launch and use that in your intent.
Launch an application from another application on Android
Android will generally run all components from the same APK in a single process, so if one of those crashes the process then they will all be gone.
You can however tell it to put an activity or service in its own process.
<activity
android:name=".app.activity.Activity2"
android:label="#string/app_name"
android:launchMode="singleInstance"
android:process=":my_unique_process">
Of course if your process is dieing unexpectedly, that's a problem that needs to be understood and fixed - this would just be a temporary workaround.
Related
I have a launcher app which has a singleTask activity as the main entry point. When the user navigates away to another activity or to a 3rd party app and then hits the home button, then this activity should be brought to the front. However what I experience is that for the first home button press only, another instance is created instead (a new task is created, onCreate() is called). In the meantime the old task is still alive, containing the original instance of this activity, but it is impossible to navigate back to that task/activity or to bring it to the foreground.
After the first home button press, the next home button press brings the 2nd instance of this activity to the foreground. Not sure why not the very first instance's onNewIntent() method is called for the first time... So this only happens once, after that always the 2nd instance's onNewIntent() method is called. This means that the original activity will be not accessible..
I tried to bring the task to the foreground, nothing was happening... Like if it never existed (but the task is there with the activity, it is not killed at any point). I can find the task from code and also using a shell script. It contains the original activity
This is happening on Android TV (Os: Pie). Any idea what can be the reason for this? I do not really understand how this is happening... BTW the result is the same if I set the activity to singleInstance.
The activity looks like this:
<activity
android:name=".activities.MainActivity"
android:excludeFromRecents="true"
android:launchMode="singleTask"
android:theme="#style/AppTheme">
<intent-filter android:priority="2">
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.HOME"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.LEANBACK_LAUNCHER"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.ALL_APPS"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
I tried alternating the above attributes (priority, excludeFromRecents, taskAffinity), also removed them completely, they had no effect...
The home button press sends the following intent:
action: "android.intent.action.MAIN"
category:
"android.intent.category.HOME"
component: the above activity
it has also some extras but I do not think it is relevant
You are experiencing this nasty long-standing Android bug:
Re-launch of Activity on Home button, but...only the first time
You say in a comment that it doesn't happen with real users. That is not actually true. If a real user would install your app from the Play store and then launch it immediately (click the OPEN APP button after installation) then the problem would be reproduced exactly as you describe it.
I was struggling with the exactly same issue for the last couple of hours and I've read many similar Q&A about this topic/bug on StackOverflow. No solution really worked for me until, out of mere curiosity, I did the following.
If you're building a launcher and using onNewIntent() in your MainActivity (although OP doesn't mention that he's using this method), then simply comment out this line:
super.onNewIntent(intent);
Uninstall your app and install it again.
I don't know how this works, but EVEN when you then uncomment the very same line, it still behaves in a proper manner, that is: the app has really only single instance of its main activity all the time. And how I know that? My MainActivity is doing some database operations, and previously I saw in my Logcat that these operations were done twice every time, but now they are done only once.
And BTW my MainActivity tag in AndroidManifest.xml is nothing special:
<activity
android:name=".activities.MainActivity"
android:exported="true"
android:excludeFromRecents="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
My app contains a number of activities. One of these activities responds to an NFC intent filter, as well as standard intents, however, this activity is launching in it's own task, and not in the same task as the app. The app is not necessarily running when the NFC intent is initiated but if it is, I want the activity to launch in the same task to ensure a seamless user experience. At the moment, the app is behaving as though there are 2 of them running.
Here is the manifest for my NFC activity:
<activity
android:name="name.subname.app.activity.ItemSummaryActivity"
android:label="#string/title_activity_item_summary" >
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<data android:mimeType="application/vnd.name.nfcdemo" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
Is it possible to launch the activity in the existing task, if it exists?
I see two options here:
1) Add android:launchMode="singleTask" to activity tag in the manifest:
<activity
android:name="name.subname.app.activity.ItemSummaryActivity"
android:label="#string/title_activity_item_summary"
android:launchMode="singleTask" >
"singleTask":
The system creates the activity at the root of a new task and routes the intent to it. However, if an instance of the activity already exists, the system routes the intent to existing instance through a call to its onNewIntent() method, rather than creating a new one.
2) Supply Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT flag to startActivity() intent. But, if the activity is triggered by NFC (and using this option is not feasible) consider what #NFC guy has to say here.
My app consists of 2 activities:
<activity
android:name="com.domain.android.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.domain.android.AboutActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
I open my app, navigate to second screen, then go to the homescreen. From there I launch the app again - and it starts the main activity. But the app is running, it is just in the background, but why it didn't open the second activity? I guess it is something connected with activity's category. But how to fix that? Thanks.
Welcome to the ever-growing list of developers who have been bitten by this Android bug. Please see Re-launch of Activity on Home button, but...only the first time for all the gory details. And please go to Google Code and star the issues. We need all the noise we can make to get these fixed.
Hold your home button it will show the running apps click on your app it will open the activity from where you left. even if you click on the application launcher it will open the activity from where you left.
your application will not be in the same state sometimes if android needs resources it might end that activity. open an application move to next screen and press the home button and launch again it will open from where you left do the same with 5 or 6 apps then try launching the 1st app it will not be in the same state it will launch from the launch activity but any app you come to home screen and launch immediately it will open from where you left. If the background app is not doing anything android might end it if it needs resource. correct me if i am wrong. additional information i will be happy to know.
One issue may be that you have 2 activities designated as the main activity using:
<action android:name="android.intent.action.MAIN" />
You will probably have two icons in your launcher for your app. Each one will launch a different activity. You might be launching the first one again and again by using the icon for the first activity. Try removing
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
from your AboutActivity activity declaration. This might fix your problem.
I am looking for advice when it comes to properly handling flows between Activities. Let's say I have two activities - LoginActivity and MainActivity:
<activity
android:name=".LoginActivity"
android:configChanges="keyboardHidden|orientation"
android:label="#string/app_name"
android:launchMode="singleTop"
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=".MainActivity"
android:configChanges="keyboardHidden|orientation"
android:label="#string/app_name"
android:launchMode="singleTop"
android:screenOrientation="portrait" />
Now, when application starts, I start LoginActivity, and if login is successful I show MainActivity.
Now, the problems start when I want to handle certain types of Intents. Let's say I want to add custom schema to my app:
<intent-filter>
<data android:scheme="customschema" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
To which activity would I add this? Ideally I would love to add it to MainActivity and then handle it in onNewIntent method, but it is possible that my app was not started and in that case, I first need to run LoginActivity. On the other hand if I add that to LoginActivity, I need a way to pass that intent to MainActivity once user is successfully logs in. Or if app is already started I need to switch focus from LoginActivity to MainActivity and pass intent data immediately.
I believe this problem must've been solved previously and I would much rather follow best practice rather than try to invent my own solution - which is why I am looking for advice.
Forget what I said initially, I was thinking of Broadcast Receivers.
Use this solution by Commonsware instead:
How to create/disable intent-filter by programmable way?
Your MUST never have more then a ONE LoginActivity instance.
Once you've received intent to your "Main activity" make sure in the onCreate method to check for the login, and if the user is not logged in, throw an intent back to the LoginActivity.
if the user have reached the LoginActivity, but is already logged in throw an intent back to the main activity.
This might cause a glitches in the UI, but that would only indicate a faulty design, since no event of any kind should arrive to an application which is not logged in!
I'm running into a problem starting other activities from mine. I know this must be being done elsewhere as there are so many launcher apps out there which much use package manager to start specific activities...
I can get an Acitivity name I would like to start from the package manager, but how can I somehow parse this and turn it into an intent? Baring in mind I can't access the class... Also I would like to start that specific activity and not launch the MAIN intent from the package...
I'm sure someone must be doing this somewhere... It's kind of the point in activities isn't it?
Assuming you have following in your AndroidManifest.xml
<!-- The askUser dialog activity -->
<activity android:theme="#android:style/Theme.Dialog"
android:name="my.app.AskUserActivity"
android:excludeFromRecents="true"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="my.app.intents.AskUserConfirmConnect"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Then you can call this Activity by name, like this:
Intent dlgIntent = null;
dlgIntent = new Intent("my.app.intents.AskUserConfirmConnect");
dlgIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
dlgIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
context.startActivity(dlgIntent);
You can use setClassName(String, String) on the Intent to avoid needing the other class.