Commit e72b6f74ca8ca0dd30c77b07a812712e092cdea0

Authored by 简柏林
0 parents

首次提交

Showing 45 changed files with 1401 additions and 0 deletions
  1 +*.iml
  2 +.gradle
  3 +/local.properties
  4 +/.idea/caches
  5 +/.idea/libraries
  6 +/.idea/modules.xml
  7 +/.idea/workspace.xml
  8 +/.idea/navEditor.xml
  9 +/.idea/assetWizardSettings.xml
  10 +.DS_Store
  11 +/build
  12 +/captures
  13 +.externalNativeBuild
  14 +.cxx
  15 +local.properties
... ...
  1 +# Default ignored files
  2 +/shelf/
  3 +/workspace.xml
... ...
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project version="4">
  3 + <component name="CompilerConfiguration">
  4 + <bytecodeTargetLevel target="11" />
  5 + </component>
  6 +</project>
\ No newline at end of file
... ...
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project version="4">
  3 + <component name="GradleMigrationSettings" migrationVersion="1" />
  4 + <component name="GradleSettings">
  5 + <option name="linkedExternalProjectsSettings">
  6 + <GradleProjectSettings>
  7 + <option name="testRunner" value="GRADLE" />
  8 + <option name="distributionType" value="DEFAULT_WRAPPED" />
  9 + <option name="externalProjectPath" value="$PROJECT_DIR$" />
  10 + <option name="modules">
  11 + <set>
  12 + <option value="$PROJECT_DIR$" />
  13 + <option value="$PROJECT_DIR$/app" />
  14 + </set>
  15 + </option>
  16 + </GradleProjectSettings>
  17 + </option>
  18 + </component>
  19 +</project>
\ No newline at end of file
... ...
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project version="4">
  3 + <component name="DesignSurface">
  4 + <option name="filePathToZoomLevelMap">
  5 + <map>
  6 + <entry key="..\:/jbl/workspace/android/bigScreem/app/src/main/res/drawable/default_background.xml" value="0.1" />
  7 + <entry key="..\:/jbl/workspace/android/bigScreem/app/src/main/res/layout/activity_details.xml" value="0.24010416666666667" />
  8 + <entry key="..\:/jbl/workspace/android/bigScreem/app/src/main/res/layout/activity_main.xml" value="0.2546875" />
  9 + </map>
  10 + </option>
  11 + </component>
  12 + <component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="Android Studio default JDK" project-jdk-type="JavaSDK">
  13 + <output url="file://$PROJECT_DIR$/build/classes" />
  14 + </component>
  15 + <component name="ProjectType">
  16 + <option name="id" value="Android" />
  17 + </component>
  18 +</project>
\ No newline at end of file
... ...
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project version="4">
  3 + <component name="VcsDirectoryMappings">
  4 + <mapping directory="$PROJECT_DIR$" vcs="Git" />
  5 + </component>
  6 +</project>
\ No newline at end of file
... ...
No preview for this file type
  1 +/build
\ No newline at end of file
... ...
  1 +plugins {
  2 + id 'com.android.application'
  3 + id 'org.jetbrains.kotlin.android'
  4 +}
  5 +
  6 +android {
  7 + compileSdk 32
  8 +
  9 + defaultConfig {
  10 + applicationId "com.apaas.bigscreem"
  11 + minSdk 28
  12 + targetSdk 32
  13 + versionCode 1
  14 + versionName "1.0"
  15 +
  16 + }
  17 +
  18 + signingConfigs {
  19 + config {
  20 + storeFile file('./AppSignature.jks')
  21 + storePassword '123456'
  22 + keyAlias 'study'
  23 + keyPassword '123456'
  24 + v1SigningEnabled true
  25 + v2SigningEnabled true
  26 + }
  27 + release {
  28 + storeFile file('./AppSignature.jks')
  29 + storePassword '123456'
  30 + keyAlias 'study'
  31 + keyPassword '123456'
  32 + v1SigningEnabled true
  33 + v2SigningEnabled false
  34 + }
  35 + }
  36 +
  37 + buildTypes {
  38 + release {
  39 + debuggable false
  40 + jniDebuggable false
  41 + // 压缩对齐开关
  42 + zipAlignEnabled true
  43 + // 签名信息配置
  44 + signingConfig signingConfigs.release
  45 + // 添加清单占位符
  46 + addManifestPlaceholders([
  47 + 'app_name': '@string/app_name'
  48 + ])
  49 + minifyEnabled false
  50 + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
  51 + }
  52 + }
  53 +}
  54 +
  55 +dependencies {
  56 +
  57 + implementation 'androidx.core:core-ktx:1.7.0'
  58 + implementation 'androidx.leanback:leanback:1.0.0'
  59 + implementation 'com.github.bumptech.glide:glide:4.11.0'
  60 + implementation 'androidx.browser:browser:1.3.0'
  61 +}
\ No newline at end of file
... ...
  1 +# Add project specific ProGuard rules here.
  2 +# You can control the set of applied configuration files using the
  3 +# proguardFiles setting in build.gradle.
  4 +#
  5 +# For more details, see
  6 +# http://developer.android.com/guide/developing/tools/proguard.html
  7 +
  8 +# If your project uses WebView with JS, uncomment the following
  9 +# and specify the fully qualified class name to the JavaScript interface
  10 +# class:
  11 +#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
  12 +# public *;
  13 +#}
  14 +
  15 +# Uncomment this to preserve the line number information for
  16 +# debugging stack traces.
  17 +#-keepattributes SourceFile,LineNumberTable
  18 +
  19 +# If you keep the line number information, uncomment this to
  20 +# hide the original source file name.
  21 +#-renamesourcefileattribute SourceFile
\ No newline at end of file
... ...
No preview for this file type
  1 +{
  2 + "version": 3,
  3 + "artifactType": {
  4 + "type": "APK",
  5 + "kind": "Directory"
  6 + },
  7 + "applicationId": "com.apaas.bigscreem",
  8 + "variantName": "release",
  9 + "elements": [
  10 + {
  11 + "type": "SINGLE",
  12 + "filters": [],
  13 + "attributes": [],
  14 + "versionCode": 1,
  15 + "versionName": "1.0",
  16 + "outputFile": "app-release.apk"
  17 + }
  18 + ],
  19 + "elementType": "File"
  20 +}
