올해 초 새로 출시한 안드로이드 앱에 결제 모듈을 연동한 결제기능이 있다.
그런데 메일이 한통 왔는데
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