Android

안드로이드11 패키지 가시성제한 대응

반응형

올해 초 새로 출시한 안드로이드 앱에 결제 모듈을 연동한 결제기능이 있다.

 

그런데 메일이 한통 왔는데

 

1.     배경 

1)     안드로이드 11 보안 정책 변경 (11 1 )

2)     안드로이드 11 이전 버전 OS에서는 App PackageManager에서 제공하는 메소드 (queryIntentActivities(), getInstalledApplications(), getInstalledApplications(), resolveActivity() ) 

사용하여 시스템에 설치된 App 확인할 있었음 

3)     안드로이드 11 (API 30) 버전부터 패키지 가시성 제한으로 조회할 없게 되어, 

결제창 등에서 사용하는 외부 App (앱카드, 백신, 삼성페이, 페이코 ) 호출 패키지 정보로 App 설치 여부를 확인하고 있을 경우 문제가 발생할 있음 

 

2.     정책 변경 내용

1)     적용 OS : Android

2)     방안 

ν  1) 자체 App <queries>요소에 패키지 정의

ν  2) 재정의한 shouldOverrideUrlLoading() 메소드에서 startActivity() 호출 App 미설치로 발생하는 

ActivityNotFoundException (No Activity found to handle Intent)에 예외처리 로직 추가

ν  11 1일부터 설정 필수 

 

 

*요약

1. 11월 1일부로 안드로이드 11 정책 변경

2. 앞으로 QUERY_ALL_PACKAGES 권한을 사용하지 못함.

3. QUERY_ALL_PACKAGES 대신 <queries>를  추가하여 패키지를 설정해놓아야함.

 

현재 웹뷰에서

결제모듈로 넘어가서 카드를 선택하여 넘어오는 Url을 파싱해서 

			/**
             * 결제 모듈 URL 관리
             */
                if (url.startsWith("intent")) { // chrome 버젼 방식 // 앱설치 체크를 합니다.
                    if (getPackageManager().resolveActivity(intent, 0) == null) {
                        String packagename = intent.getPackage();
                        if (packagename != null) {
                            Uri uri = Uri.parse("market://details?id=" + packagename); // 마켓으로 바로 이동
                            intent = new Intent(Intent.ACTION_VIEW, uri);
                            startActivity(intent);
                            return true;
                        }
                    } else { // 앱이 설치되어 있으면
                        int runType = Integer.parseInt(android.os.Build.VERSION.SDK);
                        if (runType <= 18) {
                            Uri uri = Uri.parse(intent.getDataString());
                            intent = new Intent(Intent.ACTION_VIEW, uri);
                            startActivity(intent);
                        } else {
                            intent.addCategory(Intent.CATEGORY_BROWSABLE);
                            intent.setComponent(null);
                            try {
                                if (startActivityIfNeeded(intent, -1)) {
                                    return true;
                                }
                            } catch (ActivityNotFoundException ex) {
                                return false;
                            }
                        }

                    }
                } else { // 구 방식
                    Uri uri = Uri.parse(url);
                    intent = new Intent(Intent.ACTION_VIEW, uri);
                    startActivity(intent);
                }

 

이처럼 설치되어 있으면 startActivity(), 아니라면 마켓으로 이동시키곤 했는데

getPackageManager().resolveActivity(intent, 0)

부분에서 구방식대로라면 보안 정책 변경이후에 문제가 될 것 같다.

그래서 AndroidManifest에

 

    <queries>
        <package android:name="kvp.jjy.MispAndroid320"/>
        <package android:name="com.wooricard.smartapp"/>
        <package android:name="com.hanaskcard.paycla"/>
        ......
        
	</queires>

 

이렇게 추가해주고 

 

<!--    <uses-permission-->
<!--        android:name="android.permission.QUERY_ALL_PACKAGES"-->
<!--        tools:ignore="QueryAllPackagesPermission" />-->

 

위 코드는 일단 주석처리를....

 

참고

 

- https://support.google.com/googleplay/android-developer/answer/10446026?hl=ko
- https://developer.android.com/about/versions/11/privacy/package-visibility?hl=ko
- https://developer.android.com/training/basics/intents/package-visibility?hl=ko#package-name
- https://developer.android.com/training/package-visibility/use-cases?hl=ko

 

반응형