Friday, November 18, 2016

Launching Ionic app from external link, url capturing and redirect

Howdy guys,

I'm continuing my ionic series. Today let's talk about the following scenario:

Scenario: You have two web-apps: one for desktops and another (ionic) for mobiles. Both of them can send email notifications with some link, for example to verify email. Desktop and ionic urls are slightly different, but convertable from one to another. You always receive a desktop version of link to your email.

Task: When user clicks on that link from android device, we need to be able to open it in ionic app. In addition to that, ionic app should be able to parse that link and redirect to proper view.

1. Launching Ionic app from external link


First part can be implemented easily. You just need to define intent-filter. For android, you need to edit AndroidManifest.xml, which is located here:
./platforms/android/AndroidManifest.xml

You need to add highlighted content to AndroidManifest.xml and change mywebsite.com to your domain name:
...
<activity android:name="MainActivity" ... >
  <intent-filter>
    <action android:name="android.intent.action.VIEW"></action>
    <category android:name="android.intent.category.DEFAULT"></category>
    <category android:name="android.intent.category.BROWSABLE"></category>
    <data android:scheme="https" android:host="mywebsite.com" android:pathPattern="/.*"></data>
    <data android:scheme="http" android:host="mywebsite.com" android:pathPattern="/.*"></data>
  </intent-filter>
  <intent-filter android:label="@string/launcher_name">
...

But the problem is that 'platforms' is dynamically built folder and you can't keep it in git. To solve that issue, I recommend to update AndroidManifest.xml dynamically via hook. It checks if intent filter is already added to 'AndroidManifest.xml', if not, then add it.

1. Create script ./scripts/add_intent_filters.sh (original source):
MANIFEST=./platforms/android/AndroidManifest.xml
if  grep -q pathPattern $MANIFEST ; then echo "Manifest already modified"; exit 0; fi
AFTER_LINE='android:name="MainActivity"'
ADDITION='\
  <intent-filter>\
    <action android:name="android.intent.action.VIEW"></action>\
    <category android:name="android.intent.category.DEFAULT"></category>\
    <category android:name="android.intent.category.BROWSABLE"></category>\
    <data android:scheme="https" android:host="mywebsite.com" android:pathPattern="/.*"></data>\
    <data android:scheme="http" android:host="mywebsite.com" android:pathPattern="/.*"></data>\
  </intent-filter>
';
sed -i -e "/${AFTER_LINE}/a${ADDITION}" $MANIFEST

2. Add this line to ./config.xml to run the script:
<hook type="after_prepare" src="scripts/add_intent_filters.sh" />

3. Rebuild your android platform:
rm -rf ./platforms/android
ionic build android

That's it. Now when you have intent filter in your AndroidManifest.xml and click on "https://mywebsite.com/somepath?verify=hash" android should offer you to open it in your ionic app.

2. Url capturing and redirect


We will do it using webintent plugin. But I slightly modified it, you will understand why a bit later. So let's use this fork instead (until my pull request is merged).

1. Add plugin to ./config.xml
<plugin name="WebIntent" value="com.borismus.webintent.WebIntent"/>

1.1. Optionally add plugin to ./package.json (if you adding plugins automatically like this):
...
  "cordovaPlugins": [
...
    "https://github.com/serglopatin/cordova-webintent.git"
  ],

1.2 If you prefer to add plugins manually, run this:
cordova plugin add https://github.com/serglopatin/cordova-webintent.git

2. In your main app.js file add the following controller:
angular.module('MyApp', [])
.controller('MyLinkController', function(){

  document.addEventListener('deviceready', function(){

    window.plugins.webintent.getUri(function(url) {

      // url is the url the intent was launched with
      if(url) {

            //We must clear url, otherwise it will be returned on the next call again!
            //Currently this method exists only in my modified version of plugin.
            window.plugins.webintent.clearUri(function(){
              return;
            }, function() {
              return;
            });

            //Process our url here and redirect somewhere else
            window.location.href = 'second_view.html#/someparameter';
      }
    });
  });
});

3. Ensure that your default html file contains the minimum requirements:
<html><head>
<script src="cordova.js"></script>
<script type="text/javascript" src="js/thirdparty/angular-1.4.5.min.js"></script>
<script type="text/javascript" src="js/app.js"></script>
</head>
<body ng-app="MyApp">
<div ng-controller="MyLinkController"></div>
...


That's pretty much it. Now when you click on your link from third-party app, it will be opened in your ionic app, then using webintent plugin you can parse it and redirect to another view. If you are not interested in redirection, then you don't need to clear intent url and just use original plugin instead.


No comments:

Post a Comment