본문 바로가기

Kotlin/안드로이드 공부

외부 앱에 공유하기 이슈 (w.안드로이드 11 패키지 공개 상태)

728x90

발생한 문제:

안드로이드 10, 11 기기에서만 공유하기 메뉴를 눌렀을 때 연결 앱이 일부만 표시된다.


안드로이드 패키지 공개 상태 

안드로이드 10 이하를 대상으로 하는 경우 모든 앱이 자동으로 앱에 표시된다.

하지만 안드로이드 11 버전부터는 앱의 패키지 공개 상태를 지정하지 않으면 외부 앱의 패키지 정보에 접근할 수 없다.

 

다음 함수 사용시 패키지 공개 상태에 따라 영향 받음

  • PackageManager.getPackageInfo()
  • PackageManager.queryIntentActivities()
  • Intent.resolveActivity()
  • PackageManager.getInstalledPakages()
  • PackageManager.getInstalledApplications()
  • bindService()

하지만 인텐트로 외부 앱에 연동하는 부분에는 영향이 없고, 외부 앱을 연동하더라도 패키지 정보를 활용하지 않는다면 문제 없음

자동으로 표시되는 패키지 : https://developer.android.com/training/package-visibility/automatic


 

매니페스트 파일에 QUERY_ALL_PACKAGES 권한을 추가하면 디바이스에 설치된 모든 패키지를 찾을 수 있다.

하지만 기기의 모든 앱을 검색하기 위한 핵심 목적이 없는 앱이라면 다가오는 22년 3월 1일부터는 사용이 제한된다.

<uses-permission  android:name="android.permission.QUERY_ALL_PACKAGES" />

 

 

 

 

따라서 특수한 앱이 아니라면 위의 방법은 더이상 사용할 수 없다.

내 앱의 동작에 의존적인 패키지가 있다면 매니페스트 파일에 <queries> 태그로 필요한 패키지, 인텐트 등을 정의해야 한다.

(화이트 리스트 방식)

<queries>
    <intent>
        <action android:name="android.intent.action.SEND" />
        <data android:mimeType="image/*" />
    </intent>
</queries>

 

 

이때 주의할 점: 안드로이드 스튜디오 버전(3.6.1 이상)과 gradle 버전을 신경써주어야 한다.

https://android-developers.googleblog.com/2020/07/preparing-your-build-for-package-visibility-in-android-11.html


테스트

버전별 세 개의 기기 (android 9, 10, 11) 를 대상으로 찾을 수 있는 패키지 개수와 실제 공유 가능한 앱 목록을 비교해보았다.

아무것도 정의하지 않았을 때 vs <queries> 정의했을 때 vs QUERY_ALL_PACKAGES 정의했을 때

 

이때 패키지 목록(개수)을 불러오는 데에는 queryIntentActivities() 함수를 사용했다.

 

  28
