feat: replace direct player with web browser for search results
- Add BrowserActivity with WebView, toolbar (back/forward/close), URL bar, progress bar - SearchFragment: open BrowserActivity instead of PlayerActivity on result click - Browser allows user to browse the video site directly before choosing to play
This commit is contained in:
@@ -34,6 +34,11 @@
|
|||||||
android:name=".SettingsActivity"
|
android:name=".SettingsActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".BrowserActivity"
|
||||||
|
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||||
|
android:exported="false" />
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
123
app/src/main/java/com/videoapp/tv/BrowserActivity.kt
Normal file
123
app/src/main/java/com/videoapp/tv/BrowserActivity.kt
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
package com.videoapp.tv
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.KeyEvent
|
||||||
|
import android.view.View
|
||||||
|
import android.webkit.WebChromeClient
|
||||||
|
import android.webkit.WebSettings
|
||||||
|
import android.webkit.WebView
|
||||||
|
import android.webkit.WebViewClient
|
||||||
|
import android.widget.ImageButton
|
||||||
|
import android.widget.ProgressBar
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
|
||||||
|
class BrowserActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
private lateinit var webView: WebView
|
||||||
|
private lateinit var progressBar: ProgressBar
|
||||||
|
private lateinit var tvUrl: TextView
|
||||||
|
private lateinit var btnBack: ImageButton
|
||||||
|
private lateinit var btnForward: ImageButton
|
||||||
|
private lateinit var btnClose: ImageButton
|
||||||
|
|
||||||
|
@SuppressLint("SetJavaScriptEnabled")
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_browser)
|
||||||
|
|
||||||
|
webView = findViewById(R.id.browser_webview)
|
||||||
|
progressBar = findViewById(R.id.browser_progress)
|
||||||
|
tvUrl = findViewById(R.id.tv_url)
|
||||||
|
btnBack = findViewById(R.id.btn_back_browser)
|
||||||
|
btnForward = findViewById(R.id.btn_forward_browser)
|
||||||
|
btnClose = findViewById(R.id.btn_close_browser)
|
||||||
|
|
||||||
|
val url = intent.getStringExtra("url") ?: ""
|
||||||
|
val title = intent.getStringExtra("title") ?: ""
|
||||||
|
supportActionBar?.title = title
|
||||||
|
|
||||||
|
setupWebView()
|
||||||
|
setupListeners()
|
||||||
|
|
||||||
|
if (url.isNotEmpty()) {
|
||||||
|
webView.loadUrl(url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetJavaScriptEnabled")
|
||||||
|
private fun setupWebView() {
|
||||||
|
webView.settings.apply {
|
||||||
|
javaScriptEnabled = true
|
||||||
|
domStorageEnabled = true
|
||||||
|
mediaPlaybackRequiresUserGesture = false
|
||||||
|
allowFileAccess = true
|
||||||
|
allowContentAccess = true
|
||||||
|
useWideViewPort = true
|
||||||
|
loadWithOverviewMode = true
|
||||||
|
setSupportZoom(true)
|
||||||
|
builtInZoomControls = true
|
||||||
|
displayZoomControls = false
|
||||||
|
mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
|
||||||
|
cacheMode = WebSettings.LOAD_DEFAULT
|
||||||
|
}
|
||||||
|
|
||||||
|
webView.webViewClient = object : WebViewClient() {
|
||||||
|
override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) {
|
||||||
|
super.onPageStarted(view, url, favicon)
|
||||||
|
tvUrl.text = url
|
||||||
|
progressBar.visibility = View.VISIBLE
|
||||||
|
updateNavButtons()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPageFinished(view: WebView, url: String) {
|
||||||
|
super.onPageFinished(view, url)
|
||||||
|
tvUrl.text = url
|
||||||
|
progressBar.visibility = View.GONE
|
||||||
|
updateNavButtons()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated("Deprecated in Java")
|
||||||
|
override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
|
||||||
|
view.loadUrl(url)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
webView.webChromeClient = object : WebChromeClient() {
|
||||||
|
override fun onProgressChanged(view: WebView, newProgress: Int) {
|
||||||
|
progressBar.progress = newProgress
|
||||||
|
if (newProgress == 100) {
|
||||||
|
progressBar.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupListeners() {
|
||||||
|
btnBack.setOnClickListener {
|
||||||
|
if (webView.canGoBack()) webView.goBack()
|
||||||
|
}
|
||||||
|
|
||||||
|
btnForward.setOnClickListener {
|
||||||
|
if (webView.canGoForward()) webView.goForward()
|
||||||
|
}
|
||||||
|
|
||||||
|
btnClose.setOnClickListener { finish() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateNavButtons() {
|
||||||
|
btnBack.alpha = if (webView.canGoBack()) 1.0f else 0.4f
|
||||||
|
btnForward.alpha = if (webView.canGoForward()) 1.0f else 0.4f
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
|
||||||
|
if (keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) {
|
||||||
|
webView.goBack()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return super.onKeyDown(keyCode, event)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,7 +19,7 @@ import androidx.lifecycle.lifecycleScope
|
|||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.videoapp.tv.R
|
import com.videoapp.tv.R
|
||||||
import com.videoapp.tv.PlayerActivity
|
import com.videoapp.tv.BrowserActivity
|
||||||
import com.videoapp.tv.SettingsActivity
|
import com.videoapp.tv.SettingsActivity
|
||||||
import com.videoapp.tv.data.AppDatabase
|
import com.videoapp.tv.data.AppDatabase
|
||||||
import com.videoapp.tv.data.SearchHistory
|
import com.videoapp.tv.data.SearchHistory
|
||||||
@@ -185,10 +185,9 @@ class SearchFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun openPlayer(result: SearchResult) {
|
private fun openPlayer(result: SearchResult) {
|
||||||
val intent = Intent(requireContext(), PlayerActivity::class.java).apply {
|
val intent = Intent(requireContext(), BrowserActivity::class.java).apply {
|
||||||
putExtra("detail_url", result.detailUrl)
|
putExtra("url", result.detailUrl)
|
||||||
putExtra("title", result.title)
|
putExtra("title", result.title)
|
||||||
putExtra("category", result.category)
|
|
||||||
}
|
}
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|||||||
72
app/src/main/res/layout/activity_browser.xml
Normal file
72
app/src/main/res/layout/activity_browser.xml
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
<?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="vertical"
|
||||||
|
android:background="@color/background">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:background="@color/surface"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingStart="8dp"
|
||||||
|
android:paddingEnd="8dp">
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/btn_back_browser"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:src="@android:drawable/ic_menu_revert"
|
||||||
|
android:scaleType="centerInside"
|
||||||
|
android:contentDescription="后退" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/btn_forward_browser"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:src="@android:drawable/ic_media_ff"
|
||||||
|
android:scaleType="centerInside"
|
||||||
|
android:contentDescription="前进" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_url"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:paddingStart="8dp"
|
||||||
|
android:paddingEnd="8dp"
|
||||||
|
android:textColor="@color/text_secondary"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/btn_close_browser"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:src="@android:drawable/ic_menu_close_clear_cancel"
|
||||||
|
android:scaleType="centerInside"
|
||||||
|
android:contentDescription="@string/back" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/browser_progress"
|
||||||
|
style="?android:attr/progressBarStyleHorizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="3dp"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<WebView
|
||||||
|
android:id="@+id/browser_webview"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
Reference in New Issue
Block a user