2015-10-06 19 views
6

Mam aktywność, która ładuje zewnętrzny adres URL do widoku WWW w mojej aplikacji. Chciałbym używać kart niestandardowych Chrome, gdy są one dostępne, ale obsługuję urządzenia, które mogą nie mieć wersji Chrome, która je obsługuje.Jak mogę sprawdzić, czy Chrome obsługuje niestandardowe karty Chrome?

W przypadku nieobsługiwania CustomTabs chciałbym użyć mojego starego kodu, ale używam CustomTabsIntent.Builder(), gdy są. Stary kod ładuje zawartość do WebView zawartego w działaniu, w którym nadal mogę zarządzać ActionBarem.

Chciałbym napisać metodę pomocnika, która powie mi, czy jest obsługiwana, ale nie jestem pewien jak. Informacje na stronie dla programistów są dość wąskie: https://developer.chrome.com/multidevice/android/customtabs

Mówi, że jeśli powiążesz pomyślnie, można bezpiecznie używać niestandardowych zakładek. Czy istnieje łatwy sposób wiązania, aby to przetestować?

Jak to zakładam:

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 
} 

Odpowiedz

5

skończyło się na piśmie statycznej metody w klasie Utils więc mogę sprawdzić i obsłużyć przypadku, gdy nie jest obsługiwany:

/** 
    * 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

Czy to sprawdzi, czy karty niestandardowe Chrome są obsługiwane w innych przeglądarkach? – X09

11

Zamiast wiązania i odłączania usługi, można użyć menedżera pakietów, aby sprawdzić, czy obsługiwane są niestandardowe karty.

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()); 
    } 

Należy pamiętać, że inne przeglądarki mogą obsługiwać karty niestandardowe w przyszłości, więc możesz chcieć je zmodyfikować w celu obsługi tego przypadku.

+0

jesteś ekspertem w dziedzinie niestandardowej zakładki chrome .. –

6

Można spróbować następujący kod, aby dowiedzieć się, czy masz przeglądarkę, która obsługuje niestandardową kartę:

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; 
} 

Dzwoniąc, można zrobić coś takiego:

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

Fantastyczna odpowiedź, można zmodyfikować, aby zwrócić prostą wartość boolową, wskazującą na istnienie przeglądarki zgodnej z Chrome Tab. https://gist.github.com/aashreys/fd8a14e652b7c80b784dc90be235d208 – aashrey99

0

I rozwiązać ten problem przez obsługę wyjątku ActivityNotFound w bloku catch.

Sztuką jest sprawdzenie, czy aktywność przeglądarki Chrome może zostać uruchomiona, czy nie, czy nie można uruchomić, czy wyrzuca wyjątek, po prostu otwórz link przez Intent.ACTION_VIEW.

Tutaj wszystko jest odpowiedni kod ....

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); 
} 

Co jest openCustomTab(url) mówisz: Oto odpowiedni kod dla niego.

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()); 
} 

Mój styl odpowiedź może wydawać się zarozumiały, ale przed kliknięciem downvote dać mi znać, jeśli napotkasz jakiekolwiek nieoczekiwanego błędu lub innego problemu, że takie podejście może mieć przyczynę. Przekaż swoją opinię, jesteśmy społecznością.

1

ze strony dewelopera Chrome, znalazłem następne -

Począwszy od Chrome 45, Chrome klienta Tabs jest teraz ogólnie dostępne dla wszystkich użytkowników Chrome na wszystkich obsługiwanych wersji Androida Chrome (Jellybean dalej).

Link: https://developer.chrome.com/multidevice/android/customtabs#whencaniuseit

Tak, sprawdziłem czy Chrome obsługuje Tab Chrome niestandardowy od wersji.

Sprawdź mój kod:

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 
} 

Nie wiem, jak skuteczne jest to, po prostu chcą się dzielić.

Powiązane problemy