패키지 수
28 앱 목록 29 
패키지 수
29 앱 목록 30 
패키지 수
30 앱 목록
기존 코드 23개 지도, 행아웃 채팅, gmail, nearby, google, wifi다이렉트, always on display, 리마인더, 링크 공유, 연락처 > 나, 메시지, 삼성 클라우드, smart view, filpboard, 블루투스 66개 지도, duo, gmail, nearby, 블루투스 3개 nearby (대표), 블루투스
action.SEND (image/*) 23개 지도, 행아웃 채팅, gmail, nearby, google, wifi다이렉트, always on display, 리마인더, 링크 공유, 연락처 > 나, 메시지, 삼성 클라우드, smart view, filpboard, 블루투스 66개 지도, duo, gmail, nearby, 블루투스 26개 nearby(대표), 블루투스, 드라이브, 인쇄
QUERY_ALL_PACKAGES 23개 지도, 행아웃 채팅, gmail, nearby, google, wifi다이렉트, always on display, 리마인더, 링크 공유, 연락처 > 나, 메시지, 삼성 클라우드, smart view, filpboard, 블루투스 66개 지도, duo, gmail, nearby, 블루투스 26개 nearby(대표), 블루투스, 드라이브, 인쇄

android 9, 10 기기에서는 찾을 수 있는 패키지 갯수가 같았지만,

android 11 에서는 찾을 수 있는 패키지가 3개 -> 26개로 늘어났다.

 

결론적으로 위에서 조사한 바와 같았다.

= android 10 까지는 모든 패키지를 찾을 수 있으며, android 11 부터는 <queries> 에 정의한대로 늘어난다.

하지만 이는 queryIntentActivities() 함수에 영향이 있던 것이지 실제 외부 앱으로 공유하는 코드에는 영향을 미치지 않는다.


문제 해결 :

이슈는 안드로이드 10, 11 기기에서 공유하기 메뉴를 눌렀을 때 연결 앱이 일부만 표시되는 문제 인데

위의 테스트 내용과는 별개로 원인은 전혀 다른 곳에 있었다.

 

기존 코드에서는 EXTRA_INITIAL_INTENTS 를 사용하여 인텐트에 연결할 앱 리스트를 담아주는 방식을 사용하였다.

하지만 android 10 의 ChooserActivity 에서는 EXTRA_INITIAL_INTENTS 의 최대 개수가 2로 제한이 생겼으며

따라서 실제로 전달한 건수보다 실제 앱 리스트에는 적은 갯수가 표시되는 것이었다.

private static final int MAX_EXTRA_INITIAL_INTENTS = 2;

 

 

관련 이슈 트래커: https://issuetracker.google.com/issues/134367295

 


 

android 10 이전까지는 공유 화면에 보여줄 타이틀을 정하고 앱 리스트에 표시할 항목과 순서를 정하는 등 커스터마이징이 가능했으나, 

android 10 부터는 표준 Intent.ACTION_SEND, ACTION_SEND_MULTIPLE 를 사용하기를 권장하며 이러한 커스터마이징에 제한이 생길 것으로 보인다.

 

기존 코드에는 패키지 이름을 비교하여 본인 앱은 EXTRA_INITIAL_INTENTS 로 전달하는 리스트에서 제외시키고 앱 리스트에 표시되지 않도록 해주는 처리가 있었는데 (화이트 리스트 방식)

만약 이 동작을 android 10 버전 이상에서 그대로 유지하고 싶다면 EXTRA_EXCLUDE_COMPONENT 에 본인 패키지명을 전달하는 방식으로 바꿔야 할 것 같다. (블랙 리스트 방식. 단, api 24(android N) 이상에서 가능)

 


결론과 남은 궁금증:

Q1. 분기처리 없이 표준 ACTION_SEND  방식을 모든 버전에 적용해주면 안되는지

자기 자신의 앱 패키지를 반드시 앱 리스트에서 제외시켜야 할까?

이상한 것 같기도 아닌 것 같기도.. (snow 앱은 본인 앱으로 공유 가능한 것 확인)

 

결론 : 모든 버전에 ACTION_SEND 방식을 적용해도 되지만

자신의 앱은 보여주지 않기 위해서 분기처리하고 EXTRA_EXCLUDE_COMPONENT 적용함!

 

ComponentName[] componentNameArray = new ComponentName[]{new ComponentName(context, Activity.class)};

chooserIntent.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, componentNameArray);

 

Q2. 왜 딱 2개의 앱만 표시되지 않고 그 이상 표시되는지?

4개 이상 보이지 않는다는 의견이 있음

https://issuetracker.google.com/issues/136027280?pli=1 

 

 

Q3. 왜 안드로이드 m 에서 한번 더 분기해주는 예시가 많은지

  // deal with M list seperate problem
  // create chooser with empty intent in M could fix the empty cells problem

 

ex ) https://stackoverflow.com/questions/38345994/how-to-exclude-a-specific-application-from-action-send-intent

https://stackoverflow.com/questions/57846229/for-the-intent-chooser-is-it-possible-to-set-which-sharing-items-to-show-and-i

 

 

더보기