Last active
March 10, 2021 08:55
-
-
Save Asutosh11/098e2e3c62e26dd79935777665d7c121 to your computer and use it in GitHub Desktop.
Android: Open a web page in chrome custom tabs and also show a custom native view on top of it
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
<?xml version="1.0" encoding="utf-8"?> | |
<LinearLayout | |
xmlns:android="http://schemas.android.com/apk/res/android" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:orientation="horizontal"> | |
<TextView | |
android:id="@+id/btn_xml" | |
android:layout_width="0dp" | |
android:layout_height="wrap_content" | |
android:layout_weight="1" | |
android:gravity="center" | |
android:padding="8dp" | |
android:text="just a button" | |
android:textColor="#fff" | |
android:background="#31adad" | |
/> | |
</LinearLayout> |
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
package com.asutosh.trials | |
import `in`.novopay.los.ui.offlinekyc.WebViewActivity | |
import android.app.PendingIntent | |
import android.content.Context | |
import android.content.Intent | |
import android.content.pm.PackageManager | |
import android.net.Uri | |
import android.text.TextUtils | |
import android.widget.RemoteViews | |
import androidx.browser.customtabs.CustomTabsIntent | |
import androidx.browser.customtabs.CustomTabsService | |
class CustomTabHelper { | |
var sPackageNameToUse: String? = null | |
val STABLE_PACKAGE = "com.android.chrome" | |
val BETA_PACKAGE = "com.chrome.beta" | |
val DEV_PACKAGE = "com.chrome.dev" | |
val LOCAL_PACKAGE = "com.google.android.apps.chrome" | |
/** @context: context of the activity or application context | |
* @url: the url to open in the chrome custom tab | |
* @pendingIntent: the intent that will be fired on clicking on the custom view on the chrome custom tab | |
* @packageName: package name from where the chrome custom tab is loaded | |
* @customXmlLayout: XML layout, where the custom native view to be shown on the chrome custom tab is | |
* @idOfCustomView: id of the custom native view to be shown on the chrome custom tab | |
*/ | |
fun loadCustomChromeTab( | |
context: Context, | |
url: String, | |
pendingIntent: PendingIntent, | |
packageName: String, | |
customXmlLayout: Int, | |
idOfCustomView: Int) { | |
val builder = CustomTabsIntent.Builder() | |
// this view will be placed as a native view on the webpage loaded on chrome custom tab | |
val remoteViews = RemoteViews(packageName, customXmlLayout) | |
builder.setSecondaryToolbarViews( | |
remoteViews, | |
intArrayOf(idOfCustomView), | |
pendingIntent | |
) | |
val customTabsIntent = builder.build() | |
val packageName = getPackageNameToUse(context, url) | |
if (packageName == null) { | |
// if chrome not available open in web view | |
val intentOpenUri = Intent(context, WebViewActivity::class.java) | |
intentOpenUri.putExtra(WebViewActivity.EXTRA_URL, Uri.parse(url).toString()) | |
context.startActivity(intentOpenUri) | |
} else { | |
// open in chrome custom tab | |
customTabsIntent.intent.setPackage(packageName) | |
customTabsIntent.launchUrl(context, Uri.parse(url)) | |
} | |
} | |
fun getPackageNameToUse(context: Context, url: String): String? { | |
sPackageNameToUse?.let { | |
return it | |
} | |
val pm = context.getPackageManager() | |
val activityIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) | |
val defaultViewHandlerInfo = pm.resolveActivity(activityIntent, 0) | |
var defaultViewHandlerPackageName: String? = null | |
defaultViewHandlerInfo?.let { | |
defaultViewHandlerPackageName = it.activityInfo.packageName | |
} | |
val resolvedActivityList = pm.queryIntentActivities(activityIntent, 0) | |
val packagesSupportingCustomTabs = ArrayList<String>() | |
for (info in resolvedActivityList) { | |
val serviceIntent = Intent() | |
serviceIntent.action = CustomTabsService.ACTION_CUSTOM_TABS_CONNECTION | |
serviceIntent.setPackage(info.activityInfo.packageName) | |
pm.resolveService(serviceIntent, 0)?.let { | |
packagesSupportingCustomTabs.add(info.activityInfo.packageName) | |
} | |
} | |
when { | |
packagesSupportingCustomTabs.isEmpty() -> sPackageNameToUse = null | |
packagesSupportingCustomTabs.size == 1 -> sPackageNameToUse = | |
packagesSupportingCustomTabs.get(0) | |
!TextUtils.isEmpty(defaultViewHandlerPackageName) | |
&& !hasSpecializedHandlerIntents(context, activityIntent) | |
&& packagesSupportingCustomTabs.contains(defaultViewHandlerPackageName) -> | |
sPackageNameToUse = defaultViewHandlerPackageName | |
packagesSupportingCustomTabs.contains(STABLE_PACKAGE) -> sPackageNameToUse = | |
STABLE_PACKAGE | |
packagesSupportingCustomTabs.contains(BETA_PACKAGE) -> sPackageNameToUse = BETA_PACKAGE | |
packagesSupportingCustomTabs.contains(DEV_PACKAGE) -> sPackageNameToUse = DEV_PACKAGE | |
packagesSupportingCustomTabs.contains(LOCAL_PACKAGE) -> sPackageNameToUse = | |
LOCAL_PACKAGE | |
} | |
return sPackageNameToUse | |
} | |
private fun hasSpecializedHandlerIntents(context: Context, intent: Intent): Boolean { | |
try { | |
val pm = context.getPackageManager() | |
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 | |
} | |
} |
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
val intent = Intent(applicationContext, FileChooserActivity::class.java) | |
val pendingIntent = PendingIntent.getActivity(applicationContext, 106, intent, PendingIntent.FLAG_UPDATE_CURRENT) | |
CustomTabHelper().loadCustomChromeTab( | |
this, | |
"http://example.com/", | |
pendingIntent, | |
packageName!!, | |
R.layout.custom_layout, | |
R.id.btn_xml) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment