Created
May 12, 2016 00:58
-
-
Save chibatching/2e29f2fa80e576c6169675501514c3c7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.app.Activity | |
import android.content.ComponentName | |
import android.content.Context | |
import android.content.Intent | |
import android.content.pm.PackageManager | |
import android.graphics.Bitmap | |
import android.net.Uri | |
import android.support.customtabs.CustomTabsClient | |
import android.support.customtabs.CustomTabsIntent | |
import android.support.customtabs.CustomTabsServiceConnection | |
import android.support.customtabs.CustomTabsSession | |
import android.text.TextUtils | |
import java.util.* | |
class CustomTabsHelper( | |
val activity: Activity, | |
val showTitle: Boolean, | |
val toolbarColorInt: Int? = null, | |
val secondaryToolbarColor: Int? = null, | |
val closeButtonIcon: Bitmap? = null, | |
val startAnimation: Pair<Int, Int>? = null, | |
val exitAnimation: Pair<Int, Int>? = null, | |
val urlBarHiding: Boolean = false | |
) { | |
private var mayLaunchUrl: String? = null | |
private var customTabsConnection: CustomTabsServiceConnection? = null | |
private var customTabsClient: CustomTabsClient? = null | |
var customTabsSession: CustomTabsSession? = null | |
fun bindCustomTabs(url: String? = null) { | |
mayLaunchUrl = url | |
customTabsConnection?.let { return } | |
customTabsConnection = BargainCustomTabConnection() | |
CustomTabsClient.bindCustomTabsService(activity, getPackageNameToUse(activity), customTabsConnection) | |
} | |
fun unbindCustomTabs() { | |
customTabsConnection?.let { | |
activity.unbindService(it) | |
customTabsClient = null | |
customTabsSession = null | |
customTabsConnection = null | |
} | |
} | |
fun launchUrl(url: String? = mayLaunchUrl) { | |
url?.let { | |
CustomTabsIntent.Builder(customTabsSession).apply { | |
setShowTitle(showTitle) | |
toolbarColorInt?.let { setToolbarColor(it) } | |
secondaryToolbarColor?.let { setSecondaryToolbarColor(it) } | |
closeButtonIcon?.let { setCloseButtonIcon(it) } | |
startAnimation?.let { setStartAnimations(activity, it.first, it.second) } | |
exitAnimation?.let { setExitAnimations(activity, it.first, it.second) } | |
if (urlBarHiding) { | |
enableUrlBarHiding() | |
} | |
}.build() | |
.launchUrl(activity, Uri.parse(it)) | |
} | |
} | |
inner class BargainCustomTabConnection : CustomTabsServiceConnection() { | |
override fun onCustomTabsServiceConnected(componentName: ComponentName, customTabsClient: CustomTabsClient) { | |
this@CustomTabsHelper.customTabsClient = customTabsClient.apply { warmup(0) } | |
this@CustomTabsHelper.customTabsSession = this@CustomTabsHelper.customTabsClient?.newSession(null) | |
this@CustomTabsHelper.customTabsSession?.mayLaunchUrl(Uri.parse(mayLaunchUrl), null, null) | |
} | |
override fun onServiceDisconnected(name: ComponentName?) { | |
this@CustomTabsHelper.customTabsClient = null | |
} | |
} | |
// Below code from custom-tabs-client sample | |
// https://github.com/GoogleChrome/custom-tabs-client/blob/addb26ad8fce8cdcb640217f4c9da75dd19763cc/shared/src/main/java/org/chromium/customtabsclient/shared/CustomTabsHelper.java | |
companion object { | |
private val STABLE_PACKAGE = "com.android.chrome" | |
private val BETA_PACKAGE = "com.chrome.beta" | |
private val DEV_PACKAGE = "com.chrome.dev" | |
private val LOCAL_PACKAGE = "com.google.android.apps.chrome" | |
private val ACTION_CUSTOM_TABS_CONNECTION = "android.support.customtabs.action.CustomTabsService" | |
private var packageNameToUse: String? = null | |
} | |
fun getPackageNameToUse(context: Context): String? { | |
packageNameToUse?.let { return it } | |
val pm = context.packageManager | |
// Get default VIEW intent handler. | |
val activityIntent = Intent(Intent.ACTION_VIEW, Uri.parse("http://www.example.com")) | |
val defaultViewHandlerInfo = pm.resolveActivity(activityIntent, 0) | |
var defaultViewHandlerPackageName: String? = null | |
if (defaultViewHandlerInfo != null) { | |
defaultViewHandlerPackageName = defaultViewHandlerInfo.activityInfo.packageName | |
} | |
// Get all apps that can handle VIEW intents. | |
val resolvedActivityList = pm.queryIntentActivities(activityIntent, 0) | |
val packagesSupportingCustomTabs = ArrayList<String>() | |
for (info in resolvedActivityList) { | |
val serviceIntent = Intent() | |
serviceIntent.action = ACTION_CUSTOM_TABS_CONNECTION | |
serviceIntent.`package` = 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()) { | |
packageNameToUse = null | |
} else if (packagesSupportingCustomTabs.size == 1) { | |
packageNameToUse = packagesSupportingCustomTabs[0] | |
} else if (!TextUtils.isEmpty(defaultViewHandlerPackageName) | |
&& !hasSpecializedHandlerIntents(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 fun hasSpecializedHandlerIntents(intent: Intent): Boolean { | |
try { | |
val pm = activity.packageManager | |
val handlers = pm.queryIntentActivities( | |
intent, | |
PackageManager.GET_RESOLVED_FILTER) | |
if (handlers == null || handlers.size == 0) { | |
return false | |
} | |
for (resolveInfo in handlers) { | |
val filter = resolveInfo.filter ?: continue | |
if (filter.countDataAuthorities() == 0 || filter.countDataPaths() == 0) continue | |
if (resolveInfo.activityInfo == null) continue | |
return true | |
} | |
} catch (e: RuntimeException) { | |
} | |
return false | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment