React Native Android deep linking url not passed through - android

I've got deep linking to work on a basic level with our React native app using the excellent tutorial at https://medium.com/react-native-training/deep-linking-your-react-native-app-d87c39a1ad5e. Works a treat on iOS, however on Android I don't seem to get the url passed back when it links back into my app:
class App extends Component {
componentDidMount() {
if (UtilsCommon.isNative) {
RNSplashScreen.hide();
if (UtilsCommon.isIos) {
Linking.addEventListener("url", this.handleOpenURL);
} else {
console.log("registering deep linking on Android");
Linking.getInitialURL().then(url => {
console.log("url", url);
});
}
}
}
componentWillUnmount() {
Linking.removeEventListener("url", this.handleOpenURL);
}
handleOpenURL = event => {
console.log(event.url);
};
So on iOS, the link back from the test page happily goes into handleOpenURL and I see the entire url that was linked to come out in the console. However, on Android, we always get url as being null. So whilst it re-opens the app, I can't determine where it should go due to this. I added the following intent to AppManifest.xml:
<intent-filter android:label="filter_react_native">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="myapp" />
</intent-filter>
I've tried specifying an android:host attribute inside of the data node, but the url still stubbornly remained null. Can anyone tell me what else I need to do?

Related

Http links on Flutter not working on Android devices

With the help of uni_links library, I am connecting the payment screen in the browser with the app, to link back to the app once payment is successful. It all works as expected on iOS, and app is opened with return url. But on Android callback is not even called, that notifies me about the return url, even though the app is opened, meaning http linking part works.
This is what I've added in Android Manifest file:
<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.redirect.mydomain.eu"
android:pathPrefix="/return_url"/>
</intent-filter>
And this is the callback from uni_links that I am listening to in order for it to trigger with the return url string, but it doesn't trigger on Android at all:
_subscription = getLinksStream().listen((String link) {
// Handle success case
}, onError: (err) {
// Handle exception by warning the user their action did not succeed
});
Any idea why this is not working on Android at all?

Get Intent from intent-filter with WebIntent Native Plugin

I’m working with Ionic Native Plugin Web Intent, and I want to get an android Intent and use a media file or your local url in my app. My AndroidManifest.xml it’s ok, and i can see myApp as an option for share or pick an image.
<action android:name="android.intent.action.PICK"/>
<action android:name="android.intent.action.SEND"/>
<action android:name="android.intent.action.SEND_MULTIPLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="image/*"/>
But i’m locked trying to get this intent in my app.
I tried to use https://ionicframework.com/docs/native/web-intent/ native plugin, but i’m getting a response error “plugin_not_installed”.
constructor(private _platform: Platform,
private _webIntent: WebIntent
) {
}
...
ionViewDidLoad() {
this._platform.ready().then(() => {
this._webIntent.getIntent().then((data: any) => {
// Use data from intent
}).catch((error:any) => console.log(error));
});
}
Debugging with an Android version 5.0.1.
If anyone can help me! I really appreciate!
Obs.: I read https://forum.ionicframework.com/t/webintent-plugin-not-installed/96744, and I don’t see any resolution from there.
You have to add an Intent Filter to your AndroidManifest.xml.
<intent-filter>
<action android:name="android.intent.action.PICK"/>
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*"/>
</intent-filter>
Then in your constructor, do this after your device in ready state.
if (window.plugins){
window.plugins.webintent.hasExtra(window.plugins.webintent.EXTRA_STREAM,
function(hasIt){
if (hasIt) {
window.plugins.webintent.getExtra(window.plugins.webintent.EXTRA_STREAM,
function(streamData){
console.log(streamData);
}, function(err){
console.log(err);
});
}
},function(err){
console.log(err);
});
}
You should move getIntent() inside constructor.

share link from a link of a web page [duplicate]

Is it possible to make a link such as:
click me!
cause my Anton app to start up?
I know that this works for the Android Market app with the market protocol, but can something similar be done with other apps?
Here is an example of a link that will start up the Android Market:
click me!
Update:
The answer I accepted provided by eldarerathis works great, but I just want to mention that I had some trouble with the order of the subelements of the <intent-filter> tag. I suggest you simply make another <intent-filter> with the new subelements in that tag to avoid the problems I had. For instance my AndroidManifest.xml looks like this:
<activity android:name=".AntonWorld"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<data android:scheme="anton" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Please DO NOT use your own custom scheme like that!!! URI schemes are a network global namespace. Do you own the "anton:" scheme world-wide? No? Then DON'T use it.
One option is to have a web site, and have an intent-filter for a particular URI on that web site. For example, this is what Market does to intercept URIs on its web site:
<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="http" android:host="market.android.com"
android:path="/search" />
</intent-filter>
Alternatively, there is the "intent:" scheme. This allows you to describe nearly any Intent as a URI, which the browser will try to launch when clicked. To build such a scheme, the best way is to just write the code to construct the Intent you want launched, and then print the result of intent.toUri(Intent.URI_INTENT_SCHEME).
You can use an action with this intent for to find any activity supporting that action. The browser will automatically add the BROWSABLE category to the intent before launching it, for security reasons; it also will strip any explicit component you have supplied for the same reason.
The best way to use this, if you want to ensure it launches only your app, is with your own scoped action and using Intent.setPackage() to say the Intent will only match your app package.
Trade-offs between the two:
http URIs require you have a domain you own. The user will always get the option to show the URI in the browser. It has very nice fall-back properties where if your app is not installed, they will simply land on your web site.
intent URIs require that your app already be installed and only on Android phones. The allow nearly any intent (but always have the BROWSABLE category included and not supporting explicit components). They allow you to direct the launch to only your app without the user having the option of instead going to the browser or any other app.
I think you'll want to look at the <intent-filter> element of your Manifest file. Specifically, take a look at the documentation for the <data> sub-element.
Basically, what you'll need to do is define your own scheme. Something along the lines of:
<intent-filter>
<data android:scheme="anton" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" /> <--Not positive if this one is needed
...
</intent-filter>
Then you should be able to launch your app with links that begin with the anton: URI scheme.
I have a jQuery plugin to launch native apps from web links: https://github.com/eusonlito/jquery.applink
You can use it easily:
<script>
$('a[data-applink]').applink();
</script>
My Facebook Profile
I also faced this issue and see many absurd pages. I've learned that to make your app browsable, change the order of the XML elements, this this:
<activity
android:name="com.example.MianActivityName"
android:label="#string/title_activity_launcher">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<data android:scheme="http" />
<!-- or you can use deep linking like -->
<data android:scheme="http" android:host="xyz.abc.com"/>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
This worked for me and might help you.
Here's my recipe:
Create a static HTML that redirects to your requested app URL, put that page on the web.
That way, the links you share are 'real' links as far as Android is concerned ( they will be 'clickable').
You 'share' a regular HTTP link, www.your.server.com/foo/bar.html
This URL returns a simple 8 line HTML that redirects to your app's URI (window.location = "blah://kuku") (note that 'blah' doesn't have to be HTTP or HTTPS any more).
Once you get this up and running, you can augment the HTML with all the fancy capabilities as suggested above.
This works with the built-in browser, Opera, and Firefox (haven't tested any other browser). Firefox asks 'This link needs to be opened with an application' (ok, cancel). Other browsers apparently don't worry about security that much, they just open the app, no questions asked.
This method doesn't call the disambiguation dialog asking you to open either your app or a browser.
If you register the following in your Manifest
<manifest package="com.myApp" .. >
<application ...>
<activity ...>
<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:host="gallery"
android:scheme="myApp" />
</intent-filter>
</activity>
..
and click this url from an email on your phone for example
<a href="intent://gallery?directLink=true#Intent;scheme=myApp;package=com.myApp;end">
Click me
</a>
then android will try to find an app with the package com.myApp that responds to your gallery intent and has a myApp scheme. In case it can't, it will take you to the store, looking for com.myApp, which should be your app.
Once you have the intent and custom url scheme for your app set up, this javascript code at the top of a receiving page has worked for me on both iOS and Android:
<script type="text/javascript">
// if iPod / iPhone, display install app prompt
if (navigator.userAgent.match(/(iPhone|iPod|iPad);?/i) ||
navigator.userAgent.match(/android/i)) {
var store_loc = "itms://itunes.com/apps/raditaz";
var href = "/iphone/";
var is_android = false;
if (navigator.userAgent.match(/android/i)) {
store_loc = "https://play.google.com/store/apps/details?id=com.raditaz";
href = "/android/";
is_android = true;
}
if (location.hash) {
var app_loc = "raditaz://" + location.hash.substring(2);
if (is_android) {
var w = null;
try {
w = window.open(app_loc, '_blank');
} catch (e) {
// no exception
}
if (w) { window.close(); }
else { window.location = store_loc; }
} else {
var loadDateTime = new Date();
window.setTimeout(function() {
var timeOutDateTime = new Date();
if (timeOutDateTime - loadDateTime < 5000) {
window.location = store_loc;
} else { window.close(); }
},
25);
window.location = app_loc;
}
} else {
location.href = href;
}
}
</script>
This has only been tested on the Android browser. I am not sure about Firefox or Opera. The key is even though the Android browser will not throw a nice exception for you on window.open(custom_url, '_blank'), it will fail and return null which you can test later.
Update: using store_loc = "https://play.google.com/store/apps/details?id=com.raditaz"; to link to Google Play on Android.
You may want to consider a library to handle the deep link to your app:
https://github.com/airbnb/DeepLinkDispatch
You can add the intent filter on an annotated Activity like people suggested above. It will handle the routing and parsing of parameters for all of your deep links. For example, your MainActivity might have something like this:
#DeepLink("somePath/{useful_info_for_anton_app}")
public class MainActivity extends Activity {
...
}
It can also handle query parameters as well.
Try my simple trick:
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if(url.startsWith("classRegister:")) {
Intent MnRegister = new Intent(getApplicationContext(), register.class); startActivity(MnRegister);
}
view.loadUrl(url);
return true;
}
and my html link:
Go to register.java
or you can make < a href="classRegister:true" > <- "true" value for class filename
however this script work for mailto link :)
if (url.startsWith("mailto:")) {
String[] blah_email = url.split(":");
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("text/plain");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{blah_email[1]});
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, what_ever_you_want_the_subject_to_be)");
Log.v("NOTICE", "Sending Email to: " + blah_email[1] + " with subject: " + what_ever_you_want_the_subject_to_be);
startActivity(emailIntent);
}
Just want to open the app through browser? You can achieve it using below code:
HTML:
Click here
Manifest:
<intent-filter>
<action android:name="packageName" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
This intent filter should be in Launcher Activity.
If you want to pass the data on click of browser link, just refer this link.

Is there an efficient way to add multiple Appinks to mobile devices in HTML?

I am a developer of a basic e-commerce app which has a companion website. I wanted to try app links as a way to direct my users from my website to certain screens on my mobile app.
The applinks website tutorial gives the following example as a way to introduce app links to a certain app.
This is possible if I wanted to "link" to just one screen in each app. But what do I have to do if I want to link to multiple screens?
I want the website to be able to direct the user to the home screen, the search screen as well as the payment screen. Is there an efficient way to do this? Do I have to add different app links on different pages?
EDIT
Thanks for the response Alex. I've tried to follow your guide for my Android app but it doesn't seem to work. Whenever I open the URL of my website on the Android Chrome browser nothing happens. I want an automatic redirect to my app.
This is a snippet of my code (under pseudonyms for the names and urls).
Website:
<meta property="al:android:url" content="ecommerceapp://dlogsman" />
<meta property="al:android:app_name" content="ECommerceApp" />
<meta property="al:android:package" content="com.ecommerce.app" />
<meta property="al:web:url" content="http://ecommerce.com/~dlogsman" />
Android Manifest:
<activity
android:name="com.ecommerce.app.App"
android:label="#string/app_name_ecommerce">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<data android:scheme="ecommerceapp" android:host="open" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
And then my onStart method handles the intent exactly like you recommended. Any suggestions?? Thanks again for the time.
As a heads up, I work on the Branch linking tool (branch.io) which helps simplify deep linking across all channels including Facebook (and simplifying the AppLinks nightmare)
What App Links do is simply tell the Facebook robot how to map a corresponding website URL to your native app URL. It's just a set of metatags to add to your site's header in order to tell Facebook which app URL to call when the app is installed. The only actual link is your website link. Therefore, you can only have 1 set of AppLinks on a given page on your existing ecommerce site. In order to use AppLinks to different pages in your app, you'll need to actually have different web URLs. So, you'll need to have a:
http://yourecommercesite.com/home and add metatags for yourecommerceapp://home
http://yourecommercesite.com/search and add metatags for yourecommerceapp://search
http://yourecommercesite.com/payment and add metatags for yourecommerceapp://payment
Then, you'll need to structure your app for deep linking. In case you haven't done that, here's how to set it up and receive the URL path in iOS:
Add the URI scheme for yourecommerceapp:// to the PLIST file
Write the code to receive the URI path
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
if ([[url path] hasSuffix:#"home"]) {
// load the home view controller
} else if ([[url path] hasSuffix:#"search"]) {
// load the search view controller
} else if ([[url path] hasSuffix:#"payment"]) {
// load the payment view controller
}
return YES;
}
And here's how in Android:
Setup the app Manifest to receive intents from yourecommercesite://. You just need to add this inside the <activity></activity> tags
<intent-filter>
<data android:scheme="yourecommercesite"/>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
In onStart of the Activity that receives the intent, add the following code:
#Override
protected void onStart() {
super.onStart();
if (this.getIntent().getData() != null) {
if (this.getIntent().getData().getPath().equals("home")) {
// load the home activity
} else if (this.getIntent().getData().getPath().equals("search")) {
// load the search activity
} else if (this.getIntent().getData().getPath().equals("payment")) {
// load the payment activity
}
}
}

cordova webintent plugin isnt working

I actually want to capture the weblink which can trigger my app to launch.
I am using the code as given below. [written in AndroidManifest.xml].
<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:host="mysite.com"
android:pathPrefix="/_mobile/"
android:scheme="http"
/>
</intent-filter>
Launching of an app is a success when I try to visit "mysite.com/_mobile". Basically, the aforementioned link is actually a link to the mobile version of my main website. Now, if a user has the app installed, it should open the app rather than the mobile web page. So far, it works great. Now the problem is when I want to navigate to a specific page in an app. for example, "mysite.com/_mobile?productId=103" - this would open a page for productId=103 in mobile web view. But, incase the user has my app installed, how can I redirect him to this productId page in an app.
I did some googling on this topic and stumbled upon a cordova plugin. I added this plugin, so called "Initsogar/cordova-webintent" here. Now, I am using this code,
window.plugins.webintent.getUri(function(url) {
if(url !== "") {
alert("URL was "+url);
}
});
All I want is to get the uri which launched the app. I do not get the desired outcome. I tried to alert some value to check if this code is working or not, it seems its NOT.
see the code that i used for testing:
window.plugins.webintent.getUri(function(url) {
alert(2);
if(url !== "") {
alert("URL was "+url);
}
});
Here, 2 is not alerted. I dont know whats wrong with this plugin. other than this, I have no clue where to start from. any help would be great. :)

Categories

Resources