2015-10-06 2 views
6

У меня есть активность, которая загружает внешний url в веб-просмотр в моем приложении. Я бы хотел использовать вкладки Chrome Custom, когда он доступен, но я поддерживаю устройства, которые могут не иметь версию Chrome, которая их поддерживает.Как проверить, поддерживает ли Chrome пользовательские вкладки Chrome?

В случае поддержки CustomTabs я бы хотел использовать старый код, но использовать CustomTabsIntent.Builder(), когда они есть. Старый код загружает содержимое в WebView, содержащееся в Activity, где я все еще могу управлять ActionBar.

Я хотел бы написать вспомогательный метод, который скажет мне, поддерживается ли он, но я не уверен, как это сделать. Информация на странице разработчика довольно тонкая: https://developer.chrome.com/multidevice/android/customtabs

Сообщается, что если вы привязываете успешно, пользовательские вкладки могут быть безопасно использованы. Есть ли простой способ привязки, чтобы проверить это?

Как это я предполагаю:

Intent serviceIntent = new Intent("android.support.customtabs.action.CustomTabsService"); 
serviceIntent.setPackage("com.android.chrome"); 
boolean customTabsSupported = bindService(serviceIntent, new CustomTabsServiceConnection() { 
      @Override 
      public void onCustomTabsServiceConnected(final ComponentName componentName, final CustomTabsClient customTabsClient) {} 

      @Override 
      public void onServiceDisconnected(final ComponentName name) {} 
     }, 
     Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY); 

if (customTabsSupported) { 
    // is supported 
} 

ответ

5

Я закончил тем, что писал статический метод в моем классе Utils, так что я могу проверить и обработать случай, когда он не поддерживается:

/** 
    * Check if Chrome CustomTabs are supported. 
    * Some devices don't have Chrome or it may not be 
    * updated to a version where custom tabs is supported. 
    * 
    * @param context the context 
    * @return whether custom tabs are supported 
    */ 
    public static boolean isChromeCustomTabsSupported(@NonNull final Context context) { 
     Intent serviceIntent = new Intent("android.support.customtabs.action.CustomTabsService"); 
     serviceIntent.setPackage("com.android.chrome"); 

     CustomTabsServiceConnection serviceConnection = new CustomTabsServiceConnection() { 
      @Override 
      public void onCustomTabsServiceConnected(final ComponentName componentName, final CustomTabsClient customTabsClient) { } 

      @Override 
      public void onServiceDisconnected(final ComponentName name) { } 
     }; 

     boolean customTabsSupported = 
       context.bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY); 
     context.unbindService(serviceConnection); 

     return customTabsSupported; 
    } 
+2

Будет ли это проверяться, поддерживаются ли пользовательские вкладки Chrome в других браузерах? – X09

11

Вместо привязки и открепления службы, вы можете использовать PackageManager, чтобы проверить, поддерживаются ли пользовательские вкладки.

private static final String SERVICE_ACTION = "android.support.customtabs.action.CustomTabsService"; 
    private static final String CHROME_PACKAGE = "com.android.chrome"; 

    private static boolean isChromeCustomTabsSupported(@NonNull final Context context) { 
     Intent serviceIntent = new Intent(SERVICE_ACTION); 
     serviceIntent.setPackage(CHROME_PACKAGE); 
     List<ResolveInfo> resolveInfos = context.getPackageManager().queryIntentServices(serviceIntent, 0); 
     return !(resolveInfos == null || resolveInfos.isEmpty()); 
    } 

Имейте в виду, что другие браузеры могут поддерживать пользовательские вкладки в будущем, так что вы можете изменить, что для поддержки этого дела.

+0

вы являетесь экспертом на вкладке chrome chrome .. –

6

Вы можете попробовать следующий код, чтобы выяснить, если у вас есть браузер, который поддерживает пользовательские вкладки:

private static final String TAG = "CustomTabLauncher"; 
static final String STABLE_PACKAGE = "com.android.chrome"; 
static final String BETA_PACKAGE = "com.chrome.beta"; 
static final String DEV_PACKAGE = "com.chrome.dev"; 
static final String LOCAL_PACKAGE = "com.google.android.apps.chrome"; 
String mPackageNameToUse; 

private String getPackageName(Context context) { 
    if (mPackageNameToUse != null) { 
     return mPackageNameToUse; 
    } 

    // Get default VIEW intent handler that can view a web url. 
    Intent activityIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.test-url.com")); 

    // Get all apps that can handle VIEW intents. 
    PackageManager pm = context.getPackageManager(); 
    List<ResolveInfo> resolvedActivityList = pm.queryIntentActivities(activityIntent, 0); 
    List<String> packagesSupportingCustomTabs = new ArrayList<>(); 
    for (ResolveInfo info : resolvedActivityList) { 
     Intent serviceIntent = new Intent(); 
     serviceIntent.setAction(CustomTabsService.ACTION_CUSTOM_TABS_CONNECTION); 
     serviceIntent.setPackage(info.activityInfo.packageName); 
     if (pm.resolveService(serviceIntent, 0) != null) { 
      packagesSupportingCustomTabs.add(info.activityInfo.packageName); 
     } 
    } 

    // Now packagesSupportingCustomTabs contains all apps that can handle both VIEW intents 
    // and service calls. 
    if (packagesSupportingCustomTabs.isEmpty()) { 
     mPackageNameToUse = null; 
    } else if (packagesSupportingCustomTabs.size() == 1) { 
     mPackageNameToUse = packagesSupportingCustomTabs.get(0); 
    } else if (packagesSupportingCustomTabs.contains(STABLE_PACKAGE)) { 
     mPackageNameToUse = STABLE_PACKAGE; 
    } else if (packagesSupportingCustomTabs.contains(BETA_PACKAGE)) { 
     mPackageNameToUse = BETA_PACKAGE; 
    } else if (packagesSupportingCustomTabs.contains(DEV_PACKAGE)) { 
     mPackageNameToUse = DEV_PACKAGE; 
    } else if (packagesSupportingCustomTabs.contains(LOCAL_PACKAGE)) { 
     mPackageNameToUse = LOCAL_PACKAGE; 
    } 
    return mPackageNameToUse; 
} 

