발단

 

Google PlayStore 의 최근 요구 사항에 따라 ( https://developer.android.com/distribute/best-practices/develop/target-sdk?hl=ko ) 최근 App targetSdkVersion 을 30으로 올리는 작업을 진행했습니다.

 

2021년 8월부터 신규 앱은 다음 요건을 충족해야 합니다.
...
 * API 수준 30(Android 11) 이상을 타겟팅하고 동작 변경사항에 맞게 조정합니다.
...

 

진행하다 보니, 평소에 잘 동작하던 queryIntentActivities 가 제대로 동작하지 않았습니다.

 

 

개요

 

PackageManager.queryIntentActivities 는 보통 암시적 Intent ,(이를 테면, URL 을 가지고 Web Browser 로 넘기기전에 적당한 Intent ), 를 실행하는 App 을 선택하기 위해, 주로 사용하는 API 였습니다.

 

안드로이드 예전 버전에서 startActivity 를 실행했을 때, 생길 수 있는 선택창을 없애기 위한 방법 중 하나였습니다.

이를  테면, 브라우저 앱이 크롬, 파이어폭스, 제조사 브라우저 등 여러개 설치되어 있다고 할 때,

URL - ACTION_VIEW Intent 로 startActivity 를 실행하기 전, 선택가능한 Activity 중 하나를 코드상에서 선택하게 함으로,

사용자에게 어떤 브라우저를 사용할 것인지 확인을 받는 동선을 없애버려서, 좀 더 편하게 사용하게 하려는 의도이기도 합니다.

 

혹은 startActivity 를 사용할 때, ActivityNotFoundException 을 회피하기 위해 사용하기도 했습니다.

아래 코드 처럼 try-catch 로 처리하거나, Intent.resolveActivity 를 사용하는 방법도 있긴하지만,

queryIntentActivities() 결과 값 크기로 구분하기도 했습니다.

 

    try {
        startActivity(intent)
    } catch (e: ActivityNotFoundException) {

    }

 

이 API 를 잘 이용해서, action = MAIN, category = LAUNCHER 로 인텐트 필터로 사용하면, 앱 관리자 같은 앱을 만들 수도 있습니다.

 

 

좀 더 깊숙히

 

하지만, targetSdkVersion = 30 부터는 이런 동작이 쉽지 않게 되었습니다.

예를 들어, 아래와 같이 jpeg image 를 보내는 intent 를 만들었다고 가정하면,...

 

fun Context.queryIntentActivitiesTest() {
    val jpegIntent = Intent(Intent.ACTION_SEND).apply {
        this.setDataAndType(Uri.parse("file://a"), "image/jpeg")
    }
    val query = this.packageManager.queryIntentActivities(jpegIntent, 0)
    val system = query.filter { it.activityInfo.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM != 0 }
    val other = query.filter { it.activityInfo.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM == 0 }
    Log.d("Test", "jpegIntent queryIntentActivities = total, SYSTEM, NON-SYSTEM " +
            "${query.size}, ${system.size}, ${other.size}"
    )
}

 

이 결과는 아래 표와 같이 나옵니다.

  Total System Other
targetSdkVersion = 29 42 14 28
targetSdkVersion = 30 15 7 8

 

즉, targetSdkVersion 을 변경한 것으로 queryIntentActivities 로 반환된 결과 값의 차이가 생기고,

이는 실행할 수 있는 Activity 의 갯수가 줄어든다는 것입니다.

 

물론, 단순히 startActivity 만 사용하는 코드에서는 전혀 문제가 없지만, 위에서 언급했던 것처럼, 특정 App 이 직접 실행되도록 하는 코드를 작성할 경우에는 targetSdkVersion 만 변경한 것으로도 이전과 다른 동작을 하게 될 수가 있습니다.

 

구글이 targetSdkVersion = 30 에서 이런 제한을 둔 것은 보안상의 이유라고 보여집니다.

위에서도  언급했지만, queryIntentActivities() 를 잘 이용하면, <앱 관리자> 유형의 앱을 개발할 수 있습니다.

즉, 이 API 를 이용하면, 사용자 단말에 설치되어 있는 앱 목록을 알 수 있다는 것이고, 이를 다른 용도로 앱이 이용할 가능성이 있기 때문에, API 이용에 제한을 두기 시작했다는 것으로 볼 수 있습니다.

 

 

해결방법

 

만약, targetSdkVersion = 29 일 때와 동일하게 동작하게 하려면,

아래와 같이 AndroidManifest.xml 파일에 아래와 같이 <queries></queries> 를 추가해주어야 합니다.

 

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

 

혹은 아래와 같은 permission 을 추가해 주어야 합니다. 하지만, 이 방법은 권장?, 추천?하지 않습니다.

 

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

 

왜냐하면, <앱관리자> 같은 특정한 성격의 앱이 아니고서는 플레이스토어 심사를 통과하지 못 할 가능성이 높기 때문입니다.

( https://support.google.com/googleplay/android-developer/answer/10158779?hl=ko  )

 

위 문서에는 아래와 같이 언급되어 있습니다.

 

앱이 QUERY_ALL_PACKAGES 권한의 허용되는 용도에 관한 요구사항을 충족할 경우, Play Console의 권한 선언 양식을 사용해 이 권한 및 위험성이 높은 기타 모든 권한을 선언해야 합니다.

정책 요구사항을 충족하지 못하거나 권한 선언 양식을 제출하지 않으면 앱이 Google Play에서 삭제될 수 있습니다.

중요: 앱에서 제한된 권한을 사용하는 방식을 변경하려면 정확하게 업데이트된 정보로 요청을 수정해야 합니다. 이러한 권한을 사기성 및 선언되지 않은 용도로 사용하면 앱이 정지되거나 개발자 계정이 해지될 수 있습니다.

 

 

참고한 문서

 

1. Google Play의 타겟 API 수준 요구사항 충족하기

  -  https://developer.android.com/distribute/best-practices/develop/target-sdk?hl=ko

2. 패키지 공개 상태 관리

  -   https://developer.android.com/training/basics/intents/package-visibility

3. 폭넓은 패키지(앱) 가시성 (QUERY_ALL_PACKAGES) 권한 사용

  -   https://support.google.com/googleplay/android-developer/answer/10158779?hl=ko 

 

#Android,#PackageManager,#targetSdkVersion=30,#queryIntentActivities

'Android' 카테고리의 다른 글

Firebase Authentication ‘Code:10, message:10’ 에러 해결  (0) 2023.04.04
Gson - Android Proguard 문제  (0) 2020.11.12
Android Studio - Database Inspector  (0) 2020.11.04
Android AlertDialog Style 변경  (0) 2020.08.05
Android Custom Lint  (0) 2020.07.28