안드로이드 11의 "패키지 공개 상태" 변경 사항 정리

Image not Found

안드로이드 11의 출시가 얼마 남지 않았습니다. 공식 문서에 따르면 2020년 3분기 안에 출시가 될 에정이니, 1~2달 안에 정식 버전이 출시될 것 같습니다. 지금까지의 메이저 버전 업데이트가 항상 그랬듯, 이번 안드로이드 11에서도 중요한 변경사항이 많고 이에 기존 앱들은 큰 영향을 받을 수 있습니다. 그중에서도 “패키지 공개 상태"에 대한 변경은 버즈빌 안드로이드 제품에도 많은 영향을 주는 부분이이서, 이에 대해 조사하며 실제로 테스트해본 결과를 공유하고자 합니다.

“패키지 공개 상태” 변경사항

targetSdkVersion이 안드로이드 11 이상인 앱에서는 디바이스에 설치된 다른 앱 목록을 알 수 없고, 미리 매니페스트 파일에 지정한 앱의 정보만 가져올 수 있습니다. 쿼리 하고 싶은 앱을 지정하려면 AndroidManifest.xml<queries> 요소를 추가해서 쿼리할 패키지 이름 또는 인텐트 필터 서명을 포함해야 합니다.

패키지 이름 지정 방법

<manifest package="com.example.game">
    <queries>
        <package android:name="com.example.store" />
        <package android:name="com.example.services" />
    </queries>
    ...
</manifest>

인텐트 필터 지정 방법

<manifest package="com.example.game">
    <queries>
        <intent>
            <action android:name="android.intent.action.SEND" />
            <data android:mimeType="image/jpeg" />
        </intent>
    </queries>
    ...
</manifest>

예외적으로 몇몇 사용 사례(런처, 접근성, 브라우저, 보안 앱 등)에서는 기기에 설치된 모든 앱을 쿼리하거나 상호작용해야 할 수 있습니다. 이를 위해 안드로이드 11에는 QUERY_ALL_PACKAGES 권한이 도입되었습니다.

공식 문서에서는 QUERY_ALL_PACKAGES 권한에 대해 Google Play에서의 관련 가이드라인을 제공할 예정이라고 설명하고 있습니다. 구글에서는 대부분의 상황에서 <queries> 요소를 통해 앱이 작동하는 데 필요한 패키지 공개 상태를 최소한으로 요청하여 앱의 기존 동작을 유지할 수 있다고 보고 있는 것 같아, 아마 위에 언급한 예외적인 사용 사례를 제외하면 이 권한의 사용을 어떤 방식으로든 제한할 것으로 보입니다.

더 자세한 내용은 안드로이드 개발자 페이지의 공식 문서를 읽어보시기를 추천해 드립니다.

영향받는 API

공식 가이드 문서에는 예시로 든 API는 PackageManager.queryIntentActivities() 뿐이지만, 구글 안드로이드 11 밋업에서는 “패키지 공개 상태” 변경에 영향을 받는 다른 API도 소개하고 있습니다.

  • PackageManager.getPackageInfo("com.another.app", 0)
    • 앱 설치 여부와 상관없이 NameNotFoundException 예외 발생
  • PackageManager.getInstalledPackage(0)
    • 자기 자신과 적은 수의 시스템 필수 패키지 목록만 반환
  • PackageManager.queryIntentActivities(intent, 0)
    • 자기 자신과 적은 수의 시스템 필수 패키지 목록만 반환
  • 명시적 intent를 통한 방법
    • 예외 발생

동작 테스트

변경에 영향을 받을 것으로 예상되는 API를 실제로 테스트해보기 위해 샘플 앱을 생성해 안드로이드 11 가상 디바이스에서 돌려보았습니다. Android 11 Beta 2.5 이미지를 사용했고, 샘플 앱의 코드는 여기서 확인할 수 있습니다. 테스트 대상 API는 위의 구글 밋업에서 소개된 API 4개, 그리고 추가로 이와 비슷한 역할을 API 2개를 선정했습니다.

1. PackageManager.getPackageInfo()

  • <queries> 요소를 지정하지 않으면, NameNotFoundException이 발생합니다.
  • 매니페스트 파일이 아래와 같으면, “com.android.chrome"을 인자로 호출한 API가 정상적으로 동작합니다.
    <manifest package="...">
      <queries>
          <package android:name="com.android.chrome" />
      <queries>
      ...
    </manifest>
    

