Android 앱 링크 인증하기

Android 앱 링크는 사용자가 앱을 선택할 필요 없이 웹사이트 URL을 클릭하면 Android 앱에서 해당 콘텐츠가 바로 열리도록 하는 특별한 유형의 딥 링크입니다. Android 앱 링크는 Digital Asset Links API를 사용하여 앱이 웹사이트에서 승인되어 해당 도메인의 링크를 자동으로 열 수 있다는 신뢰를 구축합니다. 시스템에서 개발자의 URL 소유권이 확인되면 URL 인텐트를 앱에 자동으로 라우팅합니다.

앱과 웹사이트 URL을 모두 소유하고 있는지 확인하려면 다음 단계를 완료하세요.

  1. autoVerify 속성이 포함된 인텐트 필터를 추가합니다. 이 속성은 앱이 인텐트 필터에 사용된 URL 도메인에 속하는지 확인해야 한다고 시스템에 신호를 보냅니다.

  2. 다음 위치에서 디지털 애셋 링크 JSON 파일을 호스팅하여 웹사이트와 인텐트 필터 간의 연결을 선언합니다.

    https://domain.name/.well-known/assetlinks.json

다음 리소스에서 관련 정보를 찾을 수 있습니다.

앱 링크 인증을 위한 인텐트 필터 추가

앱의 링크 처리 인증을 사용 설정하려면 다음 형식과 일치하는 인텐트 필터를 추가합니다.

<!-- Make sure you explicitly set android:autoVerify to "true". -->
<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" />

    <!-- If a user clicks on a shared link that uses the "http" scheme, your
         app should be able to delegate that traffic to "https". -->
    <!-- Do not include other schemes. -->
    <data android:scheme="http" />
    <data android:scheme="https" />

    <!-- Include one or more domains that should be verified. -->
    <data android:host="..." />
</intent-filter>

호스트가 다른 표시 해제된 선언 간에 사용되더라도 각 호스트의 <intent-filter> 선언 하나에만 autoVerify를 포함하는 것으로 충분하지만 일관성을 위해 각 <intent-filter> 요소에 autoVerify를 추가하는 것이 좋습니다. 이렇게 하면 매니페스트 파일에서 요소를 삭제하거나 리팩터링한 후에도 앱이 여전히 정의된 모든 도메인과 연결된 상태로 유지됩니다.

도메인 확인 프로세스는 인터넷 연결이 필요하고 완료하는 데 다소 시간이 걸릴 수 있습니다. 프로세스의 효율성을 개선할 수 있도록 시스템은 Android 12 이상을 타겟팅하는 앱의 도메인이 이전 코드 스니펫에 지정된 정확한 형식이 포함된 <intent-filter> 요소 내에 있는 경우에만 이 도메인을 확인합니다. 예를 들어 <data android:scheme="custom" />와 같이 'http' 및 'https'가 아닌 스키마는 <intent-filter>가 도메인 확인을 트리거하지 못하게 합니다.

여러 호스트에서 앱 링크 지원

시스템은 앱의 URL 인텐트 필터의 데이터 요소에 지정된 호스트를 해당 인텐트 필터의 각 웹 도메인에서 호스팅되는 디지털 애셋 링크 파일과 비교하여 확인할 수 있어야 합니다. 인증에 실패하면 시스템은 기본적으로 표준 동작을 사용하여 인텐트를 해결합니다(앱 콘텐츠의 딥 링크 만들기의 설명 참고). 그러나 앱은 앱의 다른 인텐트 필터에 정의된 URL 패턴 중 어느 것에 대해서도 기본 핸들러로 인증될 수 있습니다.

참고: Android 11 (API 수준 30) 이하에서는 매니페스트에 정의한 모든 호스트에 일치하는 디지털 애셋 링크 파일이 발견되지 않는 한 시스템에서 앱을 기본 핸들러로 확인하지 않습니다.

