![](/img/trans.png)
[英]I have implemented gridview in my android but i am unable to open chrome custom tabs with on itemclick in grid view with webview fallback
[英]Android Chrome custom tabs fallback
我正在實施fallback chrome自定義標簽
我指的是它有一些自定義回退實現的鏈接。 我不知道為什么需要它。
我做了以下處理后備並且工作正常。
try {
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
builder.setToolbarColor(ContextCompat.getColor(context, R.color.appthemecolor));
CustomTabsIntent customTabsIntent = builder.build();
customTabsIntent.launchUrl(context, Uri.parse(url));
} catch (ActivityNotFoundException e) {
e.printStackTrace();
Intent intent = new Intent(context, WebviewActivity.class);
intent.putExtra(WebviewActivity.EXTRA_URL, url);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);
}
知道為什么處理回退需要這么復雜的實現嗎?
使用以下版本的支持庫compile 'com.android.support:customtabs:25.3.1'
如果您看到CustomTabsIntent
的源代碼,它只不過是一個幫助器來創建使用Intent.ACTION_VIEW
打開URL的常規隱式意圖。 它可以幫助您使用Chrome識別的特定鍵向意圖添加額外數據,Chrome隨后會使用這些鍵來呈現自定義UI。
以下是官方網頁的解釋:
自定義選項卡使用ACTION_VIEW Intent和關鍵Extras來自定義UI。 這意味着默認情況下,頁面將在系統瀏覽器或用戶的默認瀏覽器中打開。
如果用戶安裝了Chrome並且它是默認瀏覽器,它將自動獲取EXTRAS並顯示自定義UI。 另一個瀏覽器也可以使用Intent附加功能來提供類似的自定義界面。
對於鏈接上的解決方案,源代碼取自此處 。 正如您在CustomTabActivityHelper#openCustomTab
看到的,首先它將查找支持自定義選項卡的應用程序。 如果可用,則啟動CustomTabsIntent
描述的隱式intent。 如果沒有,請打開WebViewActivity
。
如何找出是否有任何應用支持自定義標簽? 您可以在CustomTabsHelper.getPackageNameToUse
。 首先,它將解析所有可以使用Intent.ACTION_VIEW
打開URL的應用程序。 然后,它將檢查該應用是否支持自定義標簽。
然后,
null
null
現在,您的解決方案如何?
如果我們使用您的解決方案,如果沒有應用程序可以處理CustomTabsIntent
創建的隱式意圖,則會打開WebviewActivity
,在這種情況下沒有安裝瀏覽器? 如果我們有瀏覽器並且它們都不支持自定義標簽會發生什么? 您的應用仍會要求在瀏覽器中打開鏈接,而不是在WebViewActivity
中WebViewActivity
。
請記住, CustomTabsIntent
只是一個幫助器,可以創建一個正常的隱式意圖,使用Intent.ACTION_VIEW
打開一個URL,並使用各種EXTRA數據來自定義UI。 如何自定義UI由瀏覽器處理。 基本上,我認為我們可以創建並啟動使用自定義UI打開瀏覽器的意圖,而無需CustomTabsIntent
。 我從來沒有試過這個。
如果您希望在任何瀏覽器中打開鏈接,無論瀏覽器是否支持自定義選項卡,以及在沒有可用應用程序的情況下在WebViewActivity
打開的鏈接,您的解決方案即使不是我認為的最佳解決方案也能解決它。
但是,如果您希望在支持自定義選項卡的瀏覽器中打開鏈接,並且如果沒有支持自定義選項卡的應用程序可以在WebViewActivity
打開鏈接,則他的解決方案是正確的。
但是,如果您想要的只是提供回退機制,那就不應該那么復雜了。 這是更簡單的代碼:
public class CustomTabs {
private static final String ACTION_CUSTOM_TABS_CONNECTION = "android.support.customtabs.action.CustomTabsService";
private static final String STABLE_PACKAGE = "com.android.chrome";
private static final String BETA_PACKAGE = "com.chrome.beta";
private static final String DEV_PACKAGE = "com.chrome.dev";
private static final String LOCAL_PACKAGE = "com.google.android.apps.chrome";
public static void openTab(Context context, String url) {
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
/* do some UI customization here */
CustomTabsIntent customTabsIntent = builder.build();
String packageName = getPackageNameToUse(context);
if (packageName == null) {
Intent intent = new Intent(context, WebviewActivity.class);
intent.putExtra(WebviewActivity.EXTRA_URL, url);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);
} else {
customTabsIntent.intent.setPackage(packageName);
customTabsIntent.launchUrl(context, Uri.parse(url));
}
}
private static String getPackageNameToUse(Context context) {
String packageNameToUse = null;
PackageManager pm = context.getPackageManager();
Intent activityIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.example.com"));
ResolveInfo defaultViewHandlerInfo = pm.resolveActivity(activityIntent, 0);
String defaultViewHandlerPackageName = null;
if (defaultViewHandlerInfo != null) {
defaultViewHandlerPackageName = defaultViewHandlerInfo.activityInfo.packageName;
}
List<ResolveInfo> resolvedActivityList = pm.queryIntentActivities(activityIntent, 0);
List<String> packagesSupportingCustomTabs = new ArrayList<>();
for (ResolveInfo info : resolvedActivityList) {
Intent serviceIntent = new Intent();
serviceIntent.setAction(ACTION_CUSTOM_TABS_CONNECTION);
serviceIntent.setPackage(info.activityInfo.packageName);
if (pm.resolveService(serviceIntent, 0) != null) {
packagesSupportingCustomTabs.add(info.activityInfo.packageName);
}
}
if (packagesSupportingCustomTabs.isEmpty()) {
packageNameToUse = null;
} else if (packagesSupportingCustomTabs.size() == 1) {
packageNameToUse = packagesSupportingCustomTabs.get(0);
} else if (!TextUtils.isEmpty(defaultViewHandlerPackageName)
&& !hasSpecializedHandlerIntents(context, activityIntent)
&& packagesSupportingCustomTabs.contains(defaultViewHandlerPackageName)) {
packageNameToUse = defaultViewHandlerPackageName;
} else if (packagesSupportingCustomTabs.contains(STABLE_PACKAGE)) {
packageNameToUse = STABLE_PACKAGE;
} else if (packagesSupportingCustomTabs.contains(BETA_PACKAGE)) {
packageNameToUse = BETA_PACKAGE;
} else if (packagesSupportingCustomTabs.contains(DEV_PACKAGE)) {
packageNameToUse = DEV_PACKAGE;
} else if (packagesSupportingCustomTabs.contains(LOCAL_PACKAGE)) {
packageNameToUse = LOCAL_PACKAGE;
}
return packageNameToUse;
}
private static boolean hasSpecializedHandlerIntents(Context context, Intent intent) {
try {
PackageManager pm = context.getPackageManager();
List<ResolveInfo> handlers = pm.queryIntentActivities(intent, PackageManager.GET_RESOLVED_FILTER);
if (handlers == null || handlers.size() == 0) {
return false;
}
for (ResolveInfo resolveInfo : handlers) {
IntentFilter filter = resolveInfo.filter;
if (filter == null) continue;
if (filter.countDataAuthorities() == 0 || filter.countDataPaths() == 0) continue;
if (resolveInfo.activityInfo == null) continue;
return true;
}
} catch (RuntimeException e) {
Log.e("LOG", "Runtime exception while getting specialized handlers");
}
return false;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.