앱 링크의 인텐트 필터 추가

앱 링크는 HTTP 또는 HTTPS 스키마를 사용하고 Android에서 웹사이트와 연결된 것으로 확인되는 딥 링크입니다. 앱 링크를 처리하도록 등록하려면 다음 단계를 따르세요.

  1. 웹사이트 도메인 또는 URL을 지정하는 인텐트 필터를 하나 이상 앱 매니페스트에 추가합니다.
  2. 인텐트 필터 요소에 autoVerify="true"attribute를 추가합니다. 이렇게 하면 시스템에서 웹사이트의 assetlinks.json 구성에 대해 스키마 및 호스트 도메인을 확인하도록 시도해야 함을 알립니다.
  3. 웹사이트 연결을 선언합니다.

다음은 스키마 및 호스트와 autoVerify="true"가 포함된 앱 링크 선언의 예입니다.

<activity
    android:name=".MainActivity"
    android:exported="true"
    ...>
    <!-- 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 link that uses the "http" scheme, your
             app should be able to delegate that traffic to "https". -->
        <!-- Do not include other schemes, as this will prevent verification. -->
        <data android:scheme="http" />
        <data android:scheme="https" />

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

코드 관련 핵심 사항

  • AutoVerify: android:autoVerify="true" 속성은 앱 링크에 필요합니다. 이 속성은 시스템에서 앱과 <data> 태그에 지정된 스키마 및 도메인 간의 연결을 확인하도록 시도해야 함을 알립니다. 확인 가능한 모든 인텐트 필터에 autoVerify="true"를 추가하는 것이 좋습니다.
  • 데이터 요소: 각 앱 링크 인텐트 필터에는 확인 가능한 웹사이트 도메인과 일치하는 스키마 및 호스트 형식을 지정하는 <data> 요소가 하나 이상 포함되어야 합니다.
  • 스키마: 인텐트 필터에는 <data> 스키마 모두에 httphttps 요소가 포함되어야 합니다.
  • 호스트: 필요에 따라 <data> 요소를 추가하여 하나 이상의 호스트와 일치시킬 수 있습니다. 와일드 카드 (*)를 사용하여 여러 하위 도메인 (예: *.example.com)과 일치시킵니다. 시스템은 웹사이트의 assetlinks.json 파일에 대해 각 호스트를 확인하려고 시도합니다. 경로 수준 라우팅은 assetlinks.json 파일에서 처리해야 합니다 (아래의 권장사항 섹션 참고).

  • 여러 호스트: 여러 호스트 도메인을 선언하면 시스템 (Android 12 이상)에서 각 도메인을 확인하려고 시도합니다. 호스트가 확인되면 앱이 확인된 호스트의 링크에 대한 기본 핸들러가 됩니다. Android 11 이하에서는 호스트를 하나라도 확인할 수 없으면 확인이 실패합니다.

  • 여러 인텐트 필터: 고유한 URL (예: 스키마와 호스트의 특정 조합)을 선언하려는 경우 별도의 필터를 만드는 것이 중요합니다. 동일한 인텐트 필터의 여러 <data> 요소가 함께 병합되어 결합된 속성의 모든 변형을 나타내기 때문입니다.

매니페스트 필터 규칙 고려사항

Android 15 이상에서 동적 앱 링크와 함께 사용할 필터를 설정하는 경우 서버 측 assetlinks.json 파일에 선언된 동적 규칙이 앱 매니페스트에서 정적으로 선언하는 URL 규칙의 범위를 확장할 수 없다는 점을 기억하는 것이 중요합니다.

따라서 이 접근 방식을 사용하는 것이 좋습니다.

  • 앱 매니페스트에서 스키마와 도메인만 선언하는 등 가능한 가장 광범위한 범위를 설정합니다.
  • 경로 수준 라우팅과 같은 추가 구체화를 위해 서버 측 assetlinks.json 규칙을 사용합니다.

이 이상적인 구성을 사용하면 앱 매니페스트에서 설정한 광범위한 범위 내에 들어갈 것이라는 점을 알고 필요에 따라 assetlinks.json 파일에 새 앱 링크 경로를 동적으로 추가할 수 있습니다.

여러 호스트의 앱 링크 지원

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

예를 들어 다음 인텐트 필터가 포함된 앱은 assetlinks.json 파일이 https://www.example.com/.well-known/assetlinks.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>

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