예를 들어 다음 인텐트 필터가 포함된 앱은 https://www.example.com/.well-known/assetlinks.jsonassetlinks.json 파일이 있고 https://www.example.net/.well-known/assetlinks.json에는 없는 경우에만 https://www.example.com에 대한 인증을 통과합니다.

<application>

  <activity android:name=”MainActivity”>
    <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="http" />
      <data android:scheme="https" />
      <data android:host="www.example.com" />
    </intent-filter>
  </activity>
  <activity android:name=”SecondActivity”>
    <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:scheme="https" />
     <data android:host="www.example.net" />
    </intent-filter>
  </activity>

</application>

참고: 동일한 인텐트 필터의 모든 <data> 요소는 결합된 속성의 모든 변형을 설명하기 위해 함께 병합됩니다. 예를 들어 위의 첫 번째 인텐트 필터에는 HTTPS 스키마만 선언하는 <data> 요소가 포함되어 있습니다. 하지만, 인텐트 필터가 http://www.example.comhttps://www.example.com을 모두 지원하도록 다른 <data> 요소와 결합됩니다. 따라서 URI 스키마와 도메인의 특정 조합을 정의하려면 별도의 인텐트 필터를 만들어야 합니다.

여러 하위 도메인에서 앱 링크 지원

디지털 애셋 링크 프로토콜은 인텐트 필터에 있는 하위 도메인을 별도의 고유 호스트로 취급합니다. 따라서 인텐트 필터에 서로 다른 하위 도메인을 가진 여러 호스트가 나열된 경우에는 각 도메인에 유효한 assetlinks.json를 게시해야 합니다. 예를 들어 다음 인텐트 필터는 www.example.commobile.example.com를 허용된 인텐트 URL 호스트로 포함합니다. 따라서 유효한 assetlinks.jsonhttps://www.example.com/.well-known/assetlinks.jsonhttps://mobile.example.com/.well-known/assetlinks.json 양쪽에 게시해야 합니다.

<application>
  <activity android:name=”MainActivity”>
    <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="https" />
      <data android:host="www.example.com" />
      <data android:host="mobile.example.com" />
    </intent-filter>
  </activity>
</application>

또는 와일드 카드 (예: *.example.com)를 사용하여 호스트 이름을 선언하는 경우에는 루트 호스트 이름(example.com)에 assetlinks.json 파일을 게시해야 합니다. 예를 들어 다음 인텐트 필터가 사용된 앱은 assetlinks.json 파일이 https://example.com/.well-known/assetlinks.json에 게시된 경우 example.com의 모든 하위 이름 (예: foo.example.com)과 관련된 인증을 통과합니다.

<application>
  <activity android:name=”MainActivity”>
    <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:host="*.example.com" />
    </intent-filter>
  </activity>
</application>

동일한 도메인에 연결된 여러 앱 확인

각각 같은 도메인과 연결된 앱을 여러 개 게시하면 각각 성공적으로 확인될 수 있습니다. 그러나 앱의 라이트 및 전체 버전과 마찬가지로 앱이 똑같은 도메인 호스트 및 경로를 확인할 수 있다면 가장 최근에 설치된 앱만 도메인의 웹 인텐트를 확인할 수 있습니다.

이러한 경우 필요한 패키지 공개 상태가 있다면 사용자 기기에서 충돌 가능성이 있는 앱을 확인합니다. 그런 다음 앱에서 queryIntentActivities() 호출의 결과가 포함된 맞춤 선택기 대화상자를 표시합니다. 사용자는 대화상자에 표시되는 일치하는 앱 목록에서 선호하는 앱을 선택할 수 있습니다.

웹사이트 연결 선언하기