\ No newline at end of file
... ...
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3 + xmlns:tools="http://schemas.android.com/tools"
  4 + package="com.apaas.bigscreem"
  5 + tools:ignore="MissingLeanbackLauncher">
  6 +
  7 + <uses-permission android:name="android.permission.INTERNET" />
  8 +
  9 + <uses-feature
  10 + android:name="android.hardware.touchscreen"
  11 + android:required="false" />
  12 + <uses-feature
  13 + android:name="android.software.leanback"
  14 + android:required="true" />
  15 +
  16 + <application
  17 + android:allowBackup="true"
  18 + android:icon="@mipmap/ic_launcher"
  19 + android:label="@string/app_name"
  20 + android:supportsRtl="true"
  21 + android:theme="@style/Theme.BigScreem">
  22 + <activity
  23 + android:name=".MainActivity"
  24 + android:banner="@drawable/app_icon_your_company"
  25 + android:exported="true"
  26 + android:icon="@drawable/app_icon_your_company"
  27 + android:label="@string/app_name"
  28 + android:logo="@drawable/app_icon_your_company"
  29 + android:screenOrientation="landscape">
  30 + <intent-filter>
  31 + <action android:name="android.intent.action.MAIN" />
  32 +
  33 + <category android:name="android.intent.category.LAUNCHER" />
  34 + </intent-filter>
  35 + </activity>
  36 + <activity
  37 + android:name=".DetailsActivity"
  38 + android:screenOrientation="landscape"
  39 + android:exported="false" />
  40 + <activity
  41 + android:name=".PlaybackActivity"
  42 + android:exported="false" />
  43 + <activity
  44 + android:name=".BrowseErrorActivity"
  45 + android:exported="false" />
  46 + </application>
  47 +
  48 +</manifest>
\ No newline at end of file
... ...
  1 +package com.apaas.bigscreem
  2 +
  3 +import android.os.Bundle
  4 +import android.os.Handler
  5 +import android.os.Looper
  6 +import android.view.Gravity
  7 +import android.view.LayoutInflater
  8 +import android.view.View
  9 +import android.view.ViewGroup
  10 +import android.widget.FrameLayout
  11 +import android.widget.ProgressBar
  12 +import androidx.fragment.app.Fragment
  13 +import androidx.fragment.app.FragmentActivity
  14 +
  15 +/**
  16 + * BrowseErrorActivity shows how to use ErrorFragment.
  17 + */
  18 +class BrowseErrorActivity : FragmentActivity() {
  19 +
  20 + private lateinit var mErrorFragment: ErrorFragment
  21 + private lateinit var mSpinnerFragment: SpinnerFragment
  22 +
  23 + override fun onCreate(savedInstanceState: Bundle?) {
  24 + super.onCreate(savedInstanceState)
  25 + setContentView(R.layout.activity_main)
  26 + if (savedInstanceState == null) {
  27 + getSupportFragmentManager().beginTransaction()
  28 + .replace(R.id.main_browse_fragment, MainFragment())
  29 + .commitNow()
  30 + }
  31 + testError()
  32 + }
  33 +
  34 + private fun testError() {
  35 + mErrorFragment = ErrorFragment()
  36 + supportFragmentManager
  37 + .beginTransaction()
  38 + .add(R.id.main_browse_fragment, mErrorFragment)
  39 + .commit()
  40 +
  41 + mSpinnerFragment = SpinnerFragment()
  42 + supportFragmentManager
  43 + .beginTransaction()
  44 + .add(R.id.main_browse_fragment, mSpinnerFragment)
  45 + .commit()
  46 +
  47 + val handler = Handler(Looper.myLooper()!!)
  48 + handler.postDelayed({
  49 + supportFragmentManager
  50 + .beginTransaction()
  51 + .remove(mSpinnerFragment)
  52 + .commit()
  53 + mErrorFragment.setErrorContent()
  54 + }, TIMER_DELAY)
  55 + }
  56 +
  57 + class SpinnerFragment : Fragment() {
  58 + override fun onCreateView(
  59 + inflater: LayoutInflater, container: ViewGroup?,
  60 + savedInstanceState: Bundle?
  61 + ): View? {
  62 + val progressBar = ProgressBar(container?.context)
  63 + if (container is FrameLayout) {
  64 + val layoutParams =
  65 + FrameLayout.LayoutParams(SPINNER_WIDTH, SPINNER_HEIGHT, Gravity.CENTER)
  66 + progressBar.layoutParams = layoutParams
  67 + }
  68 + return progressBar
  69 + }
  70 + }
  71 +
  72 + companion object {
  73 + private val TIMER_DELAY = 3000L
  74 + private val SPINNER_WIDTH = 100
  75 + private val SPINNER_HEIGHT = 100
  76 + }
  77 +}
\ No newline at end of file
... ...
  1 +package com.apaas.bigscreem
  2 +
  3 +import android.graphics.drawable.Drawable
  4 +import androidx.leanback.widget.ImageCardView
  5 +import androidx.leanback.widget.Presenter
  6 +import androidx.core.content.ContextCompat
  7 +import android.util.Log
  8 +import android.view.ViewGroup
  9 +
  10 +import com.bumptech.glide.Glide
  11 +import kotlin.properties.Delegates
  12 +
  13 +/**
  14 + * A CardPresenter is used to generate Views and bind Objects to them on demand.
  15 + * It contains an ImageCardView.
  16 + */
  17 +class CardPresenter : Presenter() {
  18 + private var mDefaultCardImage: Drawable? = null
  19 + private var sSelectedBackgroundColor: Int by Delegates.notNull()
  20 + private var sDefaultBackgroundColor: Int by Delegates.notNull()
  21 +
  22 + override fun onCreateViewHolder(parent: ViewGroup): Presenter.ViewHolder {
  23 + Log.d(TAG, "onCreateViewHolder")
  24 +
  25 + sDefaultBackgroundColor = ContextCompat.getColor(parent.context, R.color.default_background)
  26 + sSelectedBackgroundColor =
  27 + ContextCompat.getColor(parent.context, R.color.selected_background)
  28 + mDefaultCardImage = ContextCompat.getDrawable(parent.context, R.drawable.movie)
  29 +
  30 + val cardView = object : ImageCardView(parent.context) {
  31 + override fun setSelected(selected: Boolean) {
  32 + updateCardBackgroundColor(this, selected)
  33 + super.setSelected(selected)
  34 + }
  35 + }
  36 +
  37 + cardView.isFocusable = true
  38 + cardView.isFocusableInTouchMode = true
  39 + updateCardBackgroundColor(cardView, false)
  40 + return Presenter.ViewHolder(cardView)
  41 + }
  42 +
  43 + override fun onBindViewHolder(viewHolder: Presenter.ViewHolder, item: Any) {
  44 + val movie = item as Movie
  45 + val cardView = viewHolder.view as ImageCardView
  46 +
  47 + Log.d(TAG, "onBindViewHolder")
  48 + if (movie.cardImageUrl != null) {
  49 + cardView.titleText = movie.title
  50 + cardView.contentText = movie.studio
  51 + cardView.setMainImageDimensions(CARD_WIDTH, CARD_HEIGHT)
  52 + Glide.with(viewHolder.view.context)
  53 + .load(movie.cardImageUrl)
  54 + .centerCrop()
  55 + .error(mDefaultCardImage)
  56 + .into(cardView.mainImageView)
  57 + }
  58 + }
  59 +
  60 + override fun onUnbindViewHolder(viewHolder: Presenter.ViewHolder) {
  61 + Log.d(TAG, "onUnbindViewHolder")
  62 + val cardView = viewHolder.view as ImageCardView
  63 + // Remove references to images so that the garbage collector can free up memory
  64 + cardView.badgeImage = null
  65 + cardView.mainImage = null
  66 + }
  67 +
  68 + private fun updateCardBackgroundColor(view: ImageCardView, selected: Boolean) {
  69 + val color = if (selected) sSelectedBackgroundColor else sDefaultBackgroundColor
  70 + // Both background colors should be set because the view"s background is temporarily visible
  71 + // during animations.
  72 + view.setBackgroundColor(color)
  73 + view.setInfoAreaBackgroundColor(color)
  74 + }
  75 +
  76 + companion object {
  77 + private val TAG = "CardPresenter"
  78 +
  79 + private val CARD_WIDTH = 313
  80 + private val CARD_HEIGHT = 176
  81 + }
  82 +}