디지털 애셋 링크 프로토콜은 인텐트 필터에 있는 하위 도메인을 별도의 고유 호스트로 취급합니다. 따라서 인텐트 필터에 서로 다른 하위 도메인을 가진 여러 호스트가 나열된 경우에는 각 도메인별로 유효한 assetlinks.json을 게시해야 합니다. 예를 들어 다음 인텐트 필터는 허용되는 인텐트 URL 호스트로 www.example.commobile.example.com을 포함합니다. 따라서 유효한 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)에 assetlinks.json 파일을 게시해야 합니다. 예를 들어, 다음 인텐트 필터가 있는 앱은 assetlinks.json 파일이 https://example.com/.well-known/assetlinks.json에 게시되는 한 example.com의 하위 이름 (예: foo.example.com)과 관련된 인증을 통과합니다.*.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 사용자는 대화상자에 표시되는 일치하는 앱 목록에서 선호하는 앱을 선택할 수 있습니다.

assetlinks.json의 고급 일치 규칙 및 <uri-relative-filter-group> 사용을 비롯한 동적 앱 링크 기능은 Android 15 (API 수준 35) 이상에서만 완전히 지원됩니다.

Android 14 (API 수준 34) 이하에서는 시스템에서 앱 링크 확인을 위해 매니페스트의 <data> 요소에 선언된 schemehost만 고려합니다. assetlinks.json의 경로별 규칙, 제외, 동적 업데이트는 적용되지 않습니다.

즉, 매니페스트에서 schemehost만 지정하는 경우 Android 15 이상용 assetlinks.json에 정의된 경로별 규칙과 관계없이 Android 14 이하에서 확인된 도메인의 모든 경로를 앱이 예기치 않게 캡처할 수 있습니다.

Android 15 이상에서 더 구체적인 경로에 동적 앱 링크를 사용하려는 경우 Android 14 이하에서 앱이 도메인의 모든 링크를 처리하지 못하도록 하려면 매니페스트의 인텐트 필터에 일치하지 않는 경로를 포함하세요. 링크의 유효한 경로가 될 가능성이 없는 android:path 속성이 있는 <data> 요소를 추가합니다. 이렇게 하면 인텐트 필터가 하위 버전의 모든 경로와 일치하지 않습니다.

예:

<activity
    android:name=".MainActivity"
    android:exported="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" />

        <data android:scheme="http" />
        <data android:scheme="https" />
        <data android:host="www.example.com" />

        <!-- Add a non-matching path for backward compatibility -->
        <data android:path="/no_match_for_older_android_versions" />

        <uri-relative-filter-group android:allow="true">
          <data android:pathPattern="/.*"/>
        </uri-relative-filter-group>
    </intent-filter>
</activity>

<data android:path="/no_match_for_older_android_versions" />를 추가하면 Android 14 이하에서 이 인텐트 필터가 수신 링크와 일치하지 않지만 assetlinks.json 규칙의 고급 일치 규칙에 따라 Android 15 이상에서 동적 앱 링크와 함께 사용할 도메인을 계속 확인할 수 있습니다.

매니페스트에 특정 경로 규칙 (예: android:pathPrefix)이 있는 앱 링크가 이미 있고 Android 15 이상에서 동적 앱 링크 를 사용하기 시작하려면 <uri-relative-filter-group> 요소를 기존 인텐트 필터에 직접 안전하게 추가할 수 있습니다.

Android 14 이하에서는 <uri-relative-filter-group> 요소를 무시하므로 기존 앱 링크는 하위 버전의 Android를 실행하는 기기에서 지금과 동일하게 계속 작동합니다.

그러나 Android 15 이상에서 '혼합' 구성을 평가하는 방법을 신중하게 고려해야 합니다.

  • 2단계 필터링: Android 15 이상에서는 시스템에서 인텐트 필터를 결합으로 평가합니다. URL은 기존 정적 <data> 태그 또는 <uri-relative-filter-group>의 광범위한 규칙을 충족하는 경우 매니페스트 검사를 통과합니다. URL이 이 초기 매니페스트 검사를 통과하면 시스템은 assetlinks.json 파일에 정의된 동적 규칙을 세부 필터링의 두 번째 레이어로 적용합니다. 즉, 서버 측 JSON 규칙은 일치하는 URL 중 실제로 앱을 여는 URL을 최종적으로 결정합니다.

하이브리드 구성의 예:

<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="www.example.com" />

    <!-- Legacy rule: Android 14 and lower use this. Android 15 and higher
         also use this. -->
    <data android:pathPrefix="/store" />

    <!--
      Dynamic rule: Android 14 and lower ignore this. Android 15 and higher
      evaluate this as a union between all paths and the configuration
      specified in the assetlinks.json file. Make sure to apply further
      refinements in the assetlinks.json file to prevent all URL paths from
      opening in the app.
    -->
    <uri-relative-filter-group android:allow="true">
        <data android:pathPrefix="/" />
    </uri-relative-filter-group>
</intent-filter>