[Huawei Developers] muraliameakula:
HMS App Linking Introduction

HMS App Linking allows you to create cross-platform links that can work as defined regardless of whether your app has been installed by a user. When a user taps the link on an Android or iOS device, the user will be redirected to the specified in-app content. If a user taps the link in a browser, the user will be redirected to the same content of the web version.

To identify the source of a user, you can set tracing parameters for various channels when creating a link of App Linking to trace traffic sources. By analyzing the link performance of each traffic source based on the tracing parameters, you can find the platform that can achieve better promotion effect for your app:

Deferred deep link: Directs a user who has not installed your app to AppGallery to download your app first and then navigate to the link in-app content directly, without requiring the user to tap the link again.

Link display in card form: Uses a social Meta tag to display a link of App Linking as a card, which will attract more users from social media.

Statistics: Records the data of all link-related events, such as numbers of link taps, first app launches, and non-first app launches for you to conduct analysis.

API Overview

1. (Mandatory) Call AppLinking.Builder to create a Builder object.

2. (Mandatory) Call AppLinking.Builder.setUriPrefix to set the URL prefix that has been applied for in Applying for a URL Prefix.

3. (Mandatory) Call AppLinking.Builder.setDeepLink to set a deep link.

4. Call AppLinking.Builder.setAndroidLinkInfo to set Android app parameters. In this method, Android app parameters are contained in an AppLinking.AndroidLinkInfo instance, which can be built by calling AppLinking.AndroidLinkInfo.Builder. If this method is not called, the link will be opened in the browser by default.

5. Call AppLinking.Builder.setIOSLinkInfo to set iOS app parameters. In this method, iOS app parameters are contained in an AppLinking.IOSLinkInfo instance, which can be built by calling AppLinking.IOSLinkInfo.Builder. If this method is not called, the link will be opened in the browser by default.

6. Call AppLinking.IOSLinkInfo.Builder.setITunesConnectCampaignInfo to set App Store Connect campaign parameters. In this method, App Store Connect campaign parameters are contained in an AppLinking.ITunesConnectCampaignInfo instance, which can be built by calling AppLinking.ITunesConnectCampaignInfo.Builder.

7. Call AppLinking.Builder.setPreviewType to set the link preview type. If this method is not called, the preview page with app information is displayed by default.

8. Call AppLinking.Builder.setSocialCardInfo to set social Meta tags. In this method, social Meta tags are contained in an AppLinking.SocialCardInfo instance, which can be built by calling AppLinking.SocialCardInfo.Builder. If this method is not called, links will not be displayed as cards during social sharing.

9. Call AppLinking.Builder.setCampaignInfo to set ad tracing parameters. In this method, campaign parameters are contained in an AppLinking.CampaignInfo instance, which can be built by calling AppLinking.CampaignInfo.Builder.

Key Concepts

URL prefix

The URL prefix is the domain name contained in a link, which is in https://Domain name format. You can use the domain name provided by AppGallery Connect for free.

Long link

A long link is a link of App Linking in its entirety. follows this format:

URL prefix+Deep link+Android app parameters+iOS app parameters+[Preview type]+[Social meta tag]+[Tracing parameters]+[Landing page display parameter]+[Site ID].

An example of a long link is as follows:

https://yourapp.drcn.agconnect.link/?deeplink=https%3A%2F%2Fyourdeeplink.com&android_deeplink=https%3A%2F%2Fyourdeeplink.com&android_open_type=1&android_package_name=tiantian.huawei&campaign_channel=huawei&campaign_medium=pic&campaign_name=%E4%BF%83%E9%94%80&ios_link=https%3A%2F%2Fyourdeeplink.com&ios_bundle_id=aapp.huawei&at=1234&pt=212&ct=1234&mt=1&preview_type=2&social_title=%E6%8E%A5%E5%85%A5%E4%BF%83%E9%94%80&landing_page_type=1&&region_id=0

Short link

If a long link is too long, it can be converted to a short link. A short link follows this format:

URL prefix+Random suffix of the string type

Prerequisite

Huawei Phone

Android Studio

AppGallery Account

App Development

Create a New Project.

Configure Project Gradle.

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
repositories {
google()
jcenter()
//TODO
maven { url 'https://developer.huawei.com/repo/' }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.3'
//TODO
classpath 'com.huawei.agconnect:agcp:1.4.2.301'
}
}