\ No newline at end of file
... ...
  1 +package com.apaas.bigscreem
  2 +
  3 +import android.os.Build
  4 +import android.os.Bundle
  5 +import android.os.Handler
  6 +import android.view.View
  7 +import android.view.WindowInsets
  8 +import android.view.WindowInsetsController
  9 +import android.webkit.WebView
  10 +import android.webkit.WebViewClient
  11 +import androidx.fragment.app.FragmentActivity
  12 +
  13 +
  14 +/**
  15 + * Details activity class that loads [VideoDetailsFragment] class.
  16 + */
  17 +class DetailsActivity : FragmentActivity() {
  18 +
  19 + private var mSelectedMovie: Movie? = null
  20 + private val handler = Handler()
  21 + private lateinit var mWebView: WebView
  22 + override fun onCreate(savedInstanceState: Bundle?) {
  23 + super.onCreate(savedInstanceState)
  24 + setContentView(R.layout.activity_details)
  25 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
  26 + window.setDecorFitsSystemWindows(false)
  27 + window.insetsController?.let {
  28 + it.hide(WindowInsets.Type.statusBars() or WindowInsets.Type.navigationBars())
  29 + it.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
  30 + }
  31 + } else {
  32 + @Suppress("DEPRECATION")
  33 + window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_FULLSCREEN
  34 + or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
  35 + or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
  36 + or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
  37 + or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
  38 + or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)
  39 + }
  40 +
  41 + mSelectedMovie = intent.getSerializableExtra(MOVIE) as Movie
  42 + if (mSelectedMovie != null) {
  43 + mWebView = findViewById(R.id.webView)
  44 + // 启用JavaScript
  45 +
  46 + mWebView.settings.javaScriptEnabled = true // 启用JavaScript
  47 +
  48 + mWebView.settings.setUserAgentString("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36") // 设置用户代理为桌面浏览器的样子
  49 +
  50 + mWebView.webViewClient = WebViewClient() // 处理点击链接的方式
  51 +
  52 + // 设置WebChromeClient来处理JavaScript的对话框、网页标题等
  53 +
  54 + mSelectedMovie!!.webUrl?.let { mWebView.loadUrl(it) }
  55 + }
  56 +
  57 + val refreshInterval = 43200000L
  58 +// val refreshInterval = 5000L
  59 + // 使用Handler定时刷新WebView
  60 + handler.postDelayed(object : Runnable {
  61 + override fun run() {
  62 + mWebView.reload()
  63 + // 递归调用自身实现定时刷新
  64 + handler.postDelayed(this, refreshInterval)
  65 + }
  66 + }, refreshInterval)
  67 + }
  68 +
  69 + companion object {
  70 + const val SHARED_ELEMENT_NAME = "hero"
  71 + const val MOVIE = "Movie"
  72 + }
  73 +
  74 + override fun onDestroy() {
  75 + super.onDestroy()
  76 + // 清理资源,移除所有回调
  77 + handler.removeCallbacksAndMessages(null)
  78 + }
  79 +}
\ No newline at end of file
... ...
  1 +package com.apaas.bigscreem
  2 +
  3 +import androidx.leanback.widget.AbstractDetailsDescriptionPresenter
  4 +
  5 +class DetailsDescriptionPresenter : AbstractDetailsDescriptionPresenter() {
  6 +
  7 + override fun onBindDescription(
  8 + viewHolder: AbstractDetailsDescriptionPresenter.ViewHolder,
  9 + item: Any
  10 + ) {
  11 + val movie = item as Movie
  12 +
  13 + viewHolder.title.text = movie.title
  14 + viewHolder.subtitle.text = movie.studio
  15 + viewHolder.body.text = movie.description
  16 + }
  17 +}
\ No newline at end of file
... ...
  1 +package com.apaas.bigscreem
  2 +
  3 +import android.os.Bundle
  4 +import android.view.View
  5 +
  6 +import androidx.core.content.ContextCompat
  7 +import androidx.leanback.app.ErrorSupportFragment
  8 +
  9 +/**
  10 + * This class demonstrates how to extend [ErrorSupportFragment].
  11 + */
  12 +class ErrorFragment : ErrorSupportFragment() {
  13 +
  14 + override fun onCreate(savedInstanceState: Bundle?) {
  15 + super.onCreate(savedInstanceState)
  16 + title = resources.getString(R.string.app_name)
  17 + }
  18 +
  19 + internal fun setErrorContent() {
  20 + imageDrawable =
  21 + ContextCompat.getDrawable(context!!, androidx.leanback.R.drawable.lb_ic_sad_cloud)
  22 + message = resources.getString(R.string.error_fragment_message)
  23 + setDefaultBackground(TRANSLUCENT)
  24 +
  25 + buttonText = resources.getString(R.string.dismiss_error)
  26 + buttonClickListener = View.OnClickListener {
  27 + fragmentManager!!.beginTransaction().remove(this@ErrorFragment).commit()
  28 + }
  29 + }
  30 +
  31 + companion object {
  32 + private val TRANSLUCENT = true
  33 + }
  34 +}
\ No newline at end of file
... ...
  1 +package com.apaas.bigscreem
  2 +
  3 +import android.os.Bundle
  4 +import androidx.fragment.app.FragmentActivity
  5 +
  6 +/**
  7 + * Loads [MainFragment].
  8 + */
  9 +class MainActivity : FragmentActivity() {
  10 +
  11 + override fun onCreate(savedInstanceState: Bundle?) {
  12 + super.onCreate(savedInstanceState)
  13 + setContentView(R.layout.activity_main)
  14 + if (savedInstanceState == null) {
  15 + getSupportFragmentManager().beginTransaction()
  16 + .replace(R.id.main_browse_fragment, MainFragment())
  17 + .commitNow()
  18 + }
  19 + }
  20 +}
