Huawei AGC App Linking integration with Unity
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)