mirror of
https://github.com/Matte23/circolapp.git
synced 2025-12-05 23:19:10 +00:00
Preload browser and page to speed up Custom Tabs
This commit is contained in:
@@ -5,6 +5,12 @@
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.support.customtabs.action.CustomTabsService" />
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
package net.underdesk.circolapp
|
||||
|
||||
import android.app.DownloadManager
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
@@ -30,6 +31,9 @@ import android.view.MenuItem
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.browser.customtabs.CustomTabsClient
|
||||
import androidx.browser.customtabs.CustomTabsServiceConnection
|
||||
import androidx.browser.customtabs.CustomTabsSession
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.findNavController
|
||||
import androidx.navigation.ui.AppBarConfiguration
|
||||
@@ -43,6 +47,7 @@ import kotlinx.coroutines.launch
|
||||
import net.underdesk.circolapp.adapters.CircularLetterAdapter
|
||||
import net.underdesk.circolapp.data.AndroidDatabase
|
||||
import net.underdesk.circolapp.databinding.ActivityMainBinding
|
||||
import net.underdesk.circolapp.utils.CustomTabsHelper
|
||||
import net.underdesk.circolapp.utils.DownloadableFile
|
||||
import net.underdesk.circolapp.works.PollWork
|
||||
|
||||
@@ -58,6 +63,8 @@ class MainActivity : AppCompatActivity(), CircularLetterAdapter.AdapterCallback
|
||||
var refreshCallback: RefreshCallback? = null
|
||||
override var fileToDownload: DownloadableFile? = null
|
||||
|
||||
var customTabsSession: CustomTabsSession? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
loadDarkTheme()
|
||||
super.onCreate(savedInstanceState)
|
||||
@@ -88,6 +95,26 @@ class MainActivity : AppCompatActivity(), CircularLetterAdapter.AdapterCallback
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
val connection: CustomTabsServiceConnection = object : CustomTabsServiceConnection() {
|
||||
override fun onCustomTabsServiceConnected(
|
||||
name: ComponentName,
|
||||
client: CustomTabsClient
|
||||
) {
|
||||
client.warmup(0)
|
||||
customTabsSession = client.newSession(null)
|
||||
}
|
||||
|
||||
override fun onServiceDisconnected(name: ComponentName) {}
|
||||
}
|
||||
CustomTabsClient.bindCustomTabsService(
|
||||
this,
|
||||
CustomTabsHelper.getPreferredCustomTabsPackage(this),
|
||||
connection
|
||||
)
|
||||
super.onStart()
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_main, menu)
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.view.ViewGroup
|
||||
import android.widget.ImageButton
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import net.underdesk.circolapp.MainActivity
|
||||
import net.underdesk.circolapp.databinding.ItemAttachmentBinding
|
||||
import net.underdesk.circolapp.utils.DownloadableFile
|
||||
import net.underdesk.circolapp.utils.FileUtils
|
||||
@@ -31,9 +32,10 @@ import net.underdesk.circolapp.utils.FileUtils
|
||||
class AttachmentAdapter(
|
||||
private val attachmentsNames: List<String>,
|
||||
private val attachmentsUrls: List<String>,
|
||||
private val adapterCallback: CircularLetterAdapter.AdapterCallback
|
||||
private val mainActivity: MainActivity,
|
||||
) :
|
||||
RecyclerView.Adapter<AttachmentAdapter.AttachmentViewHolder>() {
|
||||
private val adapterCallback: CircularLetterAdapter.AdapterCallback = mainActivity
|
||||
private lateinit var context: Context
|
||||
|
||||
inner class AttachmentViewHolder(binding: ItemAttachmentBinding) : RecyclerView.ViewHolder(binding.root) {
|
||||
@@ -54,7 +56,7 @@ class AttachmentAdapter(
|
||||
holder.title.text = attachmentsNames[position]
|
||||
|
||||
holder.viewButton.setOnClickListener {
|
||||
FileUtils.viewFile(attachmentsUrls[position], context)
|
||||
FileUtils.viewFile(attachmentsUrls[position], context, mainActivity.customTabsSession)
|
||||
}
|
||||
|
||||
holder.shareButton.setOnClickListener {
|
||||
|
||||
@@ -35,6 +35,7 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import net.underdesk.circolapp.AlarmBroadcastReceiver
|
||||
import net.underdesk.circolapp.MainActivity
|
||||
import net.underdesk.circolapp.R
|
||||
import net.underdesk.circolapp.data.AndroidDatabase
|
||||
import net.underdesk.circolapp.databinding.ItemCircularBinding
|
||||
@@ -45,11 +46,12 @@ import net.underdesk.circolapp.utils.FileUtils
|
||||
|
||||
class CircularLetterAdapter(
|
||||
private var circulars: List<Circular>,
|
||||
private val adapterCallback: AdapterCallback,
|
||||
private val mainActivity: MainActivity,
|
||||
private val adapterScope: CoroutineScope
|
||||
) :
|
||||
RecyclerView.Adapter<CircularLetterAdapter.CircularLetterViewHolder>() {
|
||||
private lateinit var context: Context
|
||||
private val adapterCallback: AdapterCallback = mainActivity
|
||||
private var collapsedItems = -1
|
||||
|
||||
init {
|
||||
@@ -136,6 +138,12 @@ class CircularLetterAdapter(
|
||||
holder.attachmentsList.visibility = View.GONE
|
||||
holder.attachmentsList.adapter = null
|
||||
} else {
|
||||
FileUtils.preloadFiles(
|
||||
circulars[position].url,
|
||||
circulars[position].attachmentsUrls,
|
||||
mainActivity.customTabsSession
|
||||
)
|
||||
|
||||
holder.collapseButton.setImageDrawable(
|
||||
getDrawable(
|
||||
context,
|
||||
@@ -155,7 +163,7 @@ class CircularLetterAdapter(
|
||||
holder.attachmentsList.adapter = AttachmentAdapter(
|
||||
circulars[position].attachmentsNames,
|
||||
circulars[position].attachmentsUrls,
|
||||
adapterCallback
|
||||
mainActivity
|
||||
)
|
||||
} else {
|
||||
holder.attachmentsList.adapter = null
|
||||
@@ -173,7 +181,7 @@ class CircularLetterAdapter(
|
||||
}
|
||||
}
|
||||
|
||||
FileUtils.viewFile(circulars[position].url, context)
|
||||
FileUtils.viewFile(circulars[position].url, context, mainActivity.customTabsSession)
|
||||
}
|
||||
|
||||
holder.shareButton.setOnClickListener {
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Circolapp
|
||||
* Copyright (C) 2019-2020 Matteo Schiff
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.underdesk.circolapp.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.ResolveInfo
|
||||
import android.net.Uri
|
||||
|
||||
object CustomTabsHelper {
|
||||
private const val ACTION_CUSTOM_TABS_CONNECTION =
|
||||
"android.support.customtabs.action.CustomTabsService"
|
||||
|
||||
fun getPreferredCustomTabsPackage(context: Context): String {
|
||||
val packages = getCustomTabsPackages(context)
|
||||
|
||||
return if (packages.isEmpty()) "com.android.chrome" else packages[0].activityInfo.packageName
|
||||
}
|
||||
|
||||
private fun getCustomTabsPackages(context: Context): ArrayList<ResolveInfo> {
|
||||
val pm = context.packageManager
|
||||
// Get default VIEW intent handler.
|
||||
val activityIntent = Intent()
|
||||
.setAction(Intent.ACTION_VIEW)
|
||||
.addCategory(Intent.CATEGORY_BROWSABLE)
|
||||
.setData(Uri.fromParts("http", "", null))
|
||||
|
||||
// Get all apps that can handle VIEW intents.
|
||||
val resolvedActivityList = pm.queryIntentActivities(activityIntent, 0)
|
||||
val packagesSupportingCustomTabs: ArrayList<ResolveInfo> = ArrayList()
|
||||
for (info in resolvedActivityList) {
|
||||
val serviceIntent = Intent()
|
||||
serviceIntent.action = ACTION_CUSTOM_TABS_CONNECTION
|
||||
serviceIntent.setPackage(info.activityInfo.packageName)
|
||||
if (pm.resolveService(serviceIntent, 0) != null) {
|
||||
packagesSupportingCustomTabs.add(info)
|
||||
}
|
||||
}
|
||||
return packagesSupportingCustomTabs
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,12 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.browser.customtabs.CustomTabColorSchemeParams
|
||||
import androidx.browser.customtabs.CustomTabsIntent.*
|
||||
import androidx.browser.customtabs.CustomTabsService
|
||||
import androidx.browser.customtabs.CustomTabsSession
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
@@ -16,7 +19,7 @@ import net.underdesk.circolapp.R
|
||||
import net.underdesk.circolapp.adapters.CircularLetterAdapter
|
||||
|
||||
object FileUtils {
|
||||
fun viewFile(url: String, context: Context) {
|
||||
fun viewFile(url: String, context: Context, session: CustomTabsSession?) {
|
||||
if (url.endsWith(".pdf")) {
|
||||
val viewIntent = Intent(Intent.ACTION_VIEW)
|
||||
viewIntent.setDataAndType(Uri.parse(url), "application/pdf")
|
||||
@@ -46,7 +49,7 @@ object FileUtils {
|
||||
.setToolbarColor(primaryColor)
|
||||
.build()
|
||||
|
||||
val customTabsIntent = Builder()
|
||||
val customTabsIntent = Builder(session)
|
||||
.setShowTitle(true)
|
||||
.setColorScheme(COLOR_SCHEME_SYSTEM)
|
||||
.setDefaultColorSchemeParams(otherParams)
|
||||
@@ -57,6 +60,24 @@ object FileUtils {
|
||||
}
|
||||
}
|
||||
|
||||
fun preloadFiles(url: String, otherUrls: List<String>, session: CustomTabsSession?) {
|
||||
if (!url.endsWith(".pdf")) {
|
||||
val bundles = arrayListOf<Bundle>()
|
||||
|
||||
for (otherUrl in otherUrls) {
|
||||
if (!url.endsWith(".pdf")) {
|
||||
val bundle = Bundle().apply {
|
||||
putParcelable(CustomTabsService.KEY_URL, Uri.parse(otherUrl))
|
||||
}
|
||||
|
||||
bundles.add(bundle)
|
||||
}
|
||||
}
|
||||
|
||||
session?.mayLaunchUrl(Uri.parse(url), null, bundles)
|
||||
}
|
||||
}
|
||||
|
||||
fun shareFile(url: String, context: Context) {
|
||||
val sendIntent: Intent = Intent().apply {
|
||||
action = Intent.ACTION_SEND
|
||||
|
||||
Reference in New Issue
Block a user