\ No newline at end of file
... ...
  1 +package com.apaas.bigscreem
  2 +
  3 +import java.util.Collections
  4 +import java.util.Timer
  5 +import java.util.TimerTask
  6 +
  7 +import android.content.Intent
  8 +import android.graphics.Color
  9 +import android.graphics.drawable.Drawable
  10 +import android.os.Bundle
  11 +import android.os.Handler
  12 +import android.os.Looper
  13 +import androidx.leanback.app.BackgroundManager
  14 +import androidx.leanback.app.BrowseSupportFragment
  15 +import androidx.leanback.widget.ArrayObjectAdapter
  16 +import androidx.leanback.widget.HeaderItem
  17 +import androidx.leanback.widget.ImageCardView
  18 +import androidx.leanback.widget.ListRow
  19 +import androidx.leanback.widget.ListRowPresenter
  20 +import androidx.leanback.widget.OnItemViewClickedListener
  21 +import androidx.leanback.widget.OnItemViewSelectedListener
  22 +import androidx.leanback.widget.Presenter
  23 +import androidx.leanback.widget.Row
  24 +import androidx.leanback.widget.RowPresenter
  25 +import androidx.core.app.ActivityOptionsCompat
  26 +import androidx.core.content.ContextCompat
  27 +import android.util.DisplayMetrics
  28 +import android.util.Log
  29 +import android.view.Gravity
  30 +import android.view.ViewGroup
  31 +import android.widget.TextView
  32 +import android.widget.Toast
  33 +
  34 +import com.bumptech.glide.Glide
  35 +import com.bumptech.glide.request.target.SimpleTarget
  36 +import com.bumptech.glide.request.transition.Transition
  37 +
  38 +/**
  39 + * Loads a grid of cards with movies to browse.
  40 + */
  41 +class MainFragment : BrowseSupportFragment() {
  42 +
  43 + private val mHandler = Handler(Looper.myLooper()!!)
  44 + private lateinit var mBackgroundManager: BackgroundManager
  45 + private var mDefaultBackground: Drawable? = null
  46 + private lateinit var mMetrics: DisplayMetrics
  47 + private var mBackgroundTimer: Timer? = null
  48 + private var mBackgroundUri: String? = null
  49 +
  50 + override fun onActivityCreated(savedInstanceState: Bundle?) {
  51 + Log.i(TAG, "onCreate")
  52 + super.onActivityCreated(savedInstanceState)
  53 +
  54 + prepareBackgroundManager()
  55 +
  56 + setupUIElements()
  57 +
  58 + loadRows()
  59 +
  60 + setupEventListeners()
  61 + }
  62 +
  63 + override fun onDestroy() {
  64 + super.onDestroy()
  65 + Log.d(TAG, "onDestroy: " + mBackgroundTimer?.toString())
  66 + mBackgroundTimer?.cancel()
  67 + }
  68 +
  69 + private fun prepareBackgroundManager() {
  70 +
  71 + mBackgroundManager = BackgroundManager.getInstance(activity)
  72 + mBackgroundManager.attach(activity!!.window)
  73 + mDefaultBackground = ContextCompat.getDrawable(context!!, R.drawable.default_background)
  74 + mMetrics = DisplayMetrics()
  75 + activity!!.windowManager.defaultDisplay.getMetrics(mMetrics)
  76 + }
  77 +
  78 + private fun setupUIElements() {
  79 + title = getString(R.string.browse_title)
  80 + // over title
  81 + headersState = BrowseSupportFragment.HEADERS_ENABLED
  82 + isHeadersTransitionOnBackEnabled = true
  83 +
  84 + // set fastLane (or headers) background color
  85 + brandColor = ContextCompat.getColor(context!!, R.color.fastlane_background)
  86 + // set search icon color
  87 + searchAffordanceColor = ContextCompat.getColor(context!!, R.color.search_opaque)
  88 + }
  89 +
  90 + private fun loadRows() {
  91 + val list = MovieList.list
  92 +
  93 + val rowsAdapter = ArrayObjectAdapter(ListRowPresenter())
  94 + val cardPresenter = CardPresenter()
  95 +
  96 + for (i in 0 until NUM_ROWS) {
  97 + if (i != 0) {
  98 + Collections.shuffle(list)
  99 + }
  100 + val listRowAdapter = ArrayObjectAdapter(cardPresenter)
  101 + for (j in 0 until NUM_COLS) {
  102 + listRowAdapter.add(list[j])
  103 + }
  104 + val header = HeaderItem(i.toLong(), MovieList.MOVIE_CATEGORY[i])
  105 + rowsAdapter.add(ListRow(header, listRowAdapter))
  106 + }
  107 +
  108 + val gridHeader = HeaderItem(NUM_ROWS.toLong(), "其他")
  109 +
  110 + val mGridPresenter = GridItemPresenter()
  111 + val gridRowAdapter = ArrayObjectAdapter(mGridPresenter)
  112 + gridRowAdapter.add(resources.getString(R.string.grid_view))
  113 + gridRowAdapter.add(getString(R.string.error_fragment))
  114 + gridRowAdapter.add(resources.getString(R.string.personal_settings))
  115 + rowsAdapter.add(ListRow(gridHeader, gridRowAdapter))
  116 +
  117 + adapter = rowsAdapter
  118 + }
  119 +
  120 + private fun setupEventListeners() {
  121 + setOnSearchClickedListener {
  122 + Toast.makeText(context!!, "Implement your own in-app search", Toast.LENGTH_LONG)
  123 + .show()
  124 + }
  125 +
  126 + onItemViewClickedListener = ItemViewClickedListener()
  127 + onItemViewSelectedListener = ItemViewSelectedListener()
  128 + }
  129 +
  130 + private inner class ItemViewClickedListener : OnItemViewClickedListener {
  131 + override fun onItemClicked(
  132 + itemViewHolder: Presenter.ViewHolder,
  133 + item: Any,
  134 + rowViewHolder: RowPresenter.ViewHolder,
  135 + row: Row
  136 + ) {
  137 +
  138 + if (item is Movie) {
  139 + Log.d(TAG, "Item: " + item.toString())
  140 + val intent = Intent(context!!, DetailsActivity::class.java)
  141 + intent.putExtra(DetailsActivity.MOVIE, item)
  142 +
  143 + val bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(
  144 + activity!!,
  145 + (itemViewHolder.view as ImageCardView).mainImageView,
  146 + DetailsActivity.SHARED_ELEMENT_NAME
  147 + )
  148 + .toBundle()
  149 + startActivity(intent, bundle)
  150 + } else if (item is String) {
  151 + if (item.contains(getString(R.string.error_fragment))) {
  152 + val intent = Intent(context!!, BrowseErrorActivity::class.java)
  153 + startActivity(intent)
  154 + } else {
  155 + Toast.makeText(context!!, item, Toast.LENGTH_SHORT).show()
  156 + }
  157 + }
  158 + }
  159 + }
  160 +
  161 + private inner class ItemViewSelectedListener : OnItemViewSelectedListener {
  162 + override fun onItemSelected(
  163 + itemViewHolder: Presenter.ViewHolder?, item: Any?,
  164 + rowViewHolder: RowPresenter.ViewHolder, row: Row
  165 + ) {
  166 + if (item is Movie) {
  167 + mBackgroundUri = item.backgroundImageUrl
  168 + startBackgroundTimer()
  169 + }
  170 + }
  171 + }
  172 +
  173 + private fun updateBackground(uri: String?) {
  174 + val width = mMetrics.widthPixels
  175 + val height = mMetrics.heightPixels
  176 + Glide.with(context!!)
  177 + .load(uri)
  178 + .centerCrop()
  179 + .error(mDefaultBackground)
  180 + .into<SimpleTarget<Drawable>>(
  181 + object : SimpleTarget<Drawable>(width, height) {
  182 + override fun onResourceReady(
  183 + drawable: Drawable,
  184 + transition: Transition<in Drawable>?
  185 + ) {
  186 + mBackgroundManager.drawable = drawable
  187 + }
  188 + })
  189 + mBackgroundTimer?.cancel()
  190 + }
  191 +
  192 + private fun startBackgroundTimer() {
  193 + mBackgroundTimer?.cancel()
  194 + mBackgroundTimer = Timer()
  195 + mBackgroundTimer?.schedule(UpdateBackgroundTask(), BACKGROUND_UPDATE_DELAY.toLong())
  196 + }
  197 +
  198 + private inner class UpdateBackgroundTask : TimerTask() {
  199 +
  200 + override fun run() {
  201 + mHandler.post { updateBackground(mBackgroundUri) }
  202 + }
  203 + }
  204 +
  205 + private inner class GridItemPresenter : Presenter() {
  206 + override fun onCreateViewHolder(parent: ViewGroup): Presenter.ViewHolder {
  207 + val view = TextView(parent.context)
  208 + view.layoutParams = ViewGroup.LayoutParams(GRID_ITEM_WIDTH, GRID_ITEM_HEIGHT)
  209 + view.isFocusable = true
  210 + view.isFocusableInTouchMode = true
  211 + view.setBackgroundColor(ContextCompat.getColor(context!!, R.color.default_background))
  212 + view.setTextColor(Color.WHITE)
  213 + view.gravity = Gravity.CENTER
  214 + return Presenter.ViewHolder(view)
  215 + }
  216 +
  217 + override fun onBindViewHolder(viewHolder: Presenter.ViewHolder, item: Any) {
  218 + (viewHolder.view as TextView).text = item as String
  219 + }
  220 +
  221 + override fun onUnbindViewHolder(viewHolder: Presenter.ViewHolder) {}
  222 + }
  223 +
  224 + companion object {
  225 + private val TAG = "MainFragment"
  226 +
  227 + private val BACKGROUND_UPDATE_DELAY = 300
  228 + private val GRID_ITEM_WIDTH = 200
  229 + private val GRID_ITEM_HEIGHT = 200
  230 + private val NUM_ROWS = 1
  231 + private val NUM_COLS = 11
  232 + }
  233 +}
