개발 관련/SW, App 관련

Unity Deep Link (딥링크) 관련

by 소서리스25 2025. 5. 1.
반응형

Unity Deep Link (딥링크) 관련

 

앱을 개발하다 외부에서 앱을 실행하며 특정 파라미터에 따라 앱의 기능이 달리 실행되도록 하는 것이 필요해서 찾아봤는데, 바로 딥링크 기능을 이용하면 된다고 한다.

 

이에 따라 관련된 자료를 찾아봤는데 Application.deepLinkActivated 로 이 기능을 활성화하려면 최소 유니티 2019.4 버전 이상에서만 가능한 것이었다.

 

지원되는 최소버전 이하에서 사용하려면 기본적인 Application.absoluteURL 의 기능을 이용하는 수밖에 없다.

왜냐하면 내가 주력으로 사용하는 버전이 유니티 2018.4.3이기 때문이다.

 

따라서 일단 Application.absoluteURL과 AndroidManifest.xml을 편집하여 주요 내용을 추가하고 테스트용 HTML을 통해 시도하였으나 결국에는 작동하지 않았다. 

즉, 관련된 사항을 모두 입력하였으나 앱이 실행되지 않았다. 아무런 반응이 없다.

 

여러 사이트에서 설명하고 작동되는 것을 동영상으로도 보여줬으나 일단 내게는 되지 않았다.

 

결국에는 지난번 아두이노 코드 만드는 것을 시도했던 제미나이를 통해 물어봤다.

물론 제미나이를 통해 얻은 것으로도 한번에 되지는 않았다.

 

처음 제시한 코드는 다음과 같은데 실행되지 않았다. 코드 자체는 문제가 없었다. 물론 이것이 AndroidManifest.xml과 연동이 잘 안 되어서 그런 것 일 수 있다.

using UnityEngine;

public class DeepLinkManager : MonoBehaviour
{
    public static DeepLinkManager Instance { get; private set; }
    public string deeplinkURL;

    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            // 앱 실행 간에 유지되도록 설정 (필요에 따라)
            // DontDestroyOnLoad(gameObject); 

            // 앱 시작 시 딥링크 URL 확인
            deeplinkURL = Application.absoluteURL; 

            if (!string.IsNullOrEmpty(deeplinkURL))
            {
                Debug.Log("딥링크로 실행됨: " + deeplinkURL);
                // URL 파싱 및 처리 로직 호출
                HandleDeepLink(deeplinkURL); 
            }
            else
            {
                Debug.Log("일반 실행됨");
                deeplinkURL = null;
            }
        }
        else
        {
            Destroy(gameObject);
        }
    }

    private void HandleDeepLink(string url)
    {
        // URL 스킴 (예: "myapp://") 확인
        if (url.StartsWith("myapp://")) 
        {
            // URL 경로 및 쿼리 파싱 (예: "myapp://profile?id=123")
            // Uri uri = new Uri(url); 
            // string host = uri.Host; // "profile"
            // string query = uri.Query; // "?id=123"
            
            // 파싱된 정보를 바탕으로 특정 씬 로드, 데이터 표시 등 구현
            Debug.Log("딥링크 처리 로직 실행: " + url);
        }
    }
}

 

 

다만, 제미나이로 여러 번 질문을 다르게 해서 기존과 다른 방법을 제시한 것을 토대로 코드를 재구성해 보았다. 왜냐면 기존 다른 분들이 소개한 방법이 처음 제미나이가 제시한 것과 비슷했기 때문에 다른 제안을 하도록 계속 질문을 바꿔봤다.

 

따라서 이를 토대로 다음과 같이 내가 활용할 테스트 코드로 최종적으로 변경하였다.

using UnityEngine;
using UnityEngine.UI;

public class DeepLinkHandler : MonoBehaviour
{
    public Text _text;

    void OnEnable()
    {
        GetIntent();
    }

    void GetIntent()
    {
#if UNITY_ANDROID
        AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
        AndroidJavaObject intent = currentActivity.Call<AndroidJavaObject>("getIntent");
        string action = intent.Call<string>("getAction");
        AndroidJavaObject uri = intent.Call<AndroidJavaObject>("getData");

        if (action == "android.intent.action.VIEW" && uri != null)
        {
            string deepLinkURL = uri.Call<string>("toString");
            Debug.Log("Android Deep Link URL: " + deepLinkURL);
            DeepLinkTest(deepLinkURL);
        }
        else
        {
            _text.text = "No data..";
        }
#endif
    }

    void DeepLinkTest(string url)
    {
        _text.text = url;

        string _stringUrl = url.Split("="[0])[1];

        _text.text = _text.text + "\n" + _stringUrl;
    }

    private void OnApplicationPause(bool pause)
    {
        if (!pause)
        {
            GetIntent();
        }
    }
}

 

 

위의 코드는 언제든지 파라미터를 달리하여 외부에서 실행될 수 있도록 했다.

이와 함께 연동되는 AndroidManifest.xml은 다음과 같이 설정하였다.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
  package="com.unity3d.player"
  xmlns:tools="http://schemas.android.com/tools">
  <application android:icon="@drawable/app_icon" android:label="@string/app_name">
    <activity android:name="com.unity3d.player.UnityPlayerActivity"
              android:theme="@style/UnityThemeSelector"
              android:exported="true">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
      <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="myapp" android:host="scene" android:pathPrefix="/d=nameA"/>
        <data android:scheme="myapp" android:host="scene" android:pathPrefix="/d=nameB"/>
      </intent-filter>        
    </activity>
  </application>
</manifest>

 

여기서 중요한 것은 두 번째 항목에 있는 intent-filter 영역이다. 

scheme와 host, 그리고 pathPrefix가 반드시 있어야 된다. 여러 가지 테스트를 했는데, 왜그런지 모르겠지만 이게 없으면 앱을 불러오지 못했다. 아마 상위버전에서는 될 수 있어도 유니티 2018.4에서는 모두 있어야 가능했다.

 

여기까지 진행되었다면 거의 다 된 것이나 마찬가지이다.

 

위의 소스는 상위버전에서도 Application.deepLinkActivated를 쓰지 않고서도 잘 된다. 테스트 결과 적어도 2021.3까지 문제없이 작동되었다.

 

다음으로 확인할 것은 HTML에서 직접 클릭해 보는 것이다. 일반적인 URL로 연결하면 안 된다고 한다. 

테스트 HTML의 코드는 다음과 같다.

<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
</head>
<body >
<h1>My Deep Link Test page</h1>
<h2 >
<a href="myrpp://scene/d=nameA">Activate A</a>
</h2>
<h2 >
<a href="myapp://scene/d=nameB">Activate B</a>
</h2>
</body>
</html>

 

 

앱을 빌드하고 HTML을 실행하면 Activate A와 B의 클릭버튼이 보일 것이다.

이것을 클릭하면 각각의 해당하는 즉, d=nameA와 d=nameB에 해당하는 것에 따라 앱이 동작할 것이다.

 

그리고 해당 URL을 불러오면 유니티에서 url.split("="[0])[1]로 "="을 구분하여 실행하면 원하는 파라미터에 따른 동작을 수행할 수 있을 것이다.

 

그리고 앱이 일시정지 상태에서 HTML로 서로 다른 것을 실행하면 해당 것이 실행될 것이다.

 

실행에 대한 동영상을 참고해 보자.

 

 

반응형

댓글