Lets say I launch my app from the home screen, navigate through some activities, then I press the home key and do something else in the Gmail app.
After i'm done checking my mail,I press the home key again to leave the Gmail app and click my app's icon at the home screen again to return to it.
When I return to my app, I want it to return to the last activity I was at, NOT start a whole new session. I've been trying to figure this out all day.
My manifest for my first activity is as follows:
<activity android:name=".Main"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:alwaysRetainTaskState="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
The category attribute LAUNCHER makes my app ALWAYS start at activity Main, so I don't know how to go about restoring the last activity. People have told me to use sharedpreferences to save the last activity and load it on Launch, but I don't think it's intended to be done that way because it isn't very elegant.
I think its the only way because what happens when you're launching an app is that Launcher application sends intent "android.intent.action.MAIN" And the only activity in your app that responds to this intent is your main activity, thus it gets activated. So the only thing you can do is save somewhere your session and on activity start up if there's already saved session restore the app to the previous state.
Try using one of these in your manifest :
<activity android:launchMode=["multiple" | "singleTop" |
"singleTask" | "singleInstance"] ...
Are onResume() and onPause implemented properly?
protected void onResume(){
super.onResume();
}
protected void onPause() {
super.onPause();
}
Related
For my android application, when a user play a video, a new activity (VideoPlay) starts in pip mode.
Manifest (Video Play)
<activity
android:name=".PlayVideo"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:launchMode="singleTask"
android:theme="#style/AppTheme.NoActionBar"
tools:ignore="LockedOrientationActivity"
android:supportsPictureInPicture="true"
android:configChanges=
"screenSize|smallestScreenSize|screenLayout|orientation"/>
The problem is when i click on close button "X" of the pip screen, a new instance of my app is created.
how to handle this problem ? thank you
That is not another instance of your app, but rather a different task which houses your PlayVideo activity. To prevent showing your activity in recents screen, you can add android:excludeFromRecents="true" in the manifest attributes of your PlayVideo activity.
Also, if you're force closing your PlayVideo activity in some way other than user interaction like backpress, you may like to call finishAndRemoveTask() instead of just finish() as calling finish() will not remove your activity from recents.
I have added a deep link to my app which maps an activity to a particular web page on my website (Link referred: https://developer.android.com/training/app-links/deep-linking ).
While handling the deep link in my Java code, getAction() and getData() methods give me null value.
I tried testing it here: https://firebase.google.com/docs/app-indexing/android/test (This gave me perfect result) But the same link opens in A web browser rather than in my app when clicked.
Android Manifest code :
<activity
android:name=".MainActivity"
android:screenOrientation="portrait"
android:launchMode="singleTask"
android:exported="true">
<tools:validation testUrl="https://www.mywebsite.com/xyz" />
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="www.mywebsite.com"
android:pathPrefix="/xyz" />
</intent-filter>
</activity>
Java Code :
Intent intent = getIntent();
String action = intent.getAction(); // getting null value here
Uri data = intent.getData(); // getting null value here
I want that if the app is present, then it should be opened when the link is clicked or else the link will open the web page.
Where and what am I missing?
You can run into this problem because using singleTask. In that case you should use onNewIntent to 'update' intent, because onCreate and onResume will not handle it.
This is called for activities that set launchMode to "singleTop" in their package, or if a client used the Intent#FLAG_ACTIVITY_SINGLE_TOP flag when calling startActivity(Intent). In either case, when the activity is re-launched while at the top of the activity stack instead of a new instance of the activity being started, onNewIntent() will be called on the existing instance with the Intent that was used to re-launch it.
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
//TODO: do something with new intent
}
instead of getting intent data in onCreate, get in onResume
#Override
protected void onResume() {
super.onResume();
Intent intent = getIntent();
if (intent != null && intent.getData() != null ){
Toast.makeText(this, intent.getData().toString(), Toast.LENGTH_SHORT).show();
webView.loadUrl(intent.getData().toString());
}
}
add these lines of code which activity is attached for deep linking to open your website page
and mark it as a answer if it helped you to solve your problem
I have an app that has 5 activities (A,B,C,D,E). The app can navigate between those activities. When the user presses home button in device the app goes background and after when the app comes to foreground, first activity should be launched i.e A activity.
Example: app in D activity, after pressing home, the app goes background and when it comes to foreground again it should open A activity not D.
Solutions which i have tried is launch mode, I set the launch mode for A activity (singleInstance) but could not able to find the required solution.
For launch same Activty you Should clear all the Activity when app goes into background.When app goes background use below code that will clear current activity and all other activity that are in stack.
For API 16+, use
finishAffinity();
For lower (Android 4.1 lower), use
ActivityCompat.finishAffinity(YourActivity.this);
When you press Home-Button change to Activity A. Maybe this will work:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_HOME)
{
Intent intent = new Intent(this, MyActivityName.class);
//replace MyActivityName.class with the name of your Activity A
startActivity(intent);
}
return super.onKeyDown(keyCode, event);
}
you may get ondestroy() or onpause() method. on it youcan do
Intent intent = new Intent(this, A.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish(); //
You can set android:clearTaskOnLaunch="true" for Activity A in your manifest file to achieve what you want:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.beispieldomain.stackoverflowxmlparse">
<application
...
<activity
android:name=".MainActivity"
android:clearTaskOnLaunch="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Have a look here:
Managing Tasks
clearTaskOnLaunch
Could someone explain the following lines in the manifest -
<activity
android:name=".AboutUs"
android:label="#string/app_name">
<intent-filter >
<action android:name="com.example.app1.ABOUT" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
How are the fields in activity and intent filter important and when are they used/referred ?
Sorry, i tried to read the documentation but still couldnt figure much out.
Thank you
android:name=".AboutUs"
This is the name of your Activity class, the dot at the front is shorthand notation for your package. So this actually stands for com.your.package.name.AboutUs which means your java file that represents this Activity is called AboutUs.java
android:label="#string/app_name"
label is the string that gets shown in the launcher(if the activity is listed in the launcher) and at the top of the window when the activity is open.
<intent-filter > ... </intent-filter>
intent filter defines the Intents that your activity "listens for" in order to launch.
<action android:name="com.example.app1.ABOUT" />
<category android:name="android.intent.category.DEFAULT"/>
Action and category are both fields that get set on an Intent before it is "fired off" into the system. The system will then look for any activities that match both the action and category and if it finds one then it will launch that activity, or if it finds multiple it will show the user all of them and let them pick.
In your case your the action you are listening for com.example.app1.ABOUT is a custom action that is specific to your app, not one of the systems actions.
So here is what an intent that would start this particular activity might look like:
Intent i = new Intent();
i.setAction("com.example.app1.ABOUT");
i.addCategory("android.intent.category.DEFAULT");
startActivity(i);
Note that because you've created a custom action, this intent does not require access to your AboutUs.class so this intent could technically be fired from any app on the device and it would launch into your activity.
For the ACTION you have this answer and for the DEFAULT category you have this answer
An Activity is an application component that provides a screen with which users can interact in order to do something, such as dial the phone, take a photo, send an email, or view a map. To declare your activity, open your manifest file and add an element as a child of the element like your example.
The android:name attribute is the only required attribute—it specifies the class name of the activity.
The android:label attribute is a user-readable label for the application as a whole, and a default label for each of the application's components
An element can also specify various intent filters—using the element—in order to declare how other application components may activate it.
The element specifies that this is the "main" entry point to the application.
The element specifies that this activity should be listed in the system's application launcher (to allow users to launch this activity).
Please refer to the http://developer.android.com/guide/components/activities.html
I have an application in android that includes a application home page. I override the hardware Home button to go back to the application home page for API level 10 or less.
My application works fine on Android version 3.0 and 4.0. The problem is overriding the Home button. I found a discussion ( Disable Home Button in Android ICS (4.0) ) which includes a method to implement a home screen somehow. It is suggested by #Chalaman.
I did not get the point yet. Is there any one that can help me more by providing some codes?
when we use :
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
in the manifest file, a dialog pops up when we click on the home button. It includes the home phone page icon and application icon. we can make a choice. If we select the application icon, we stay in the application. The problem is we stay also in the same activity. How can I go to another activity (home page of my application)?
We can to it in API level 10 or less:
#Override
public void onAttachedToWindow() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB)
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
super.onAttachedToWindow();
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_HOME:
loadStartPage();
break;
}
return super.onKeyDown(keyCode, event);
}
private void loadStartPage() {
Intent intent = new Intent(getApplicationContext(), StartActivity.class);
intent.putExtra("user", user);
intent.putExtra("user_id", user_id);
intent.putExtra("server", server);
intent.putExtra("password", password);
main_activity.startActivity(intent);
}
How to Load Start Page in API level 11 or greater?
The answer is simple: don't do it.
Users expect their apps to be consistent across the entire Android platform. I can't imagine a situation in which you could ever justify overriding the home button.
Edit:
To be clear, there are apps out there that appear to override the home button (i.e. the Car Mode app, which won't allow you to escape the app unless you click the "Exit" button). Apps such as these don't actually explicitly override the "home button". You can read more about it here.
the android home screen is just an app. it is started by a well-defined broadcast intent that is issued when the home key is pressed.
in a nutshell, you implement an android application that listens to the same event that the stock android home screen app listens to. when the user presses home, they will see the chooser allowing them to select from the stock home screen app, our your app. here's what the intent filter would look like,
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
i realize that's probably not what you want. however, there's no way to completely override the home key. this is intentional as it prevents malicious apps from locking you out of the home screen. the home button is sort of the guaranteed to work "get me out of here" button.
your users can flag your app as the default to handle the home broadcast, but that's probably not what you want either because from then on they want be able to get to the stock home screen unless they clear default or uninstall your app.
preventing users from accessing the home button is a pretty nasty thing to do. are you sure that's what you want?
Override onKeydown can't solve your problem .. when you press home button activity calls onPause() .. so put your method inside of onPause().. I guess it will work ..
protected void onPause() {
super.onPause();
loadStartPage();
}
private void loadStartPage() {
Intent intent = new Intent(getApplicationContext(), StartActivity.class);
intent.putExtra("user", user);
intent.putExtra("user_id", user_id);
intent.putExtra("server", server);
intent.putExtra("password", password);
main_activity.startActivity(intent);
}