\ No newline at end of file
... ...
  1 +package com.apaas.bigscreem
  2 +
  3 +import java.io.Serializable
  4 +
  5 +/**
  6 + * Movie class represents video entity with title, description, image thumbs and video url.
  7 + */
  8 +data class Movie(
  9 + var id: Long = 0,
  10 + var title: String? = null,
  11 + var description: String? = null,
  12 + var backgroundImageUrl: String? = null,
  13 + var cardImageUrl: String? = null,
  14 + var videoUrl: String? = null,
  15 + var studio: String? = null,
  16 + var webUrl: String? = null
  17 +) : Serializable {
  18 +
  19 + override fun toString(): String {
  20 + return "Movie{" +
  21 + "id=" + id +
  22 + ", title='" + title + '\'' +
  23 + ", webUrl='" + webUrl + '\'' +
  24 + ", backgroundImageUrl='" + backgroundImageUrl + '\'' +
  25 + ", cardImageUrl='" + cardImageUrl + '\'' +
  26 + '}'
  27 + }
  28 +
  29 + companion object {
  30 + internal const val serialVersionUID = 727566175075960653L
  31 + }
  32 +}
\ No newline at end of file
... ...
  1 +package com.apaas.bigscreem
  2 +
  3 +object MovieList {
  4 + val MOVIE_CATEGORY = arrayOf(
  5 + "华贸"
  6 + )
  7 +
  8 + val list: List<Movie> by lazy {
  9 + setupMovies()
  10 + }
  11 + private var count: Long = 0
  12 +
  13 + private fun setupMovies(): List<Movie> {
  14 + val title = arrayOf(
  15 + "党建看板",
  16 + "公司介绍",
  17 + "人员看板",
  18 + "生产入库看板",
  19 + "设备状态",
  20 + "在制品看板",
  21 + "生产进度看板",
  22 + "质量看板",
  23 + "生产计划看板",
  24 + "订单看板",
  25 + "综合看板"
  26 + )
  27 +
  28 + val description = ""
  29 + val studio = arrayOf(
  30 + "党建看板",
  31 + "公司介绍",
  32 + "人员看板",
  33 + "生产入库看板",
  34 + "设备状态",
  35 + "在制品看板",
  36 + "生产进度看板",
  37 + "质量看板",
  38 + "生产计划看板",
  39 + "订单看板",
  40 + "综合看板"
  41 + )
  42 +
  43 + val webUrl = arrayOf(
  44 + "https://mi.qgutech.com/sc/hx-hm-zhdj.html",
  45 + "https://mi.qgutech.com/sc/lx-hm-qyxc.html",
  46 + "https://mi.qgutech.com/sc/lx-hm-ryyxqk.html",
  47 + "https://mi.qgutech.com/sc/hx-hm-kcsjfx.html",
  48 + "https://mi.qgutech.com/sc/hx-hm-sbgkzx.html",
  49 + "https://mi.qgutech.com/sc/hx-hm-zjpkb.html",
  50 + "https://mi.qgutech.com/sc/hx-hm-scjdkb.html",
  51 + "https://mi.qgutech.com/sc/hx-hm-zlgkkb.html",
  52 + "https://mi.qgutech.com/sc/hx-hm-scjhkb.html",
  53 + "https://mi.qgutech.com/sc/hx-hm-xsjdkb.html",
  54 + "https://mi.qgutech.com/sc/hx-hm-kcyjkb.html",
  55 + )
  56 + val bgImageUrl = arrayOf(
  57 + "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/Zeitgeist/Zeitgeist%202010_%20Year%20in%20Review/bg.jpg",
  58 + "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/Demo%20Slam/Google%20Demo%20Slam_%2020ft%20Search/bg.jpg",
  59 + "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Gmail%20Blue/bg.jpg",
  60 + "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Google%20Fiber%20to%20the%20Pole/bg.jpg",
  61 + "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Google%20Nose/bg.jpg",
  62 + "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Google%20Nose/bg.jpg",
  63 + "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Google%20Nose/bg.jpg",
  64 + "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Google%20Nose/bg.jpg",
  65 + "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Google%20Nose/bg.jpg",
  66 + "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Google%20Nose/bg.jpg",
  67 + "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Google%20Nose/bg.jpg"
  68 + )
  69 + val cardImageUrl = arrayOf(
  70 + "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/Zeitgeist/Zeitgeist%202010_%20Year%20in%20Review/card.jpg",
  71 + "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/Demo%20Slam/Google%20Demo%20Slam_%2020ft%20Search/card.jpg",
  72 + "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Gmail%20Blue/card.jpg",
  73 + "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Google%20Fiber%20to%20the%20Pole/card.jpg",
  74 + "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Google%20Nose/card.jpg",
  75 + "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Google%20Nose/bg.jpg",
  76 + "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Google%20Nose/bg.jpg",
  77 + "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Google%20Nose/bg.jpg",
  78 + "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Google%20Nose/bg.jpg",
  79 + "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Google%20Nose/bg.jpg",
  80 + "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Google%20Nose/bg.jpg"
  81 + )
  82 +
  83 + val list = title.indices.map {
  84 + buildMovieInfo(
  85 + title[it],
  86 + description,
  87 + studio[it],
  88 + cardImageUrl[it],
  89 + bgImageUrl[it],
  90 + webUrl[it],
  91 + )
  92 + }
  93 +
  94 + return list
  95 + }
  96 +
  97 + private fun buildMovieInfo(
  98 + title: String,
  99 + description: String,
  100 + studio: String,
  101 + cardImageUrl: String,
  102 + backgroundImageUrl: String,
  103 + webUrl: String
  104 + ): Movie {
  105 + val movie = Movie()
  106 + movie.id = count++
  107 + movie.title = title
  108 + movie.description = description
  109 + movie.studio = studio
  110 + movie.cardImageUrl = cardImageUrl
  111 + movie.backgroundImageUrl = backgroundImageUrl
  112 + movie.webUrl = webUrl
  113 + return movie
  114 + }
  115 +}
