Huawei AGC App Linking integration with Unity

AppGallery Team
AppGallery
Published in
5 min readAug 10, 2021

Introduction:

In this article, we will cover Integration of AGC App Linking in Unity Project using Official Plugin (Huawei HMS Core App Services).

Requirements:

1. Unity Editor

2. Huawei device

3. Visual Studio

Follows the steps.

Step 1. Create Unity Project.

  • Click unity icon.
  • Click NEW, select 3D, Project Name and Location.
  • Click CREATE, as follows.

Step 2. Click Asset Store, search Huawei HMS Core App Services and click Import, as follows.

Step 3. Once import is successful, verify directory in Assets > Huawei HMS Core App Services path, as follows.

Step 4. Click Console and create a New Project.

Step 5. Choose Project Settings > Player and edit the required options in Publishing Settings, as follows.

Step 6. Verify the files created in Step 5.

Step 7. Download agconnect-services.json and copy to Assets>Plugins>Android, as follows.

Step 8. Update the Package Name.

Step 9. Open LauncherTemplate.gradle and add below line

apply plugin: 'com.huawei.agconnect'

Step 10. Open “baseProjectTemplate.gradle” and add lines, as follows.

maven {url 'https://developer.huawei.com/repo/'}

classpath 'com.huawei.agconnect:agcp:1.4.1.300'

Step 11. Open “mainTemplate.gradle” and add lines like shown below

apply plugin: 'com.huawei.agconnect'

implementation 'com.huawei.agconnect:agconnect-core:1.4.1.300'

implementation 'com.huawei.agconnect:agconnect-applinking:1.4.0.300'

implementation 'com.huawei.hms:hianalytics:5.0.3.300'

Step 12. Open AndroidManifest file and Add Activity like shown below.

<activity android:name="com.hms.hms_analytic_activity.TestAppLinksActivity"

android:theme="@style/UnityThemeSelector">

<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="developer.huawei.com" android:scheme="https" />

<data android:host="developer.huawei.com" android:scheme="http" />

</intent-filter>

</activity>

Step 13. Create TestAppLinksActivity.java, JavaCallBack.java and place it in Assets->Plugins->Android.

//package com.test.applinks;

package com.hms.hms_analytic_activity;

import android.app.Activity;

import android.content.Context;

import android.content.Intent;

import android.net.Uri;

import android.os.Bundle;

import android.util.Log;

import com.unity3d.player.UnityPlayerActivity;

import android.widget.Toast;

import com.huawei.agconnect.applinking.AGConnectAppLinking;

import com.huawei.agconnect.applinking.AppLinking;

import com.huawei.agconnect.applinking.ShortAppLinking;

//import androidx.appcompat.app.AppCompatActivity;

import com.huawei.agconnect.applinking.AGConnectAppLinking;

public class TestAppLinksActivity extends UnityPlayerActivity {

public static JavaCallback callback;

private static String agcLink = null;

private static final String DOMAIN_URI_PREFIX = "https://testulink.dra.agconnect.link";

//private static final String DEEP_LINK = "rmOb2";

private static final String DEEP_LINK = "https://developer.huawei.com/consumer/cn/doc/development/AppGallery-connect-Guides?id=123";

private static String deepLinkData = "";

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

Log.e("TestAppLinksActivity", "TestAppLinksActivity onCreate>> @@");

mContext = this.getApplicationContext();

handleAppLinking(getIntent());

}

public static void setCallback(JavaCallback callback1) {

Log.e("TestAppLinksActivityl", "setCallback>> @@");

callback = callback1;

if(callback != null){

Log.e("TestAppLinksActivity", "update c # script >>>>");

callback.OnJavaCallback(deepLinkData);

}else{

Log.e("TestAppLinksActivity", "TestAppLinksActivity callback is null plz initialize >>>>");

}

}

private void handleAppLinking(Intent intent) {

AGConnectAppLinking.getInstance().getAppLinking(this, intent).addOnSuccessListener(resolvedLinkData -> {

Uri deepLink = null;

if (resolvedLinkData != null) {

deepLink = resolvedLinkData.getDeepLink();

Log.e("TestAppLinksActivity", " getAppLinking@!!!$$->"+deepLink.toString());

deepLinkData = deepLink.toString();

if(callback != null){

Log.e("TestAppLinksActivity", "update c # script");

callback.OnJavaCallback(deepLink.toString());

}else{

Log.e("TestAppLinksActivity", "callback is null plz initialize");

}

}

}).addOnFailureListener(e -> {

Log.e("TestAppLinksActivity", "getAppLinking:onFailure", e);

});

}

@Override

protected void onNewIntent(Intent intent) {

super.onNewIntent(intent);

setIntent(intent);

handleAppLinking(intent);

}

