Android 11에서는 앱이 사용자가 기기에 설치한 다른 앱과 상호작용하는 방식이 변경되었습니다. Android 문서에서 이러한 변경사항에 대해 자세히 알아볼 수 있습니다.
맞춤 탭을 사용하는 Android 앱이 SDK 수준 30 이상을 타겟팅하는 경우 몇 가지 변경사항이 필요할 수 있습니다. 이 도움말에서는 이러한 앱에 필요할 수 있는 변경사항을 설명합니다.
가장 간단한 경우 맞춤 탭은 다음과 같은 한 줄로 실행할 수 있습니다.
new CustomTabsIntent.Builder().build()
.launchUrl(this, Uri.parse("https://www.example.com"));
이 접근 방식을 사용하여 애플리케이션을 실행하거나 툴바 색상 변경, 작업 버튼 추가와 같은 UI 맞춤설정을 추가하는 애플리케이션은 애플리케이션을 변경할 필요가 없습니다.
네이티브 앱 선호
하지만 권장사항을 따랐다면 일부 변경이 필요할 수 있습니다.
첫 번째 관련 권장사항은 인텐트를 처리할 수 있는 앱이 설치된 경우 애플리케이션이 맞춤 탭 대신 네이티브 앱을 사용하여 인텐트를 처리해야 한다는 것입니다.
Android 11 이상
Android 11에서는 앱이 패키지 관리자 쿼리를 선언할 필요가 없으므로 네이티브 앱을 여는 데 권장되는 방법인 새로운 인텐트 플래그 FLAG_ACTIVITY_REQUIRE_NON_BROWSER
를 도입합니다.
static boolean launchNativeApi30(Context context, Uri uri) {
Intent nativeAppIntent = new Intent(Intent.ACTION_VIEW, uri)
.addCategory(Intent.CATEGORY_BROWSABLE)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_REQUIRE_NON_BROWSER);
try {
context.startActivity(nativeAppIntent);
return true;
} catch (ActivityNotFoundException ex) {
return false;
}
}
해결 방법은 인텐트를 실행하고 FLAG_ACTIVITY_REQUIRE_NON_BROWSER
를 사용하여 실행 시 Android에 브라우저를 피하도록 요청하는 것입니다.
이 인텐트를 처리할 수 있는 네이티브 앱을 찾을 수 없는 경우 ActivityNotFoundException
이 발생합니다.
Android 11 이전
애플리케이션이 Android 11 또는 API 수준 30을 타겟팅하더라도 이전 Android 버전은 FLAG_ACTIVITY_REQUIRE_NON_BROWSER
플래그를 이해하지 못하므로 이러한 경우 패키지 관리자를 쿼리해야 합니다.
private static boolean launchNativeBeforeApi30(Context context, Uri uri) {
PackageManager pm = context.getPackageManager();
// Get all Apps that resolve a generic url
Intent browserActivityIntent = new Intent()
.setAction(Intent.ACTION_VIEW)
.addCategory(Intent.CATEGORY_BROWSABLE)
.setData(Uri.fromParts("http", "", null));
Set<String> genericResolvedList = extractPackageNames(
pm.queryIntentActivities(browserActivityIntent, 0));
// Get all apps that resolve the specific Url
Intent specializedActivityIntent = new Intent(Intent.ACTION_VIEW, uri)
.addCategory(Intent.CATEGORY_BROWSABLE);
Set<String> resolvedSpecializedList = extractPackageNames(
pm.queryIntentActivities(specializedActivityIntent, 0));
// Keep only the Urls that resolve the specific, but not the generic
// urls.
resolvedSpecializedList.removeAll(genericResolvedList);
// If the list is empty, no native app handlers were found.
if (resolvedSpecializedList.isEmpty()) {
return false;
}
// We found native handlers. Launch the Intent.
specializedActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(specializedActivityIntent);
return true;
}
여기서 사용되는 접근 방식은 패키지 관리자에서 일반 http
인텐트를 지원하는 애플리케이션을 쿼리하는 것입니다. 이러한 애플리케이션은 브라우저일 가능성이 높습니다.
그런 다음 실행하려는 특정 URL의 항목을 처리하는 애플리케이션을 쿼리합니다. 그러면 해당 URL을 처리하도록 설정된 브라우저와 네이티브 애플리케이션이 모두 반환됩니다.
이제 첫 번째 목록에 있는 모든 브라우저를 두 번째 목록에서 삭제하면 네이티브 앱만 남게 됩니다.
목록이 비어 있으면 네이티브 핸들러가 없음을 알 수 있으므로 false를 반환합니다. 그 외의 경우에는 네이티브 핸들러의 인텐트를 실행합니다.
요약 정리
상황에 따라 적절한 방법을 사용해야 합니다.
static void launchUri(Context context, Uri uri) {
boolean launched = Build.VERSION.SDK_INT >= 30 ?
launchNativeApi30(context, uri) :
launchNativeBeforeApi30(context, uri);
if (!launched) {
new CustomTabsIntent.Builder()
.build()
.launchUrl(context, uri);
}
}
Build.VERSION.SDK_INT
는 Google에 필요한 정보를 제공합니다. 30 이상이면 Android가 FLAG_ACTIVITY_REQUIRE_NON_BROWSER
를 알고 있으므로 새 접근 방식으로 네이티브 앱을 실행해 볼 수 있습니다. 그렇지 않으면 이전 접근 방식으로 실행을 시도합니다.
네이티브 앱 실행에 실패하면 맞춤 탭이 실행됩니다.
이 권장사항에는 몇 가지 템플릿이 포함되어 있습니다. Google은 라이브러리에서 복잡성을 캡슐화하여 이를 간소화하기 위해 노력하고 있습니다. android-browser-helper 지원 라이브러리의 업데이트를 기대해 주세요.
맞춤 탭을 지원하는 브라우저 감지
또 다른 일반적인 패턴은 PackageManager를 사용하여 기기에서 맞춤 탭을 지원하는 브라우저를 감지하는 것입니다. 앱 이름 해석 대화상자를 방지하기 위해 인텐트에 패키지를 설정하거나 맞춤 탭 서비스에 연결할 때 연결할 브라우저를 선택하는 것이 일반적인 사용 사례입니다.
API 수준 30을 타겟팅하는 경우 개발자는 Android 매니페스트에 쿼리 섹션을 추가하여 맞춤 탭 지원 브라우저와 일치하는 인텐트 필터를 선언해야 합니다.
<queries>
<intent>
<action android:name=
"android.support.customtabs.action.CustomTabsService" />
</intent>
</queries>
마크업을 적용하면 맞춤 탭을 지원하는 브라우저를 쿼리하는 데 사용되는 기존 코드가 예상대로 작동합니다.
자주 묻는 질문(FAQ)
Q: 맞춤 탭을 찾는 코드가 https://
인텐트를 처리할 수 있는 애플리케이션을 쿼리하지만 쿼리 필터는 android.support.customtabs.action.CustomTabsService
쿼리만 선언합니다. https://
인텐트에 관한 쿼리를 선언해야 하지 않나요?
A: 쿼리 필터를 선언하면 쿼리 자체가 아닌 PackageManager에 대한 쿼리에 대한 응답이 필터링됩니다. 맞춤 탭을 지원하는 브라우저는 CustomTabsService 처리를 선언하므로 필터링되지 않습니다. 맞춤 탭을 지원하지 않는 브라우저는 필터링됩니다.
결론
Android 11에서 작동하도록 기존 맞춤 탭 통합을 조정하는 데 필요한 모든 변경사항입니다. 맞춤 탭을 Android 앱에 통합하는 방법을 자세히 알아보려면 먼저 구현 가이드를 살펴본 다음 권장사항을 확인하여 최고의 통합을 빌드하는 방법을 알아보세요.
궁금한 점이나 의견이 있으면 알려주세요.