I am using TAG_DISCOVERED action in my TagActivity and if my application is already open, I want to close it before my TagActivity is opened. However, When my TagActivity is opened with NFC, I added some logic so it navigates to main activity when pressed to back button, however the already opened app is still there and when I close the navigated main app, it agains show me my previously opened app. How can I close the app if I open my TagActivity with nfc?
<activity
android:name=".activities.TagActivity"
android:screenOrientation="portrait" >
<!--Registering app for receiving NFC's TAG_DISCOVERED intent-->
<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
Edit: I thought the flag solved my problem but apparently I didn't test it properly. The real solution to my problem is to add android:launchMode="singleTask" to my activity in manifest file.
I added FLAG_ACTIVITY_NEW_TASK flag to my Intent when returning back and that solved my problem.
startActivity(new Intent(this, MainActivity.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK))
Related
My app (a game) has two activities: a launcher activity which shows logo, does initializations and is the main activity of my app, and a client activity which does the 3D rendering and is started by the launcher activity. Thus when the app is running, the back stack is: launcher | client.
What I want with a link is:
if the app has not been started, clicking the link should first start the launcher activity, then the launcher activity start the client activity. Finally the game runs in the client activity.
if the app is running (running in the client activity), clicking the link should switch to and notify the app that the link is clicked (either in launcher or client is ok, better in client), instead of starting another launcher activity.
What I have tried:
I added an intent filter in the declaration of the launcher acitivity:
<activity android:name=".Launcher" android:label="TestApp">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="myapp" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
<activity android:name=".Client" android:label="TestApp">
</activity>
And the intent filter works when I click the link: myapp://, the launcher activity is started. But the problem is the launcher activity is started in the browser's task. If I already have an app running, there will be a new instance of my app started in the browers back stack, instead of switching to the already running app.
Then I tried add the attribute android:launchMode="singleTask" into the activity declaration. Then clicking the link will start a new task and the Launcher activity is started in that task. And if the app has already running, the running task is switched to foreground, that's what I expect. But the problem is, the back stack of the app task is changed from "launcher | client" to "launcher", the client activity is gone.
I hope that there is only one instance of my app. Cliking a link should start the app if the app is not running, otherwise switch to the app without affecting the app's current running states.
I searched a lot but don't find a solution, please help me, thanks.
Click here for app links assistant
I have this situation in my app: I have these activities
<activity
android:name=".presentation.view.start.view.activity.StartActivity"
android:screenOrientation="sensorPortrait"
android:theme="#style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".presentation.view.main.view.activity.MainActivity"
android:configChanges="locale"
android:screenOrientation="sensorPortrait"
android:theme="#style/AppThemeMultiStep"
android:windowSoftInputMode="stateAlwaysHidden" />
<activity
android:name=".presentation.view.firstScreen.view.activity.FirstScreenActivity"
android:screenOrientation="sensorPortrait"
android:theme="#style/AppThemeMultiStep"
android:windowSoftInputMode="stateAlwaysHidden" />
<activity
android:name=".presentation.view.signup.view.activity.LoginViaPinActivity"
android:screenOrientation="sensorPortrait"
android:theme="#style/AppThemeMultiStep" />
StartActivity acts as a sort of "router" based on the application state:
If I am not logged in, it will launch FirstScreenActivity
If I am logged in, it will launch LoginViaPinActivity, which will login the user based on some logic and then launch MainActivity. At the end of all, MainActivity will be at the root of the activities stack.
At some point the app will receive a notification, and when I tap it I want this:
if the app is running and MainActivity is running, open MainActivity (this is easy, there are planty of ways I can to that with various flags) but if it's not running launch StartActivity (so that I can open the app based on all the startup logics implemented there).
So the options I can think of are:
know if an activity is running in order to fire an intent or another (I don't like static fields solutions like you read in many SO post related to this)
make StartActivity the root of the task and find a combination of intent flags which will act like "launch StartActivity, but if it is running at the root of a task, bring that task to front" (this would be my preferred option if possible)
any suggestion is very appreciated
How do you usually handle this kind of situations? (I don't think I'm the first in the world with this problem :) )
Here is my approach -
Make StartActivity as your router as you've said. Just make launchmode to singleTop in your manifest in order to user onNewIntent() method of an Activity.
You'll generate notification, sending some data with contentIntent - as a result clicking on notification you'll be redirected to StartActivity.
Two cases here -
If StartActivity is in stack
onNewIntent gets called with your new Intent - Choose your activity required to be open - If it is already in stack Bring it to front using FLAG_ACTIVITY_REORDER_TO_FRONT flag
If StartActivity is not running or not in stack
Receive bundle of intent that is being got from the intent via notification, parse data and open an activity accordingly.
I've just implemented deep linking to my app. I've added intent filter to my main activity. When user starts my url scheme I'm parsing it and handling in the activity to display proper information depending on parameters. It works well when my app is started from scratch.
<activity
android:launchMode="singleTask"
android:name="com.my.app.ui.activities.MainActivity"
android:screenOrientation="portrait"
android:configChanges="orientation|screenSize|">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="myapp-scheme"/>
</intent-filter>
</activity>
The problem occurs when user opens some other activities on stack and goes background. Now if this app is resumed from background by calling my scheme url, all activities are still on the stack and the main activity doesn't show up.
How can I resolve this?
I think about navigating back to the main activity, but I don't have info if app was started from other app or in the normal way.
You need to make your MainActivity as singleTask by adding following line in the manifest(for ManiActivity):
android:launchMode="singleTask"
Then, override the onNewIntent() in the MainActivity and handle the navigation based on deep link data.Hope this answers your question.
I am working on app which will serve as Home Screen Lock. The app will support only 4.1 and above versions. The issue is handling the Home Button. I understand that we cannot override/disable Home Button, so it has to be handled a different way. I have been struggling for almost 2 weeks and tried many umpteenth ways but none of them working as expected. Main Activity is the one which will be on top and user need to enter his set password here to unlock the device. I have set my MainActivity as Home so the user is prompted to select between default launcher and my app. So expected action is to select my app as Launcher 'always'. Also I have set an flag in broadcast receiver whenever MainAcitivity is started. This flag is used in MainActivity to launch system Launcher in case MainActivity isn't started by broadcast receiver.
Everything is working fine till this point and approach. Issue is when I click on my app to change password or access other features, it doesn't open the app and opens the system launcher. The reason is it checks the flag in Main Activity and since it is not started by broadcast receiver, it doesn't launch MainActivity now and starts the system launcher. Below are code snippets:
Manifest File:
<activity
android:name=".MainActivity"
android:excludeFromRecents="true"
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" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.HOME" />
</intent-filter>
</activity>
My Broadcast Receiver
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF) || action.equals(Intent.ACTION_USER_PRESENT)) {
AppSession.getInstance().setReceiverCall(true);
MainActivity.isStarted = true;
Intent i = new Intent(context, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
context.startActivity(i);
}
Main Activity where I check the flag and start the system launcher. I amy doing this on onResume
if (!MainActivity.isStarted) {
Intent intent = new Intent();
intent.setComponent(new ComponentName(mPackageName, mName));
startActivity(intent);
}
mPackageName & mName are system launcher name.
I tried other approaches as well but only one of the thing is resolved. Either home button is handled correctly and then my app isn't launched. If app is launched then on Home button press from anywhere it always brings my MainActivity on top.
I know this is doable as its done in many ScreenLock apps but somehow I am missing something. Please advise.
I have created an app widget which, when clicked, launches an Activity in my application.
The activity it launches is NOT the main launcher activity (as set in the application manifest).
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
The activity I'm launching has launchMode="singleTop" (may be relevant)
If I launch the app from the app launcher, then press home and then the recent apps button, the app is there.
I then remove the app from recent activities list or force close it.
If I then click on my widget, the activity launches fine.
I then press Home and then the app does not appear in the list of recent apps.
Any ideas?
My activity was defined with flag android:excludeFromRecents="true" in the Manifest.
Silly me, should've spotted that earlier.
Removing that flag fixes the problem.