androidandroid-intentgoogle-chrome-appdeep-linkingdeeplink

Block mobile website to open my app android deeplink - Google Chrome


I have supported deeplinks in my app

<activity android:name=".DeepLinkActivity" android:noHistory="true"></activity>
    <activity-alias
        android:name="com.example.Launcher"
        android:targetActivity=".DeepLinkActivity">
        <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" />
            <data android:scheme="http" />
            <data android:scheme="@string/SCHEMA" />
            <data android:host="@string/WEB_DOMAIN" />
            <data android:host="@string/WWW_WEB_DOMAIN" />
            <data android:path="/" />
            <data android:path="/x" android:pathPattern="/x/.*" />
        </intent-filter>
    </activity-alias>

So whenever user clicks on www.example.com the android app asks to open as app or web that is fine, but I do not want when my users are on mobile site they should be asked to open in app. I have gone through many stackoverflow posts but everyone says its not possible but still many websites are handling this scenario.

As per this Article the behaviour depends on user gestures, if user is clicking on any link then Chrome displays a chooser while if user is typing url on browser then it doesn't.


Solution

  • After lot of research I have solved it. You can use either way.

    Handle in mobile website : So if you want to render your user to Chrome always when they are on your msite you can achieve this by redirecting all your urls to

    Handle in app

    AndroidManifest.xml

     <activity
                android:name=".DeepLinkActivity"
                android:noHistory="true"
                android:theme="@style/Theme.Transparent">
                <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" />
                    <data android:scheme="http" />
                    <data android:scheme="@string/SCHEMA" />
                    <data android:host="@string/WEB_DOMAIN" />
                    <data android:host="@string/WWW_WEB_DOMAIN" />
                    <data android:pathPattern="/.*" />
                </intent-filter>
            </activity>
    

    DeepLinkActivity

    @Override
    protected void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        try {
            if (Intent.ACTION_VIEW.equals(getIntent().getAction())) {
                Uri uri = getIntent().getData();
                if (uri == null) throw new IllegalArgumentException("Uri can not be null");
                Intent intent = null;
                if (getString(R.string.SCHEMA).equals(uri.getScheme()) || uri.toString().matches(Links.REGEX)) {
                    intent = linkIntent(uri);
                }
                if (intent == null) SystemUtil.launchUrlInDefaultBrowser(uri, this); else startActivity(intent);
    
            }
        } catch (IllegalArgumentException e) {
            Toast.makeText(this, R.string.can_not_open_url, Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            Toast.makeText(this, R.string.can_not_open_url, Toast.LENGTH_SHORT).show();
        } finally {
            finish();
        }
    }
    
     /**
     * This will open the provided url in browser except the current app.
     * @param url Uri
     * @param context  Activity Context
     */
    public static void launchUrlInDefaultBrowser(Uri url, Context context) {
        try {
            ResolveInfo packageInfo = null;
            final Intent browserIntent = new Intent(Intent.ACTION_VIEW);
            browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            browserIntent.setData(url);
            // Try to find anything that we can launch the URL with. Pick up the first one that can.
            final List<ResolveInfo> resolveInfoList = context.getPackageManager().queryIntentActivities(browserIntent, PackageManager.MATCH_DEFAULT_ONLY);
            if (!resolveInfoList.isEmpty()) {
                for (ResolveInfo list : resolveInfoList) {
                    if (!BuildConfig.APP_PACKAGE_NAME.equals(list.activityInfo.packageName)) {
                        packageInfo = list;
                        break;
                    }
                }
            }
            if (packageInfo != null) {
                browserIntent.setClassName(packageInfo.activityInfo.packageName, packageInfo.activityInfo.name);
                context.startActivity(browserIntent);
            } else {
                Toast.makeText(context, R.string.can_not_open_url, Toast.LENGTH_SHORT).show();
            }
        } catch (Exception e) {
            Toast.makeText(context, R.string.can_not_open_url, Toast.LENGTH_SHORT).show();
        }
    }