\ No newline at end of file
... ...
  1 +package com.apaas.bigscreem
  2 +
  3 +import android.os.Bundle
  4 +import androidx.fragment.app.FragmentActivity
  5 +
  6 +/** Loads [PlaybackVideoFragment]. */
  7 +class PlaybackActivity : FragmentActivity() {
  8 +
  9 + override fun onCreate(savedInstanceState: Bundle?) {
  10 + super.onCreate(savedInstanceState)
  11 + if (savedInstanceState == null) {
  12 + supportFragmentManager.beginTransaction()
  13 + .replace(android.R.id.content, PlaybackVideoFragment())
  14 + .commit()
  15 + }
  16 + }
  17 +}
\ No newline at end of file
... ...
  1 +package com.apaas.bigscreem
  2 +
  3 +import android.net.Uri
  4 +import android.os.Bundle
  5 +import androidx.leanback.app.VideoSupportFragment
  6 +import androidx.leanback.app.VideoSupportFragmentGlueHost
  7 +import androidx.leanback.media.MediaPlayerAdapter
  8 +import androidx.leanback.media.PlaybackTransportControlGlue
  9 +import androidx.leanback.widget.PlaybackControlsRow
  10 +
  11 +/** Handles video playback with media controls. */
  12 +class PlaybackVideoFragment : VideoSupportFragment() {
  13 +
  14 + private lateinit var mTransportControlGlue: PlaybackTransportControlGlue<MediaPlayerAdapter>
  15 +
  16 + override fun onCreate(savedInstanceState: Bundle?) {
  17 + super.onCreate(savedInstanceState)
  18 +
  19 + val (_, title, description, _, _, videoUrl) =
  20 + activity?.intent?.getSerializableExtra(DetailsActivity.MOVIE) as Movie
  21 +
  22 + val glueHost = VideoSupportFragmentGlueHost(this@PlaybackVideoFragment)
  23 + val playerAdapter = MediaPlayerAdapter(context)
  24 + playerAdapter.setRepeatAction(PlaybackControlsRow.RepeatAction.INDEX_NONE)
  25 +
  26 + mTransportControlGlue = PlaybackTransportControlGlue(getActivity(), playerAdapter)
  27 + mTransportControlGlue.host = glueHost
  28 + mTransportControlGlue.title = title
  29 + mTransportControlGlue.subtitle = description
  30 + mTransportControlGlue.playWhenPrepared()
  31 +
  32 + playerAdapter.setDataSource(Uri.parse(videoUrl))
  33 + }
  34 +
  35 + override fun onPause() {
  36 + super.onPause()
  37 + mTransportControlGlue.pause()
  38 + }
  39 +}
\ No newline at end of file
... ...
  1 +package com.apaas.bigscreem
  2 +
  3 +import android.content.Intent
  4 +import android.os.Bundle
  5 +import android.net.Uri
  6 +import androidx.leanback.app.DetailsSupportFragment
  7 +import androidx.leanback.widget.RowPresenter
  8 +import androidx.core.app.ActivityOptionsCompat
  9 +import androidx.core.content.ContextCompat
  10 +import android.util.Log
  11 +import android.webkit.WebView
  12 +import android.widget.Toast
  13 +import androidx.browser.customtabs.CustomTabsIntent
  14 +
  15 +import com.bumptech.glide.Glide
  16 +import com.bumptech.glide.request.target.SimpleTarget
  17 +import com.bumptech.glide.request.transition.Transition
  18 +
  19 +import java.util.Collections
  20 +
  21 +/**
  22 + * A wrapper fragment for leanback details screens.
  23 + * It shows a detailed view of video and its metadata plus related videos.
  24 + */
  25 +class VideoDetailsFragment : DetailsSupportFragment() {
  26 +
  27 + private var mSelectedMovie: Movie? = null
  28 + private lateinit var mWebView: WebView
  29 +
  30 + override fun onCreate(savedInstanceState: Bundle?) {
  31 + super.onCreate(savedInstanceState)
  32 + mSelectedMovie = activity!!.intent.getSerializableExtra(DetailsActivity.MOVIE) as Movie
  33 + if (mSelectedMovie != null) {
  34 + mSelectedMovie!!.webUrl?.let { openWebPage(it) };
  35 + } else {
  36 + val intent = Intent(context!!, MainActivity::class.java)
  37 + startActivity(intent)
  38 + }
  39 + }
  40 +
  41 + fun openWebPage(url: String) {
  42 + val customTabsIntent = CustomTabsIntent.Builder().build()
  43 + activity?.let { customTabsIntent.launchUrl(it, Uri.parse(url)) }
  44 + }
  45 +}
\ No newline at end of file
... ...
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +
  3 +<shape xmlns:android="http://schemas.android.com/apk/res/android"
  4 + android:shape="rectangle">
  5 + <gradient
  6 + android:angle="-270"
  7 + android:endColor="@color/background_gradient_end"
  8 + android:startColor="@color/background_gradient_start" />
  9 +</shape>
