自定义Chrome选项卡要求选择多个浏览器

15

我正在尝试实现自定义Chrome标签。 我正在使用Google的默认库customtabs

我参考了这篇教程来实现自定义Chrome标签。现在,根据教程建议,我编写了以下代码。

mCustomTabsServiceConnection = new CustomTabsServiceConnection() {
    @Override
    public void onCustomTabsServiceConnected(
        ComponentName componentName,
        CustomTabsClient customTabsClient) {
        mCustomTabsClient = customTabsClient;
        mCustomTabsClient.warmup(0L);
        mCustomTabsSession = mCustomTabsClient.newSession(null);
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        mCustomTabsClient = null;
    }
};

CustomTabsClient.bindCustomTabsService(this, "com.android.chrome",
        mCustomTabsServiceConnection);

CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(
        mCustomTabsSession).setShowTitle(true);
builder.setToolbarColor(getResources().getColor(R.color.purple_main));
        builder.setStartAnimations(getApplicationContext(), R.anim.fadein,
                R.anim.fadeout);
builder.setExitAnimations(getApplicationContext(), R.anim.fadein,
                R.anim.fadeout);
mCustomTabsIntent = builder.build(); 

并启动自定义标签页。

mCustomTabsIntent.launchUrl(TampleDetails.this,
       Uri.parse(temple_website));

现在你看到我已经将自定义选项卡与Chrome的包名称绑定在一起,但它仍然要求在Chrome和UC浏览器之间进行选择。显然,UC浏览器不支持自定义选项卡。

所以我的问题是如何限制自定义选项卡只与Chrome浏览器绑定?

任何帮助都将不胜感激。

谢谢。


你正在测试哪个Android版本? - Valentino
@ValentinoS. 果冻豆 4.2.2 - V-rund Puro-hit
4个回答

22

请查看此stackoverflow答案:如果在启动url之前,将CustomTabIntent包设置为您想要的浏览器的包,则可以跳过Android浏览器选择对话框; 对我而言,这很有效:

/**
 * Opens the URL on a Custom Tab
 *
 * @param activity         The host activity.
 * @param uri              the Uri to be opened.
 */
public static void openCustomTab(Activity activity,
                                 Uri uri) {
    // Here is a method that returns the chrome package name 
    String packageName = CustomTabsHelper.getPackageNameToUse(activity, mUrl);

    CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
    mCustomTabsIntent = builder
            .setShowTitle(true)
            .build();
    builder.setToolbarColor(ContextCompat.getColor(activity, R.color.colorPrimary));

    if ( packageName != null ) {
        mCustomTabsIntent.intent.setPackage(packageName);
    }
    mCustomTabsIntent.launchUrl(activity, uri);
}

mCustomTabsIntent.intent.setPackage(packageName); 这行代码导致了一个“未找到活动”错误。 - Prabs
3
请在执行以下代码前检查变量packageName是否为null: if (packageName != null) { mCustomTabsIntent.intent.setPackage(packageName); } - Valentino

16

支持多个浏览器

自定义标签协议是开放的,这意味着其他浏览器可以支持它。事实上,三星互联网浏览器已经支持它(虽然有些不完善),而Firefox则在其夜间版本中增加了初步的、非常实验性的支持。

因此,最佳实践应该是查询Android系统安装的浏览器中哪些支持自定义标签协议:

private static final String ACTION_CUSTOM_TABS_CONNECTION =
        "android.support.customtabs.action.CustomTabsService";

public static ArrayList<ResolveInfo> getCustomTabsPackages(Context context) {
    PackageManager pm = context.getPackageManager();
    // Get default VIEW intent handler.
    Intent activityIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.example.com"));

    // Get all apps that can handle VIEW intents.
    List<ResolveInfo> resolvedActivityList = pm.queryIntentActivities(activityIntent, 0);
    ArrayList<ResolveInfo> 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);
        }
    }

    return packagesSupportingCustomTabs;
}

您可能希望检查ResolveInfo#preferredOrder来确定用户是否更喜欢其中一个应用程序。此外,如果没有首选的应用程序(或两个应用程序具有相同的主要偏好级别),您可能需要询问用户选择一个或采用合理的默认设置。

关于原生应用程序的思考

还有一点很重要,那就是检查所给的URL是否已安装处理它的本机应用程序。如果是这样,您的应用程序启动本机应用程序而不是在自定义标签中打开它可能是有意义的:

public static List<ResolveInfo> getNativeApp(Context context, Uri uri) {
    PackageManager pm = context.getPackageManager();

    //Get all Apps that resolve a random url
    Intent browserActivityIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.example.com"));
    List<ResolveInfo> resolvedBrowserList = pm.queryIntentActivities(browserActivityIntent, 0);

    Intent specializedActivityIntent = new Intent(Intent.ACTION_VIEW, uri);
    List<ResolveInfo> resolvedSpecializedList = pm.queryIntentActivities(specializedActivityIntent, 0);
    resolvedSpecializedList.removeAll(resolvedBrowserList);

    return resolvedBrowserList;

}

使用特定包名打开自定义标签页

一旦决定使用哪个处理程序打开自定义标签页,使用mCustomTabsIntent.intent.setPackage(packageName);来告诉自定义标签页要用哪个应用程序打开它。


我发现某些设备上安装的Chrome和Firefox浏览器不被以下代码捕获: Intent serviceIntent = new Intent(); serviceIntent.setAction(ACTION_CUSTOM_TABS_CONNECTION); serviceIntent.setPackage(info.activityInfo.packageName); if (pm.resolveService(serviceIntent, 0) != null) { packagesSupportingCustomTabs.add(info); }你有什么想法,andreban? - Kannan_SJD

2
可能会有帮助。
    CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
    CustomTabsIntent customTabsIntent = builder.build();

    customTabsIntent.intent.setPackage("com.android.chrome");
    builder.setToolbarColor(ContextCompat.getColor(context,R.color.colorPrimary));
    builder.setShowTitle(true);
    builder.addDefaultShareMenuItem();

    builder.build().launchUrl((Activity) context, Uri.parse(http_link));

2
如果您没有在特定的包名称下安装Chrome,那么这段代码只能在该情况下运行,否则您的应用程序将会崩溃。 - Markonioninioni

1
您可以通过像这样指定包名来避免此问题:intentCustomTabs.intent.setPackage("com.android.chrome");
完整代码:
    String url = link;
    CustomTabsIntent.Builder builderCustomTabs = new CustomTabsIntent.Builder();
    CustomTabsIntent intentCustomTabs = builderCustomTabs.build();
    intentCustomTabs.intent.setPackage("com.android.chrome"); 
    intentCustomTabs.intent.addFlags(new Integer("67108864"));
    builderCustomTabs.setShowTitle(true); 
    builderCustomTabs.setToolbarColor(ContextCompat.getColor(this, R.color.colorPrimary));
    builderCustomTabs.enableUrlBarHiding();
    intentCustomTabs.launchUrl(this, Uri.parse(url));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接