allprojects {
repositories {
google()
jcenter()
//TODO
maven { url 'https://developer.huawei.com/repo/' }
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}

3. Configure App Gradle.

implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.cardview:cardview:1.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
//TODO
implementation 'com.huawei.agconnect:agconnect-applinking:1.4.2.301'
implementation 'com.huawei.hms:hianalytics:5.0.5.301'

4. Configure AndroidManifest.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.hms.applinkandroid">

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity
android:name=".applinking.DetailActivity"
android:configChanges="orientation|keyboardHidden|screenSize" />

<activity
android:name=".applinking.SettingActivity"
android:configChanges="orientation|keyboardHidden|screenSize" />

</application>

</manifest>

5. Create Activity class with XML UI.

MainActivity.java:

This activity performs all the operation of AppLinking with short and long url with Share card.

package com.hms.applinkandroid;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import com.hms.applinkandroid.applinking.DetailActivity;
import com.hms.applinkandroid.applinking.SettingActivity;
import com.huawei.agconnect.applinking.AGConnectAppLinking;
import com.huawei.agconnect.applinking.AppLinking;
import com.huawei.agconnect.applinking.ShortAppLinking;

public class MainActivity extends AppCompatActivity {

private static final String DOMAIN_URI_PREFIX = "https://applinkingtest.drcn.agconnect.link";
private static final String DEEP_LINK = "https://developer.huawei.com/consumer/cn/doc/development/AppGallery-connect-Guides";

private TextView shortTextView;
private TextView longTextView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
shortTextView = findViewById(R.id.shortLinkText);
longTextView = findViewById(R.id.longLinkText);

findViewById(R.id.create)
.setOnClickListener(
view -> {
createAppLinking();
});

findViewById(R.id.shareShort)
.setOnClickListener(
view -> {
shareLink((String) shortTextView.getText());
});

findViewById(R.id.shareLong)
.setOnClickListener(
view -> {
shareLink((String) longTextView.getText());
});

AGConnectAppLinking.getInstance()
.getAppLinking(this)
.addOnSuccessListener(
resolvedLinkData -> {
Uri deepLink = null;
if (resolvedLinkData != null) {
deepLink = resolvedLinkData.getDeepLink();
}

TextView textView = findViewById(R.id.deepLink);
textView.setText(deepLink != null ? deepLink.toString() : "");

if (deepLink != null) {
String path = deepLink.getLastPathSegment();
if ("detail".equals(path)) {
Intent intent = new Intent(getBaseContext(), DetailActivity.class);
for (String name : deepLink.getQueryParameterNames()) {
intent.putExtra(name, deepLink.getQueryParameter(name));
}
startActivity(intent);
}
if ("setting".equals(path)) {
Intent intent = new Intent(getBaseContext(), SettingActivity.class);
for (String name : deepLink.getQueryParameterNames()) {
intent.putExtra(name, deepLink.getQueryParameter(name));
}
startActivity(intent);
}
}
})
.addOnFailureListener(
e -> {
Log.w("MainActivity", "getAppLinking:onFailure", e);
});
}

private void createAppLinking() {
AppLinking.Builder builder = new AppLinking.Builder()
.setUriPrefix(DOMAIN_URI_PREFIX)
.setDeepLink(Uri.parse(DEEP_LINK))
.setAndroidLinkInfo(new AppLinking.AndroidLinkInfo.Builder().build())
.setSocialCardInfo(new AppLinking.SocialCardInfo.Builder()
.setTitle("华为开发者大会")
.setImageUrl("https://developer.huawei.com/consumer/cn/events/hdc2020/img/kv-pc-cn.png?v0808")
.setDescription("Description").build())
.setCampaignInfo(new AppLinking.CampaignInfo.Builder()
.setName("HDC")
.setSource("AGC")
.setMedium("App").build());
longTextView.setText(builder.buildAppLinking().getUri().toString());

builder.buildShortAppLinking().addOnSuccessListener(shortAppLinking -> {
shortTextView.setText(shortAppLinking.getShortUrl().toString());
}).addOnFailureListener(e -> {
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
});

}

private void shareLink(String appLinking) {
if (appLinking != null) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, appLinking);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}