\ No newline at end of file
... ...
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3 + xmlns:tools="http://schemas.android.com/tools"
  4 + android:id="@+id/details_fragment"
  5 + android:layout_width="match_parent"
  6 + android:layout_height="match_parent"
  7 + tools:context=".DetailsActivity"
  8 + tools:deviceIds="tv" >
  9 +
  10 + <WebView
  11 + android:id="@+id/webView"
  12 + android:layout_width="match_parent"
  13 + android:layout_height="match_parent" />
  14 +</FrameLayout>
\ No newline at end of file
... ...
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3 + xmlns:tools="http://schemas.android.com/tools"
  4 + android:id="@+id/main_browse_fragment"
  5 + android:layout_width="match_parent"
  6 + android:layout_height="match_parent"
  7 + tools:context=".MainActivity"
  8 + tools:deviceIds="tv"
  9 + tools:ignore="MergeRootFrame" >
  10 +</FrameLayout>
\ No newline at end of file
... ...
No preview for this file type
No preview for this file type
No preview for this file type
  1 +<resources>
  2 + <color name="background_gradient_start">#000000</color>
  3 + <color name="background_gradient_end">#DDDDDD</color>
  4 + <color name="fastlane_background">#0096a6</color>
  5 + <color name="search_opaque">#ffaa3f</color>
  6 + <color name="selected_background">#ffaa3f</color>
  7 + <color name="default_background">#3d3d3d</color>
  8 +</resources>
\ No newline at end of file
... ...
  1 +<resources>
  2 + <string name="app_name">bigScreem</string>
  3 + <string name="browse_title">华贸大屏展示</string>
  4 + <string name="related_movies">Related Videos</string>
  5 + <string name="grid_view">返回</string>
  6 + <string name="error_fragment">错误</string>
  7 + <string name="personal_settings">设置中心</string>
  8 + <string name="watch_trailer_1">Watch trailer</string>
  9 + <string name="watch_trailer_2">FREE</string>
  10 + <string name="rent_1">Rent By Day</string>
  11 + <string name="rent_2">From $1.99</string>
  12 + <string name="buy_1">Buy and Own</string>
  13 + <string name="buy_2">AT $9.99</string>
  14 + <string name="movie">Movie</string>
  15 +
  16 + <!-- Error messages -->
  17 + <string name="error_fragment_message">An error occurred</string>
  18 + <string name="dismiss_error">Dismiss</string>
  19 +</resources>
\ No newline at end of file
... ...
  1 +<resources>
  2 +
  3 + <style name="Theme.BigScreem" parent="@style/Theme.Leanback" />
  4 +</resources>
\ No newline at end of file
... ...
  1 +// Top-level build file where you can add configuration options common to all sub-projects/modules.
  2 +plugins {
  3 + id 'com.android.application' version '7.2.1' apply false
  4 + id 'com.android.library' version '7.2.1' apply false
  5 + id 'org.jetbrains.kotlin.android' version '1.6.10' apply false
  6 +}
  7 +
  8 +task clean(type: Delete) {
  9 + delete rootProject.buildDir
  10 +}
\ No newline at end of file
... ...
  1 +# Project-wide Gradle settings.
  2 +# IDE (e.g. Android Studio) users:
  3 +# Gradle settings configured through the IDE *will override*
  4 +# any settings specified in this file.
  5 +# For more details on how to configure your build environment visit
  6 +# http://www.gradle.org/docs/current/userguide/build_environment.html
  7 +# Specifies the JVM arguments used for the daemon process.
  8 +# The setting is particularly useful for tweaking memory settings.
  9 +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
  10 +# When configured, Gradle will run in incubating parallel mode.
  11 +# This option should only be used with decoupled projects. More details, visit
  12 +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
  13 +# org.gradle.parallel=true
  14 +# AndroidX package structure to make it clearer which packages are bundled with the
  15 +# Android operating system, and which are packaged with your app"s APK
  16 +# https://developer.android.com/topic/libraries/support-library/androidx-rn
  17 +android.useAndroidX=true
  18 +# Kotlin code style for this project: "official" or "obsolete":
  19 +kotlin.code.style=official
  20 +# Enables namespacing of each library's R class so that its R class includes only the
  21 +# resources declared in the library itself and none from the library's dependencies,
  22 +# thereby reducing the size of the R class for that library
  23 +android.nonTransitiveRClass=true
\ No newline at end of file
... ...
No preview for this file type
  1 +#Thu Jun 06 11:37:19 CST 2024
  2 +distributionBase=GRADLE_USER_HOME
  3 +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
  4 +distributionPath=wrapper/dists
  5 +zipStorePath=wrapper/dists
  6 +zipStoreBase=GRADLE_USER_HOME