При вызове, вы можете сделать что-то вроде этого:

public void openCustomTab(Uri uri, Activity activity) { 
    //If we cant find a package name, it means there's no browser that supports 
    //Chrome Custom Tabs installed. So, we fallback to the default browser 
    if (getPackageName(activity) == null) { 
     activity.startActivity(new Intent(Intent.ACTION_VIEW, uri)); 
    } else { 
     CustomTabsIntent.Builder intentBuilder = new CustomTabsIntent.Builder(); 
     intentBuilder.enableUrlBarHiding(); 
     intentBuilder.setToolbarColor(activity.getResources().getColor(R.color.purple_a_01)); 

     CustomTabsIntent customTabsIntent = intentBuilder.build(); 
     customTabsIntent.intent.setPackage(mPackageNameToUse); 

     customTabsIntent.launchUrl(activity, uri); 
    } 
} 
+0

Фантастический ответ может быть изменен, чтобы вернуть простое логическое значение, указывающее на наличие браузера, совместимого с Chrome Tab. https://gist.github.com/aashreys/fd8a14e652b7c80b784dc90be235d208 – aashrey99

0

Я решил эту проблему путем обработки ActivityNotFound исключение в блоке catch.

Уловка заключается в том, чтобы проверить, можно ли запустить действие браузера хрома или нет, если он не может быть запущен или генерирует исключение, просто откройте ссылку через Intent.ACTION_VIEW.

Здесь все соответствующий код ....

private void onBtnLinkClicked(View v, int pos) { 
    try { 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 
      openCustomTab(url); 
     } else { 
      openBrowserActivity(url); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
     openBrowserActivity(url); 
    } 
} 

private void openBrowserActivity(String url) { 
    Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); 
    context.startActivity(browserIntent); 
} 

Что openCustomTab(url) вы говорите: Вот соответствующий код для него.

private void openCustomTab(String url) { 
    CustomTabsIntent.Builder intentBuilder = new CustomTabsIntent.Builder(); 

    int color = context.getResources().getColor(R.color.colorPrimary); 
    intentBuilder.setToolbarColor(color); 
    intentBuilder.setShowTitle(true); 

    String menuItemTitle = context.getString(R.string.menu_title_share); 
    PendingIntent menuItemPendingIntent = createPendingShareIntent(); 
    intentBuilder.addMenuItem(menuItemTitle, menuItemPendingIntent);  

    intentBuilder.setStartAnimations(context, 
      R.anim.slide_in_right, R.anim.slide_out_left); 
    intentBuilder.setExitAnimations(context, 
      android.R.anim.slide_in_left, android.R.anim.slide_out_right); 

    CustomTabActivityHelper.openCustomTab(
      activity, intentBuilder.build(), Uri.parse(url), new WebviewFallback()); 
} 

Мой стиль ответ может показаться дерзким, но, прежде чем нажать downvote, дайте мне знать, если вы столкнулись с какой-либо неожиданной ошибки или любой другой проблемы, что такой подход может иметь дело. Получайте свои отзывы, мы - сообщество в целом.

1

От разработчиков сайта Chrome, я нашел нижеуказанных -

С Chrome 45, Chrome Пользовательские вкладки теперь обычно доступны для всех пользователей Chrome, на всех поддерживаемых Android версии в Chrome (Jellybean и далее).

Ссылка: https://developer.chrome.com/multidevice/android/customtabs#whencaniuseit

Итак, я проверил, поддерживает ли ChromeChrome настраиваемой вкладки от версии.

Проверьте мой код:

String chromePackageName = "com.android.chrome"; 
int chromeTargetVersion = 45; 

boolean isSupportCustomTab = false; 
try { 
    String chromeVersion = getApplicationContext().getPackageManager().getPackageInfo(chromePackageName, 0).versionName; 
    if(chromeVersion.contains(".")) { 
     chromeVersion = chromeVersion.substring(0, chromeVersion.indexOf('.')); 
    } 
    isSupportCustomTab = (Integer.valueOf(chromeVersion) >= chromeTargetVersion); 
} catch (PackageManager.NameNotFoundException ex) { 
} catch (Exception ex) { } 

if (isSupportCustomTab) { 
    //Use Chrome Custom Tab 
} else { 
    //Use WebView or other Browser 
} 

Я не знаю, насколько эффективно это, просто хочу поделиться.

Смежные вопросы