디지털 애셋 링크 JSON 파일을 웹사이트에 게시하여 웹사이트와 연결된 Android 앱을 나타내고 앱의 URL 인텐트를 인증해야 합니다. JSON 파일은 다음 필드를 사용하여 연결된 앱을 식별합니다.

  • package_name: 앱의 build.gradle 파일에 선언된 애플리케이션 ID입니다.
  • sha256_cert_fingerprints: 앱 서명 인증서의 SHA256 지문입니다. 다음 명령어를 사용하여 자바 keytool을 통해 지문 파일을 생성할 수 있습니다.
    keytool -list -v -keystore my-release-key.keystore
    
    이 필드는 디버그 빌드나 프로덕션 빌드와 같이 다양한 버전의 앱을 지원하는 데 사용할 수 있는 여러 디지털 지문을 지원합니다.

    앱에 Play 앱 서명을 사용 중인 경우 keytool를 로컬에서 실행하여 생성된 인증서 지문은 일반적으로 사용자 기기의 인증서 지문과 일치하지 않습니다. Play Console 개발자 계정의 Release > Setup > App signing에서 앱에 Play 앱 서명을 사용하고 있는지 확인할 수 있습니다. 사용하면 같은 페이지에서 앱의 올바른 디지털 애셋 링크 JSON 스니펫도 찾을 수 있습니다.

다음 assetlinks.json 파일 예는 com.example Android 앱에 링크 열기 권한을 부여합니다.

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]

웹사이트와 여러 앱 연결하기

