Getting null value from intent in deep link - java

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

Related

Start the First screen each time app comes from background in android

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

Android app opening wrong page after using uri scheme

In IOS I have 2 apps (App A and App B) that will be performing different objective but at 1 point, App A will call App B using uri scheme to perform a function where App A does not have.
I wanted to implement this function to Android and currently have developed a demo for initiating call to App B. Now I am working on App B that will be receiving the uri scheme from the demo app.
Problem:
After App B return to the demo app using uri scheme I close the demo app.
When I go back to home page and open the multitask to reopen App B(or open App B through the icon), the page it reopen is the function that is used for demo app but what I wanted is the login page of App B.
This is a part of the Manifest for the intent-filter
<activity
android:name="com.apps.MasterActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:clearTaskOnLaunch="true"
android:windowSoftInputMode="adjustPan" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<data
android:host="x-callback-url"
android:scheme="myapp" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
This is where I call back to the demo app
Intent sendIntent = new Intent(Intent.ACTION_VIEW, responseUri);
sendIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
finish();
startActivity(sendIntent);
Try adding this to your activity tag in AndroidManifest.xml
android:clearTaskOnLaunch="true"
Apparently I kinda found a solution that can force the app to show the login page after going back to the demo app. By putting this code in the activity.java file.
#SuppressWarnings("deprecation")
#Override
public void onDestroy()
{
super.onDestroy();
System.runFinalizersOnExit(true);
System.exit(0);
}
I know its a deprecated function that I'm using but will try to solve it when there's something wrong in the future or when I found a better solution for it.
Edit:
Found a better solution that does not need to use the deprecated function which I have forgotten to set it to false.
I have a flag that is set to true when the app is connected through Uri Scheme which i just have to set it to false and it will be fixed. This is the change location that I made
Intent sendIntent = new Intent(Intent.ACTION_VIEW, responseUri);
sendIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
finish();
startActivity(sendIntent);
Util.isUriScheme = false;

Reading value of android:scheme programmatically

I want to know if it is possible to read the value of android:scheme from the Android-manifest-file (example below) programmatically.
<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:scheme="zxtest" />
</intent-filter>
You should be able to get this information from the PackageManager:
PackageManager pm = getPackageManager();
ActivityInfo activityInfo = pm.getActivityInfo(component,
PackageManager.GET_INTENT_FILTERS);
Unfortunately, however, you can't :-( This call SHOULD return the intent filters (according to the documentation), but it seems that the Android developers haven't gotten around to actually implementing it yet :-(
See Unable to get intent filters from a package
I'm assuming you mean that the intent has been called and you're trying to find the scheme from your activity's code?
In your activity's onCreate method, you can do the following:
Intent intent = getIntent();
Uri data = intent.getData();
String scheme = data.getScheme(); // "zxtest"

Launching Intent cannot find Activity

My program has a list of tabs that each contain a list of people. Clicking a person should edit their details, but instead, clicking a person throws an ActivityNotFoundException. My code that starts the edit activity:
Intent intent = new Intent("my.package.EDIT"); // Person is both
intent.putExtra("my.package.PERSON", (Parcelable) myPerson); // Parcelable and
GroupArrayAdapter.this.getContext().startActivity(intent); // Serializable
Relevant part of AndroidManifest.xml:
<activity android:name="EditActivity">
<intent-filter>
<action android:name="my.package.EDIT" />
</intent-filter>
</activity>
What's going on?
There's two ways to start an Activity, either explicitly or implicitly. Explicitly means that you use the class name directly; usually if you're calling an Activity that is within your own application, what you mean to use is the explicit method because it's far easier:
Intent intent = new Intent(context, EditActivity.class);
context.startActivity(intent);
However, if you really do mean to use implicit filtering, then your intent filter is missing something. Every implicit intent filter requires the category android.intent.category.DEFAULT (with few exceptions). Try this and see if it works:
<activity android:name="EditActivity">
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<action android:name="my.package.EDIT" />
</intent-filter>
</activity>
Suggested reading: intent filters.
When you instantiate your Adapter, pass the context from the calling activity. Then in your adapter use context.startActivity(...);

Restore android app stack from background

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();
}

Categories

Resources