public static void createAppLinking() {

AppLinking.Builder builder = new AppLinking.Builder().setUriPrefix(DOMAIN_URI_PREFIX)

.setDeepLink(Uri.parse(DEEP_LINK));

//longTextView.setText(builder.buildAppLinking().getUri().toString());

Log.e("TestAppLinksActivity", "createAppLinking long -->"+builder.buildAppLinking().getUri().toString());

agcLink = builder.buildAppLinking().getUri().toString();

builder.buildShortAppLinking(ShortAppLinking.LENGTH.SHORT).addOnSuccessListener(shortAppLinking -> {

//shortTextView.setText(shortAppLinking.getShortUrl().toString());

Log.e("TestAppLinksActivity", "createAppLinking short -->"+shortAppLinking.getShortUrl().toString());

agcLink = shortAppLinking.getShortUrl().toString();

}).addOnFailureListener(e -> {

//Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();

Log.e("TestAppLinksActivity", "createAppLinking failure -->"+e.getMessage());

});

}

//public void shareLink() {

public static void shareLink(Activity activity){

if (agcLink != null) {

Log.e("TestAppLinksActivity", "shareLink agcLink is not null start activity");

Intent intent = new Intent(Intent.ACTION_SEND);

intent.setType("text/plain");

intent.putExtra(Intent.EXTRA_TEXT, agcLink);

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

activity.startActivity(intent);

//startActivity(intent);

}else{

Log.e("TestAppLinksActivity", " shareLink agcLink is null");

}

}

private static Context mContext;

public static Context getAppContext(){

return mContext;

}

}

code explanation : https://developer.huawei.com/consumer/en/codelab/AppLinking/index.html#7

package com.hms.hms_analytic_activity;

public interface JavaCallback {

void OnJavaCallback(String index);

}

Note : Java classes are using package name com.hms.hms_analytic_activity & we dont create any folder structure, this is allowed.

Step 14. C# Scripting

TestLinks.cs — Two buttons are added to call functions of TestLinksActivity

using System.Collections;

using System.Collections.Generic;

using HuaweiHmsLinks;

using UnityEngine;

using UnityEngine.UI;

public class TestLinks : MonoBehaviour

{

public Text appLinkText;

public Button createAppLink;

public Button shareAppLink;

private void Awake()

{

Debug.LogError("register links listener --->");

RegisterLinksListener.registerListener(new LinksListen(this));

Button btn = createAppLink.GetComponent<Button>();

btn.onClick.AddListener(TaskOnClick);

Button btnShare = shareAppLink.GetComponent<Button>();

btnShare.onClick.AddListener(ShareOnClick);

}

void TaskOnClick()

{

Debug.Log("You have clicked the button to create applinking!");

RegisterLinksListener.createAppLinking();

}

void ShareOnClick()

{

Debug.Log(" You have clicked the share button to share applinking!");

RegisterLinksListener.shareAppLinking();

}

// Start is called before the first frame update

void Start()

{

}

// Update is called once per frame

void Update()

{

}

class LinksListen : ILinksServiceListener {

private TestLinks testLinks;

public LinksListen(TestLinks testLinks)

{

this.testLinks = testLinks;

}

public override void OnJavaCallback(string arg0)

{

Debug.LogError("links received--->"+arg0);

testLinks.appLinkText.text = arg0;

//testLinks.text = arg0;

}

}

}

ILinksServiceListener.cs — This is Listener passed to TestAppLinksActivity

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

namespace HuaweiHmsLinks

{

public class ILinksServiceListener : AndroidJavaProxy

{

public ILinksServiceListener() : base("com.hms.hms_analytic_activity.JavaCallback") { }

public virtual void OnJavaCallback(string arg0)

{

}

}

}

RegisterLinksListener.cs — This is used to call methods of TestAppLinksActivity

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

namespace HuaweiHmsLinks

{

public class RegisterLinksListener

{

public static void registerListener(ILinksServiceListener listener)

{

AndroidJavaClass cl = new AndroidJavaClass("com.hms.hms_analytic_activity.TestAppLinksActivity");

cl.CallStatic("setCallback", listener);

}

public static void createAppLinking()

{

AndroidJavaClass cl = new AndroidJavaClass("com.hms.hms_analytic_activity.TestAppLinksActivity");

cl.CallStatic("createAppLinking");

}

public static void shareAppLinking()

{

AndroidJavaClass androidJC = new AndroidJavaClass("com.unity3d.player.UnityPlayer");

AndroidJavaObject jo = androidJC.GetStatic<AndroidJavaObject>("currentActivity");

AndroidJavaClass jc = new AndroidJavaClass("com.hms.hms_analytic_activity.TestAppLinksActivity");

jc.CallStatic("shareLink", jo);

//AndroidJavaClass cl = new AndroidJavaClass("com.hms.hms_analytic_activity.TestAppLinksActivity");

//cl.CallStatic("shareLink");

//cl.Call("shareLink");

}

}

}

Step 15. Attach buttons as shown below

Step 16. How to test app linking ?

a) Run the project and click on CreateAppLink (Button)

b) Click on ShareAppLink (Button) and share link to notepad or any other app

c) Close game app, open notepad and click on link

d) This will open up linked application with this app link.

Conclusion:

AGC app links can create long links, as well as short links, as shown in demo.

References:

Location Kit Integration in Unity — Official Plugin (Huawei HMS Core App Services)

--

--

AppGallery Team
AppGallery

Insights, success stories, and monetization tips for app development at https://medium.com/appgallery