웹사이트는 동일한 assetlinks.json 파일에서 여러 앱과의 연결 관계를 선언할 수 있습니다. 다음 파일 목록은 두 앱과의 연결을 별도로 선언하고 https://www.example.com/.well-known/assetlinks.json에 있는 문 파일의 예를 보여줍니다.

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example.puppies.app",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
  },
  {
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example.monkeys.app",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]

서로 다른 앱이 같은 웹 호스트에서 다른 리소스 링크를 처리할 수 있습니다. 예를 들어 app1에서 https://example.com/articles의 인텐트 필터를 선언하고 app2에서 https://example.com/videos의 인텐트 필터를 선언할 수 있습니다.

참고: 한 도메인에 연결된 여러 앱은 동일한 인증서나 서로 다른 인증서로 서명할 수 있습니다.

여러 웹사이트와 단일 앱 연결하기

여러 웹사이트가 각각의 assetlinks.json 파일에서 동일한 앱과의 연결을 선언할 수 있습니다. 다음 파일 목록은 example.com 및 app1과 example.net의 연결을 선언하는 방법의 예입니다. 첫 번째 목록은 example.com과 app1의 연결을 보여줍니다.

https://www.example.com/.well-known/assetlinks.json

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.mycompany.app1",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]

다음 목록은 example.net과 app1의 연결을 보여줍니다. 이러한 파일이 호스팅되는 위치만 다릅니다 (.com.net).

https://www.example.net/.well-known/assetlinks.json

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.mycompany.app1",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]

JSON 인증 파일 게시하기

다음 위치에서 JSON 인증 파일을 게시해야 합니다.

https://domain.name/.well-known/assetlinks.json

다음 사항을 확인하세요.

  • assetlinks.json 파일은 콘텐츠 유형 application/json과 함께 제공됩니다.
  • assetlinks.json 파일은 앱의 인텐트 필터에서 HTTPS를 데이터 스키마로 선언하는지와 관계없이 HTTPS 연결을 통해 액세스 가능해야 합니다.
  • assetlinks.json 파일은 리디렉션 (301 또는 302 리디렉션 없음) 없이 액세스할 수 있어야 합니다.
  • 앱 링크에서 여러 호스트 도메인을 지원하는 경우 각 도메인에 assetlinks.json 파일을 게시해야 합니다. 여러 호스트에서 앱 링크 지원을 참고하세요.
  • 매니페스트 파일에 공개적으로 액세스할 수 없는 개발/테스트 URL (예: VPN을 통해서만 액세스할 수 있는 URL)에 앱을 게시하지 마세요. 이런 경우에는 빌드 변형을 구성하여 개발 빌드용으로 다른 매니페스트 파일을 생성하여 일시적으로 해결할 수 있습니다.

Android App Links 인증

android:autoVerify="true"가 앱의 인텐트 필터 중 하나 이상에 있는 경우 Android 6.0 (API 수준 23) 이상을 실행하는 기기에 앱을 설치하면 시스템이 앱 인텐트 필터의 URL과 연결된 호스트를 자동으로 확인합니다. Android 12 이상에서는 인증 프로세스를 수동으로 호출하여 인증 로직을 테스트할 수도 있습니다.

자동 인증

시스템의 자동 인증에는 다음이 포함됩니다.

  1. 시스템에서 다음 중 하나가 포함된 모든 인텐트 필터를 검사합니다.
    • 작업: android.intent.action.VIEW
    • 카테고리: android.intent.category.BROWSABLEandroid.intent.category.DEFAULT
    • 데이터 스키마: http 또는 https
  2. Android는 위의 인텐트 필터에 있는 각 고유 호스트 이름별로 디지털 애셋 링크에 대응하는 웹사이트를 https://hostname/.well-known/assetlinks.json에서 쿼리합니다.

앱과 연결할 웹사이트 목록을 확인하고 호스팅된 JSON 파일이 유효한지 확인했다면 기기에 앱을 설치합니다. 비동기 인증 프로세스가 완료될 때까지 20초 이상 기다립니다. 다음 명령어를 사용하여 시스템에서 앱이 인증되었는지, 올바른 링크 처리 정책이 설정되었는지 확인합니다.

adb shell am start -a android.intent.action.VIEW \
    -c android.intent.category.BROWSABLE \
    -d "http://domain.name:optional_port"

수동 확인

Android 12부터 기기에 설치된 앱의 도메인 확인을 수동으로 호출할 수 있습니다. 앱의 Android 12 타겟팅 여부와 관계없이 이 프로세스를 실행할 수 있습니다.

인터넷 연결

도메인 확인을 실행하려면 테스트 기기가 인터넷에 연결되어 있어야 합니다.

업데이트된 도메인 확인 프로세스 지원

앱이 Android 12 이상을 타겟팅하는 경우 시스템은 업데이트된 도메인 확인 프로세스를 자동으로 사용합니다.

자동으로 사용하지 않으면 업데이트된 확인 프로세스를 수동으로 사용 설정하면 됩니다. 이렇게 하려면 터미널 창에서 다음 명령어를 실행하세요.

adb shell am compat enable 175408749 PACKAGE_NAME

기기에서 Android App Links 상태 재설정

기기에서 수동으로 도메인 확인을 호출하기 전에 테스트 기기에서 Android App Links 상태를 재설정해야 합니다. 이렇게 하려면 터미널 창에서 다음 명령어를 실행하세요.

adb shell pm set-app-links --package PACKAGE_NAME 0 all

이 명령어는 사용자가 도메인의 기본 앱을 선택하기 전 기기의 상태와 같은 상태로 기기를 설정합니다.

도메인 확인 프로세스 호출

기기에서 Android App Links 상태를 재설정하면 확인 자체를 실행할 수 있습니다. 이렇게 하려면 터미널 창에서 다음 명령어를 실행하세요.

adb shell pm verify-app-links --re-verify PACKAGE_NAME

확인 결과 검토

확인 에이전트가 요청을 완료하도록 잠시 기다린 후 확인 결과를 검토합니다. 이렇게 하려면 다음 명령어를 실행하세요.

adb shell pm get-app-links PACKAGE_NAME

이 명령어 결과는 다음과 같습니다.

com.example.pkg:
    ID: 01234567-89ab-cdef-0123-456789abcdef
    Signatures: [***]
    Domain verification state:
      example.com: verified
      sub.example.com: legacy_failure
      example.net: verified
      example.org: 1026

확인을 통과한 도메인의 도메인 확인 상태는 verified입니다. 그 외 다른 상태는 도메인 확인을 실행할 수 없음을 나타냅니다. 특히 none 상태는 확인 에이전트가 아직 확인 프로세스를 완료하지 않았을 수 있음을 나타냅니다.

다음 목록은 주어진 도메인의 도메인 확인에서 반환할 수 있는 가능한 반환 값을 보여줍니다.

none
이 도메인에는 기록된 것이 없습니다. 확인 에이전트가 도메인 확인 관련 요청을 완료하도록 몇 분 정도 더 기다린 후 다시 도메인 확인 프로세스를 호출합니다.
verified
선언하는 앱의 도메인이 성공적으로 확인되었습니다.
approved
일반적으로 셸 명령어를 실행하여 도메인이 강제 승인되었습니다.
denied
일반적으로 셸 명령어를 실행하여 도메인이 강제 거부되었습니다.
migrated
시스템이 기존 도메인 확인을 사용한 이전 프로세스의 결과를 유지했습니다.
restored
사용자가 데이터 복원을 실행한 후 도메인이 승인되었습니다. 도메인이 이전에 확인된 것으로 추정됩니다.
legacy_failure
기존 인증 도구에서 도메인이 거부되었습니다. 구체적인 실패 이유는 알 수 없습니다.
system_configured
도메인이 기기 설정에서 자동으로 승인되었습니다.
1024 이상의 오류 코드

기기의 인증 도구와 관련된 맞춤 오류 코드입니다.

네트워크 연결을 설정했는지 다시 확인한 후 도메인 확인 프로세스를 다시 호출합니다.

사용자에게 앱을 도메인과 연결하라고 요청

앱이 도메인 승인을 받는 또 다른 방법은 사용자에게 앱을 도메인과 연결하라고 요청하는 것입니다.

앱이 도메인 승인을 이미 받았는지 확인

사용자에게 메시지를 표시하기 전에 앱이 <intent-filter> 요소에서 정의한 도메인의 기본 핸들러인지 확인합니다. 다음 메서드 중 하나를 사용하여 승인 상태를 쿼리할 수 있습니다.

DomainVerificationManager

다음 코드 스니펫은 DomainVerificationManager API 사용 방법을 보여줍니다.

Kotlin

val context: Context = TODO("Your activity or fragment's Context")
val manager = context.getSystemService(DomainVerificationManager::class.java)
val userState = manager.getDomainVerificationUserState(context.packageName)

// Domains that have passed Android App Links verification.
val verifiedDomains = userState?.hostToStateMap
    ?.filterValues { it == DomainVerificationUserState.DOMAIN_STATE_VERIFIED }

// Domains that haven't passed Android App Links verification but that the user
// has associated with an app.
val selectedDomains = userState?.hostToStateMap
    ?.filterValues { it == DomainVerificationUserState.DOMAIN_STATE_SELECTED }

// All other domains.
val unapprovedDomains = userState?.hostToStateMap
    ?.filterValues { it == DomainVerificationUserState.DOMAIN_STATE_NONE }

자바

Context context = TODO("Your activity or fragment's Context");
DomainVerificationManager manager =
        context.getSystemService(DomainVerificationManager.class);
DomainVerificationUserState userState =
        manager.getDomainVerificationUserState(context.getPackageName());

Map<String, Integer> hostToStateMap = userState.getHostToStateMap();
List<String> verifiedDomains = new ArrayList<>();
List<String> selectedDomains = new ArrayList<>();
List<String> unapprovedDomains = new ArrayList<>();
for (String key : hostToStateMap.keySet()) {
    Integer stateValue = hostToStateMap.get(key);
    if (stateValue == DomainVerificationUserState.DOMAIN_STATE_VERIFIED) {
        // Domain has passed Android App Links verification.
        verifiedDomains.add(key);
    } else if (stateValue == DomainVerificationUserState.DOMAIN_STATE_SELECTED) {
        // Domain hasn't passed Android App Links verification, but the user has
        // associated it with an app.
        selectedDomains.add(key);
    } else {
        // All other domains.
        unapprovedDomains.add(key);
    }
}

명령줄 프로그램

개발하는 동안 앱을 테스트할 때 다음 명령어를 실행하여 조직에서 소유한 도메인의 확인 상태를 쿼리할 수 있습니다.

adb shell pm get-app-links --user cur PACKAGE_NAME

다음 출력 예에서 앱은 'example.org' 도메인 확인에 실패했지만 사용자 0은 시스템 설정에서 수동으로 앱을 승인했고 이 도메인에서 확인된 다른 패키지는 없습니다.

com.example.pkg:
ID: ***
Signatures: [***]
Domain verification state:
  example.com: verified
  example.net: verified
  example.org: 1026
User 0:
  Verification link handling allowed: true
  Selection state:
    Enabled:
      example.org
    Disabled:
      example.com
      example.net

셸 명령어를 사용하여 사용자가 특정 도메인과 연결된 앱을 선택하는 프로세스를 시뮬레이션할 수도 있습니다. 이러한 명령어에 관한 자세한 설명은 adb shell pm 출력에서 확인할 수 있습니다.

요청 컨텍스트 제공

도메인 승인을 요청하기 전에 사용자에게 컨텍스트를 제공합니다. 예를 들어 앱이 특정 도메인의 기본 핸들러여야 하는 이유를 사용자에게 설명하는 스플래시 화면이나 대화상자, 유사한 UI 요소를 사용자에게 표시할 수 있습니다.

요청하기

사용자가 앱에서 요청하는 작업을 파악하면 요청을 실행합니다. 다음 코드 스니펫과 같이 ACTION_APP_OPEN_BY_DEFAULT_SETTINGS 인텐트 작업과 타겟 앱의 package:com.example.pkg와 일치하는 데이터 문자열이 포함된 인텐트를 호출합니다.

Kotlin

val context: Context = TODO("Your activity or fragment's Context")
val intent = Intent(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS,
    Uri.parse("package:${context.packageName}"))
context.startActivity(intent)

자바

Context context = TODO("Your activity or fragment's Context");
Intent intent = new Intent(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS,
    Uri.parse("package:" + context.getPackageName()));
context.startActivity(intent);

인텐트가 호출되면 사용자에게 기본적으로 열기라는 설정 화면이 표시됩니다. 이 화면에는 그림 1과 같이 지원되는 링크 열기라는 라디오 버튼이 포함되어 있습니다.

사용자가 지원되는 링크 열기를 사용 설정하면 이 앱에서 열리는 링크 섹션 아래에 체크박스 모음이 표시됩니다. 여기에서 사용자는 앱과 연결하려는 도메인을 선택할 수 있고 그림 2와 같이 링크 추가를 선택하여 도메인을 추가할 수도 있습니다. 나중에 사용자가 추가한 도메인 내에서 링크를 선택하면 링크가 앱에서 자동으로 열립니다.

라디오 버튼을 사용 설정하면 하단의 섹션에 체크박스와 &#39;링크 추가&#39; 버튼이 포함됩니다.
그림 1. 사용자가 기본적으로 앱에서 열리는 링크를 선택할 수 있는 시스템 설정 화면
각 체크박스는 추가할 수 있는 도메인을 나타냅니다. 대화상자의 버튼은 &#39;취소&#39;와 &#39;추가&#39;입니다.
그림 2. 사용자가 앱과 연결할 추가 도메인을 선택할 수 있는 대화상자

앱에서 앱이 확인할 수 없는 도메인 열기

앱의 기본 기능은 처리된 도메인을 확인하는 기능 없이 링크를 타사로 여는 것일 수 있습니다. 이 경우 사용자가 웹 링크를 선택할 때 자사 앱과 타사 앱 중에서 선택할 수 없다고 사용자에게 설명합니다. 사용자는 도메인을 타사 앱과 수동으로 연결해야 합니다.

또한 사용자가 원한다면 자사 앱에서 링크를 열 수 있는 대화상자나 트램펄린 활동을 도입하여 프록시 역할을 하도록 하는 것이 좋습니다. 이러한 대화상자나 트램펄린 활동을 설정하기 전에 앱의 웹 인텐트 필터와 일치하는 자사 앱에 관한 패키지 공개 상태를 보유하도록 앱을 설정합니다.

앱 링크 테스트하기

앱 링크 기능을 구현할 때는 링크 기능을 테스트하여 시스템에서 제대로 앱과 웹사이트를 연결하고 URL 요청을 처리할 수 있는지 확인해야 합니다.

기존 명령문 파일을 테스트하려면 명령문 목록 생성기와 테스터 도구를 사용하면 됩니다.

인증할 호스트 목록 확인하기

테스트할 때는 시스템이 앱에 관해 인증해야 하는 연결된 호스트 목록을 확인해야 합니다. 상응하는 인텐트 필터에 다음 속성과 요소가 포함된 모든 URL 목록을 작성하세요.

  • 값이 http 또는 httpsandroid:scheme 속성
  • 도메인 URL 패턴이 있는 android:host 속성
  • android.intent.action.VIEW 작업 요소
  • android.intent.category.BROWSABLE 카테고리 요소

이 목록을 사용하여 디지털 애셋 링크 JSON 파일이 이름이 지정된 각 호스트와 하위 도메인에 제공되는지 확인합니다.

디지털 애셋 링크 파일 확인하기

각 웹사이트에서 Digital Asset Links API를 사용하여 디지털 애셋 링크 JSON 파일이 적절히 호스팅되고 정의되었는지 확인합니다.

https://digitalassetlinks.googleapis.com/v1/statements:list?
   source.web.site=https://domain.name:optional_port&
   relation=delegate_permission/common.handle_all_urls

테스트 과정을 진행하면서 링크 처리의 현재 시스템 설정을 확인할 수 있습니다. 다음 명령어를 사용하여 연결된 기기의 모든 앱에 적용되는 기존 링크 처리 정책을 가져옵니다.

adb shell dumpsys package domain-preferred-apps

또는 다음을 통해서도 동일하게 처리할 수 있습니다.

adb shell dumpsys package d

참고: 앱이 설치된 후 시스템에서 인증 프로세스를 완료할 수 있도록 20초 이상 기다립니다.

이 명령어는 기기에서 정의된 각 사용자 또는 프로필의 목록을 반환합니다. 이 목록은 다음 형식의 헤더가 앞에 표시됩니다.

App linkages for user 0:

이 헤더 다음에는 다음과 같은 형식으로 해당 사용자의 링크 처리 설정이 나열됩니다.

Package: com.android.vending
Domains: play.google.com market.android.com
Status: always : 200000002

이 목록은 사용자별로 어느 앱이 어느 도메인과 연결되어 있는지 나타냅니다.

  • Package - 매니페스트에 선언된 패키지 이름을 기준으로 앱을 식별합니다.
  • Domains - 공백을 구분 기호로 사용하여 이 앱이 처리하는 웹 링크의 호스트 목록 전체를 보여줍니다.
  • Status - 이 앱의 현재 링크 처리 설정을 보여줍니다. 인증을 통과하고 매니페스트에 android:autoVerify="true"가 포함된 앱은 always 상태를 보여줍니다. 이 상태 뒤에 오는 16진수는 사용자 앱 링크 환경설정의 Android 시스템 레코드와 관련이 있습니다. 이 값은 인증 성공 여부는 나타내지 않습니다.

참고: 인증이 완료되기 전에 사용자가 앱의 앱 링크 설정을 변경한다면 인증이 실패해도 인증이 성공했다고 잘못 표시될 수 있습니다. 그러나 사용자가 앱에서 지원되는 링크를 사전 요청 없이 열도록 명시적으로 설정한 경우 이 인증 실패는 문제가 되지 않습니다. 이는 프로그램 인증이 있든 없든 상관없이 사용자 환경설정이 우선하기 때문입니다. 따라서 인증이 성공한 것처럼 대화상자가 표시되지 않고 링크가 직접 앱으로 연결됩니다.

테스트 예시

앱 링크 인증이 성공하려면 시스템은 앱 링크의 기준을 충족하는 지정된 인텐트 필터에서 지정한 각 웹사이트와 관련하여 앱을 인증할 수 있어야 합니다. 다음 예에서는 여러 앱 링크가 정의된 manifest 구성을 보여줍니다.

<application>

    <activity android:name=”MainActivity”>
        <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="https" />
            <data android:host="www.example.com" />
            <data android:host="mobile.example.com" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="https" />
            <data android:host="www.example2.com" />
        </intent-filter>
    </activity>

    <activity android:name=”SecondActivity”>
        <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:scheme="https" />
            <data android:host="account.example.com" />
        </intent-filter>
    </activity>

      <activity android:name=”ThirdActivity”>
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:scheme="https" />
            <data android:host="map.example.com" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="market" />
            <data android:host="example.com" />
        </intent-filter>
      </activity>

</application>

플랫폼이 위의 manifest에서 인증을 시도하는 호스트의 목록은 다음과 같습니다.

www.example.com
mobile.example.com
www.example2.com
account.example.com

플랫폼이 위의 매니페스트에서 인증을 시도하지 않는 호스트 목록:

map.example.com (it does not have android.intent.category.BROWSABLE)
market://example.com (it does not have either an "http" or "https" scheme)

명령문 목록에 대해 자세히 알아보려면 명령문 목록 만들기를 참고하세요.

일반적인 구현 오류 수정

Android App Links를 확인할 수 없는 경우 다음과 같은 일반적인 오류를 확인하세요. 이 섹션에서는 example.com을 자리표시자 도메인 이름으로 사용합니다. 이러한 검사를 실행할 때는 example.com을 서버의 실제 도메인 이름으로 대체하세요.

잘못된 인텐트 필터 설정
앱이 소유하지 않은 URL이 <intent-filter> 요소에 포함되어 있는지 확인합니다.
잘못된 서버 구성

서버의 JSON 구성을 확인하고 SHA 값이 올바른지 확인합니다.

또한 example.com. (마지막에 마침표 포함)가 example.com와 동일한 콘텐츠를 제공하는지 확인합니다.

서버 측 리디렉션

다음과 같은 리디렉션을 설정하면 시스템에서 앱의 Android App Links를 전혀 확인하지 않습니다.

  • http://example.com~https://example.com
  • example.com~www.example.com

이 동작은 앱의 보안을 보호합니다.

서버 견고성

서버가 클라이언트 앱에 연결할 수 있는지 확인합니다.

확인할 수 없는 링크

테스트 목적으로 확인할 수 없는 링크를 의도적으로 추가할 수 있습니다. Android 11 이하에서는 이러한 링크로 인해 시스템이 앱의 모든 Android App Links를 확인하지 않습니다.

assetlinks.json의 서명이 잘못됨

서명이 올바르고 앱에 서명하는 데 사용된 서명과 일치하는지 확인합니다. 일반적인 실수는 다음과 같습니다.

  • 디버그 인증서로 앱에 서명하고 assetlinks.json에 출시 서명만 있음
  • assetlinks.json에 소문자 서명이 있습니다. 서명은 대문자로 작성해야 합니다.
  • Play 앱 서명을 사용하는 경우 Google에서 각 출시 버전에 서명하는 데 사용하는 서명을 사용해야 합니다. 웹사이트 연결 선언에 관한 안내에 따라 전체 JSON 스니펫을 비롯한 이러한 세부정보를 확인할 수 있습니다.