private void showError(String msg) {
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}

return super.onOptionsItemSelected(item);
}
}

main_activity.xml:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/ic_bg"
android:gravity="center"
android:orientation="vertical"
tools:context=".MainActivity">

<TextView
android:id="@+id/TitleView"
android:layout_width="281dp"
android:layout_height="51dp"
android:text="Android Deep Link"
android:textColor="@android:color/white"
android:textSize="30dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.061" />

<androidx.cardview.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
card_view:cardElevation="5dp"
card_view:cardUseCompatPadding="true"
card_view:contentPadding="5dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical">

<TextView
android:id="@+id/textView5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Deeplink"
android:textColor="@android:color/black"
android:textSize="18sp"
android:textStyle="bold" />

<TextView
android:id="@+id/deepLink"
android:layout_width="match_parent"
android:layout_height="59dp"
android:textColor="@android:color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.241" />

<Button
android:id="@+id/create"
android:layout_width="230dp"
android:layout_height="50dp"
android:text="Create App Linking"
android:textAllCaps="false"
android:textSize="19sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.324" />
</LinearLayout>

</androidx.cardview.widget.CardView>

<androidx.cardview.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
card_view:cardElevation="5dp"
card_view:cardUseCompatPadding="true"
card_view:contentPadding="5dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical">

<TextView
android:id="@+id/textView3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="Long App Linking:"
android:textColor="@android:color/black"
android:textSize="18sp"
android:textStyle="bold" />

<TextView
android:id="@+id/longLinkText"
android:layout_width="match_parent"
android:layout_height="80dp"
android:gravity="center_horizontal" />

<Button
android:id="@+id/shareLong"
android:layout_width="230dp"
android:layout_height="50dp"
android:text="Share long App Linking"
android:textAllCaps="false"
android:textSize="19sp" />
</LinearLayout>

</androidx.cardview.widget.CardView>

<androidx.cardview.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
card_view:cardElevation="5dp"
card_view:cardUseCompatPadding="true"
card_view:contentPadding="5dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical">

<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="Short App Linking:"
android:textColor="@android:color/black"
android:textSize="18sp"
android:textStyle="bold" />

<TextView
android:id="@+id/shortLinkText"
android:layout_width="match_parent"
android:layout_height="60dp"
android:gravity="center_horizontal" />

<Button
android:id="@+id/shareShort"
android:layout_width="230dp"
android:layout_height="50dp"
android:text="Share short App Linking"
android:textAllCaps="false"
android:textSize="19sp" />
</LinearLayout>

</androidx.cardview.widget.CardView>

</LinearLayout>
</ScrollView>

App Gallery Integration process

Sign In and Create or Choose a project on AppGallery Connect portal.

Navigate to Project settings and download the configuration file.

Navigate to General Information, and then provide Data Storage location.

Navigate to Manage APIs and enable APIs which is required by application.

Navigate to AppLinking and Enable.

Add New link.

Navigate to App Linking and select Set domain name.

Copy Domain Name and add in your project.

App Build Result

Tips and Tricks

Since HUAWEI Analytics Kit 4.0.3.300, the SDK for Android has been significantly improved in the stability, security, and reliability. If the SDK you have integrated is earlier than 4.0.3.300, please upgrade it to 4.0.3.300 or later before April 30, 2021. From May 1, 2021, HUAWEI Analytics will not receive data reported by SDK versions earlier than 4.0.3.300. If you have integrated App Linking, you also need to upgrade its SDK to 1.4.1.300 or later for Android before April 30, 2021. Otherwise, functions that depend on HUAWEI Analytics will become unavailable.

Huawei strictly conforms to the General Data Protection Regulation (GDPR) in providing services and is dedicated to helping developers achieve business success under the principles of the GDPR. The GDPR stipulates the obligations of the data controller and data processor. When using our service, you act as the data controller, and Huawei is the data processor. Huawei solely processes data within the scope of the data processor's obligations and rights, and you must assume all obligations of the data controller as specified by the GDPR.

Conclusion

In this article, we have learned how to integrate AppLinking in application. In this application, I have explained that how to deep link our application with URL.

Thanks for reading this article. Be sure to like and comments to this article, if you found it helpful. It means a lot to me.

References

HMS AppLinking Doc: Link

Original Source