... ...
  1 +#!/usr/bin/env sh
  2 +
  3 +#
  4 +# Copyright 2015 the original author or authors.
  5 +#
  6 +# Licensed under the Apache License, Version 2.0 (the "License");
  7 +# you may not use this file except in compliance with the License.
  8 +# You may obtain a copy of the License at
  9 +#
  10 +# https://www.apache.org/licenses/LICENSE-2.0
  11 +#
  12 +# Unless required by applicable law or agreed to in writing, software
  13 +# distributed under the License is distributed on an "AS IS" BASIS,
  14 +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15 +# See the License for the specific language governing permissions and
  16 +# limitations under the License.
  17 +#
  18 +
  19 +##############################################################################
  20 +##
  21 +## Gradle start up script for UN*X
  22 +##
  23 +##############################################################################
  24 +
  25 +# Attempt to set APP_HOME
  26 +# Resolve links: $0 may be a link
  27 +PRG="$0"
  28 +# Need this for relative symlinks.
  29 +while [ -h "$PRG" ] ; do
  30 + ls=`ls -ld "$PRG"`
  31 + link=`expr "$ls" : '.*-> \(.*\)$'`
  32 + if expr "$link" : '/.*' > /dev/null; then
  33 + PRG="$link"
  34 + else
  35 + PRG=`dirname "$PRG"`"/$link"
  36 + fi
  37 +done
  38 +SAVED="`pwd`"
  39 +cd "`dirname \"$PRG\"`/" >/dev/null
  40 +APP_HOME="`pwd -P`"
  41 +cd "$SAVED" >/dev/null
  42 +
  43 +APP_NAME="Gradle"
  44 +APP_BASE_NAME=`basename "$0"`
  45 +
  46 +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
  47 +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
  48 +
  49 +# Use the maximum available, or set MAX_FD != -1 to use that value.
  50 +MAX_FD="maximum"
  51 +
  52 +warn () {
  53 + echo "$*"
  54 +}
  55 +
  56 +die () {
  57 + echo
  58 + echo "$*"
  59 + echo
  60 + exit 1
  61 +}
  62 +
  63 +# OS specific support (must be 'true' or 'false').
  64 +cygwin=false
  65 +msys=false
  66 +darwin=false
  67 +nonstop=false
  68 +case "`uname`" in
  69 + CYGWIN* )
  70 + cygwin=true
  71 + ;;
  72 + Darwin* )
  73 + darwin=true
  74 + ;;
  75 + MINGW* )
  76 + msys=true
  77 + ;;
  78 + NONSTOP* )
  79 + nonstop=true
  80 + ;;
  81 +esac
  82 +
  83 +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
  84 +
  85 +
  86 +# Determine the Java command to use to start the JVM.
  87 +if [ -n "$JAVA_HOME" ] ; then
  88 + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
  89 + # IBM's JDK on AIX uses strange locations for the executables
  90 + JAVACMD="$JAVA_HOME/jre/sh/java"
  91 + else
  92 + JAVACMD="$JAVA_HOME/bin/java"
  93 + fi
  94 + if [ ! -x "$JAVACMD" ] ; then
  95 + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
  96 +
  97 +Please set the JAVA_HOME variable in your environment to match the
  98 +location of your Java installation."
  99 + fi
  100 +else
  101 + JAVACMD="java"
  102 + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
  103 +
  104 +Please set the JAVA_HOME variable in your environment to match the
  105 +location of your Java installation."
  106 +fi
  107 +
  108 +# Increase the maximum file descriptors if we can.
  109 +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
  110 + MAX_FD_LIMIT=`ulimit -H -n`
  111 + if [ $? -eq 0 ] ; then
  112 + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
  113 + MAX_FD="$MAX_FD_LIMIT"
  114 + fi
  115 + ulimit -n $MAX_FD
  116 + if [ $? -ne 0 ] ; then
  117 + warn "Could not set maximum file descriptor limit: $MAX_FD"
  118 + fi
  119 + else
  120 + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
  121 + fi
  122 +fi
  123 +
  124 +# For Darwin, add options to specify how the application appears in the dock
  125 +if $darwin; then
  126 + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
  127 +fi
  128 +
  129 +# For Cygwin or MSYS, switch paths to Windows format before running java
  130 +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
  131 + APP_HOME=`cygpath --path --mixed "$APP_HOME"`
  132 + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
  133 +
  134 + JAVACMD=`cygpath --unix "$JAVACMD"`
  135 +
  136 + # We build the pattern for arguments to be converted via cygpath
  137 + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
  138 + SEP=""
  139 + for dir in $ROOTDIRSRAW ; do
  140 + ROOTDIRS="$ROOTDIRS$SEP$dir"
  141 + SEP="|"
  142 + done
  143 + OURCYGPATTERN="(^($ROOTDIRS))"
  144 + # Add a user-defined pattern to the cygpath arguments
  145 + if [ "$GRADLE_CYGPATTERN" != "" ] ; then
  146 + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
  147 + fi
  148 + # Now convert the arguments - kludge to limit ourselves to /bin/sh
  149 + i=0
  150 + for arg in "$@" ; do
  151 + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
  152 + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
  153 +
  154 + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
  155 + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
  156 + else
  157 + eval `echo args$i`="\"$arg\""
  158 + fi
  159 + i=`expr $i + 1`
  160 + done
  161 + case $i in
  162 + 0) set -- ;;
  163 + 1) set -- "$args0" ;;
  164 + 2) set -- "$args0" "$args1" ;;
  165 + 3) set -- "$args0" "$args1" "$args2" ;;
  166 + 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
  167 + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
  168 + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
  169 + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
  170 + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
  171 + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
  172 + esac
  173 +fi
  174 +
  175 +# Escape application args
  176 +save () {
  177 + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
  178 + echo " "
  179 +}
  180 +APP_ARGS=`save "$@"`
  181 +
  182 +# Collect all arguments for the java command, following the shell quoting and substitution rules
  183 +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
  184 +
  185 +exec "$JAVACMD" "$@"
... ...
  1 +@rem
  2 +@rem Copyright 2015 the original author or authors.
  3 +@rem
  4 +@rem Licensed under the Apache License, Version 2.0 (the "License");
  5 +@rem you may not use this file except in compliance with the License.
  6 +@rem You may obtain a copy of the License at
  7 +@rem
  8 +@rem https://www.apache.org/licenses/LICENSE-2.0
  9 +@rem
  10 +@rem Unless required by applicable law or agreed to in writing, software
  11 +@rem distributed under the License is distributed on an "AS IS" BASIS,
  12 +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 +@rem See the License for the specific language governing permissions and
  14 +@rem limitations under the License.
  15 +@rem
  16 +
  17 +@if "%DEBUG%" == "" @echo off
  18 +@rem ##########################################################################
  19 +@rem
  20 +@rem Gradle startup script for Windows
  21 +@rem
  22 +@rem ##########################################################################
  23 +
  24 +@rem Set local scope for the variables with windows NT shell
  25 +if "%OS%"=="Windows_NT" setlocal
  26 +
  27 +set DIRNAME=%~dp0
  28 +if "%DIRNAME%" == "" set DIRNAME=.
  29 +set APP_BASE_NAME=%~n0
  30 +set APP_HOME=%DIRNAME%
  31 +
  32 +@rem Resolve any "." and ".." in APP_HOME to make it shorter.
  33 +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
  34 +
  35 +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
  36 +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
  37 +
  38 +@rem Find java.exe
  39 +if defined JAVA_HOME goto findJavaFromJavaHome
  40 +
  41 +set JAVA_EXE=java.exe
  42 +%JAVA_EXE% -version >NUL 2>&1
  43 +if "%ERRORLEVEL%" == "0" goto execute
  44 +
  45 +echo.
  46 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
  47 +echo.
  48 +echo Please set the JAVA_HOME variable in your environment to match the
  49 +echo location of your Java installation.
  50 +
  51 +goto fail
  52 +
  53 +:findJavaFromJavaHome
  54 +set JAVA_HOME=%JAVA_HOME:"=%
  55 +set JAVA_EXE=%JAVA_HOME%/bin/java.exe
  56 +
  57 +if exist "%JAVA_EXE%" goto execute
  58 +
  59 +echo.
  60 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
  61 +echo.
  62 +echo Please set the JAVA_HOME variable in your environment to match the
  63 +echo location of your Java installation.
  64 +
  65 +goto fail
  66 +
  67 +:execute
  68 +@rem Setup the command line
  69 +
  70 +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
  71 +
  72 +
  73 +@rem Execute Gradle
  74 +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
  75 +
  76 +:end
  77 +@rem End local scope for the variables with windows NT shell
  78 +if "%ERRORLEVEL%"=="0" goto mainEnd
  79 +
  80 +:fail
  81 +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
  82 +rem the _cmd.exe /c_ return code!
  83 +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
  84 +exit /b 1
  85 +
  86 +:mainEnd
  87 +if "%OS%"=="Windows_NT" endlocal
  88 +
  89 +:omega
... ...
  1 +pluginManagement {
  2 + repositories {
  3 + gradlePluginPortal()
  4 + google()
  5 + mavenCentral()
  6 + }
  7 +}
  8 +dependencyResolutionManagement {
  9 + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
  10 + repositories {
  11 + google()
  12 + mavenCentral()
  13 + }
  14 +}
  15 +rootProject.name = "bigScreem"
  16 +include ':app'
... ...