2. PackageManager.queryIntentActivities(intent, 0)

아래의 샘플 코드로 테스트한 결과입니다.

Intent(Intent.ACTION_VIEW, Uri.parse("https://www.google.com")).let { intent ->
    val list = packageManager.queryIntentActivities(intent, 0)
}
  • <queries> 요소를 지정하지 않으면 빈 리스트가 반환됩니다.
  • 매니페스트 파일에 1번 예제처럼 “com.android.chrome"를 명시적으로 지정하면, 해당 패키지만 반환됩니다.
  • 매니페스트 파일에 아래와 같이 인텐트 필터를 사용하면, 설치된 모든 브라우저 앱이 반환됩니다.
    <manifest package="...">
      <queries>
          <intent>
              <action android:name="android.intent.action.VIEW" />
              <category android:name="android.intent.category.BROWSABLE" />
              <data android:scheme="https" />
          </intent>
      <queries>
      ...
    </manifest>
    

3. Intent.resolveActivity(packageManager)

2번 예제의 intent 그대로 테스트를 진행한 결과입니다.

  • <queries> 요소를 지정하지 않으면 null이 반환됩니다.
  • 매니페스트 파일에 1번 예제처럼 “com.android.chrome"를 명시적으로 지정하면, 해당 패키지가 반환됩니다.
  • 매니페스트 파일에 2번 예제와 같은 인텐트 필터를 지정하면, 실제 설치된 브라우저 중 가장 적합한 패키지가 반환됩니다.

4. PackageManager.getInstalledPackages(0)

  • <queries> 요소를 지정하지 않으면 자기 자신과 몇몇 시스템 필수 패키지만 반환됩니다.
  • <queries> 요소에 특정 패키지 혹은 인텐트 필터를 지정하면, 해당하는 패키지도 추가로 반환됩니다.

5. PackageManager.getInstalledApplications(0)

  • <queries> 요소를 지정하지 않으면 자기 자신과 몇몇 시스템 필수 패키지만 반환됩니다.
  • <queries> 요소에 특정 패키지 혹은 인텐트 필터를 지정하면, 해당하는 패키지도 추가로 반환됩니다.

6. 명시적 Intent를 이용한 Context.startActivity(intent)

아래의 샘플 코드로 테스트한 결과입니다.

Intent(Intent.ACTION_VIEW, Uri.parse("https://www.google.com")).let { i ->
    i.flags = Intent.FLAG_ACTIVITY_NEW_TASK
    i.setPackage("com.android.chrome")
    context.startActivity(i)
}
  • <queries> 요소를 지정하지 않으면 ActivityNotFoundException이 발생합니다.
  • 매니페스트 파일에 1번 예제처럼 “com.android.chrome"를 명시적으로 지정하면, 크롬 앱이 정상적으로 실행됩니다.
  • 매니페스트 파일에 2번 예제처럼 인텐트 필터를 지정해도 크롬 앱이 정상적으로 실행됩니다.

마치며

지금까지 안드로이드 11의 변경사항 중 “패키지 공개 상태"에 대해 자세히 알아보았습니다. 안드로이드 11의 출시가 얼마 남지 않은 만큼, 다른 앱 개발자 여러분들도 자신의 앱을 테스트해보시고 빠르게 변경사항에 대한 호환성을 확보하시기 바랍니다.

You May Also Like

post-thumb

안드로이드 개발자의 서버 개발기

안녕하세요. 곽서현입니다. 저는 버즈빌에서 안드로이드 개발자로 일하고 있습니다. 이번 글에서는 제가 서버 개발을 시작하면서 겪었던 시행착오와 제가 서버 개발에 적용할 수 있도록 해준 버즈빌의 가이드에 대한 소개를 해보려고 합니다. 주니어 개발자를 온보딩 시키거나 타직군 …

Read Article
post-thumb

VS Code로 컨테이너 안에서 개발하기

컨테이너 환경은 날이 갈 수록 더 많은 사람에게 사랑 받고 있죠. 처음부터 Docker, Kubernetes 등을 활용해 컨테이너 기반의 배포를 사용하기 시작한 사람들은 capistrano나 fabric 같은 도구를 사용한 배포 환경에서 나타날 수 있는 정말 다양하고 …

Read Article