├── app ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── values │ │ │ │ ├── colors.xml │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ ├── menu │ │ │ │ ├── menu_jwplayerview.xml │ │ │ │ └── menu_jwplayerfragment.xml │ │ │ ├── drawable │ │ │ │ ├── custom_button_shape.xml │ │ │ │ ├── custom_button_shape_disabled.xml │ │ │ │ ├── custom_button_shape_selected.xml │ │ │ │ └── custom_button_states.xml │ │ │ ├── xml │ │ │ │ └── network_security_config.xml │ │ │ └── layout │ │ │ │ ├── activity_jwplayerfragment.xml │ │ │ │ ├── activity_jwplayerview.xml │ │ │ │ ├── activity_jwkotlin_player_view_example.xml │ │ │ │ └── view_callback_screen.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── jwplayer │ │ │ │ └── opensourcedemo │ │ │ │ ├── EventCheckChangedListener.java │ │ │ │ ├── MenuHelper.kt │ │ │ │ ├── CastOptionsProvider.java │ │ │ │ ├── JWPlayerFragmentExample.java │ │ │ │ ├── KeepScreenOnHandler.java │ │ │ │ ├── JWPlayerViewExample.java │ │ │ │ ├── JWKotlinPlayerViewExample.kt │ │ │ │ └── CallbackScreen.java │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── jwplayer │ │ │ └── opensourcedemo │ │ │ └── ExampleUnitTest.java │ └── androidTest │ │ └── java │ │ └── com │ │ └── jwplayer │ │ └── opensourcedemo │ │ └── ApplicationTest.java ├── proguard-rules.pro └── build.gradle ├── settings.gradle ├── .github ├── CODEOWNERS └── PULL_REQUEST_TEMPLATE.md ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitmodules ├── README.md ├── gradle.properties ├── .gitignore ├── LICENSE.md ├── gradlew.bat └── gradlew /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # SDK Team 2 | * @jwplayer/team_sdks -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwplayer/jwplayer-sdk-android-demo/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwplayer/jwplayer-sdk-android-demo/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwplayer/jwplayer-sdk-android-demo/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwplayer/jwplayer-sdk-android-demo/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwplayer/jwplayer-sdk-android-demo/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwplayer/jwplayer-sdk-android-demo/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "CastCompanionLibrary-android"] 2 | path = CastCompanionLibrary-android 3 | url = git@github.com:googlecast/CastCompanionLibrary-android.git 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #606060 4 | #ffffff 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_jwplayerview.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### What does this Pull Request do? 2 | 3 | 4 | ### Why is this Pull Request needed? 5 | 6 | 7 | ### Are there any points in the code the reviewer needs to double check? 8 | 9 | 10 | #### Addresses Issue(s): 11 | 12 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Jun 15 10:21:19 EDT 2020 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/custom_button_shape.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/xml/network_security_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/custom_button_shape_disabled.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/custom_button_shape_selected.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | JW Player SDK for Android Demo 3 | JWPlayerFragment Example 4 | JWPlayerView Example 5 | Cast 6 | Kotlin Demo Example 7 | 8 | -------------------------------------------------------------------------------- /app/src/test/java/com/jwplayer/opensourcedemo/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.jwplayer.opensourcedemo; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertEquals; 6 | 7 | /** 8 | * To work on unit tests, switch the Test Artifact in the Build Variants view. 9 | */ 10 | public class ExampleUnitTest { 11 | @Test 12 | public void addition_isCorrect() throws Exception { 13 | assertEquals(4, 2 + 2); 14 | } 15 | } -------------------------------------------------------------------------------- /app/src/androidTest/java/com/jwplayer/opensourcedemo/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.jwplayer.opensourcedemo; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_jwplayerfragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/custom_button_states.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /home/paul/Android/Sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JW Player SDK for Android Open Source Demo 2 | 3 | 4 | [![Join the chat at https://gitter.im/jwplayer/jwplayer-sdk-android-demo](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/jwplayer/jwplayer-sdk-android-demo?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 5 | 6 | This application contains an example implementation of the JW Player SDK for Android. 7 | 8 | #### Usage instructions: 9 | 10 | - Clone the repository into your Android Studio workspace, `git clone git@github.com:jwplayer/jwplayer-sdk-android-demo.git` 11 | - Open the `JWPlayerViewExample` Activity and replace `YOUR_LICENSE_KEY` with your license key 12 | 13 | The demo application should now build and run. For more information on how to use our SDK refer to our developer guide: 14 | 15 | [https://developer.jwplayer.com/jwplayer/docs/android-add-the-android-sdk](https://developer.jwplayer.com/jwplayer/docs/android-add-the-android-sdk) 16 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 20 | 21 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | android.useAndroidX=true 20 | android.enableJetifier=true 21 | android.defaults.buildfeatures.buildconfig=true 22 | android.nonTransitiveRClass=false 23 | android.nonFinalResIds=false -------------------------------------------------------------------------------- /app/src/main/java/com/jwplayer/opensourcedemo/EventCheckChangedListener.java: -------------------------------------------------------------------------------- 1 | package com.jwplayer.opensourcedemo; 2 | 3 | import android.widget.CompoundButton; 4 | 5 | import com.jwplayer.pub.api.JWPlayer; 6 | import com.jwplayer.pub.api.events.EventListener; 7 | import com.jwplayer.pub.api.events.EventType; 8 | 9 | public class EventCheckChangedListener implements CompoundButton.OnCheckedChangeListener { 10 | 11 | private final JWPlayer mPlayer; 12 | private final EventType mEventType; 13 | private final EventListener mEventListener; 14 | 15 | public EventCheckChangedListener(JWPlayer player, 16 | EventType eventType, 17 | EventListener eventListener) { 18 | mPlayer = player; 19 | mEventType = eventType; 20 | mEventListener = eventListener; 21 | } 22 | 23 | @Override 24 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 25 | if (isChecked) { 26 | mPlayer.addListener(mEventType, mEventListener); 27 | } else { 28 | mPlayer.removeListener(mEventType, mEventListener); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | # Built application files 4 | *.apk 5 | *.ap_ 6 | *.aab 7 | 8 | # Files for the ART/Dalvik VM 9 | *.dex 10 | 11 | # Java class files 12 | *.class 13 | 14 | # Generated files 15 | bin/ 16 | gen/ 17 | out/ 18 | 19 | # Gradle files 20 | .gradle/ 21 | build/ 22 | 23 | # Local configuration file (sdk path, etc) 24 | local.properties 25 | 26 | # Proguard folder generated by Eclipse 27 | proguard/ 28 | 29 | # Log Files 30 | *.log 31 | 32 | # Android Studio Navigation editor temp files 33 | .navigation/ 34 | 35 | # Android Studio captures folder 36 | captures/ 37 | 38 | # IntelliJ 39 | *.iml 40 | .idea/* 41 | 42 | # Keystore files 43 | # Uncomment the following lines if you do not want to check your keystore files in. 44 | #*.jks 45 | #*.keystore 46 | 47 | # External native build folder generated in Android Studio 2.2 and later 48 | .externalNativeBuild 49 | 50 | # Google Services (e.g. APIs or Firebase) 51 | google-services.json 52 | 53 | # Freeline 54 | freeline.py 55 | freeline/ 56 | freeline_project_description.json 57 | 58 | # fastlane 59 | fastlane/report.xml 60 | fastlane/Preview.html 61 | fastlane/screenshots 62 | fastlane/test_output 63 | fastlane/readme.md 64 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_jwplayerfragment.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 16 | 17 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_jwplayerview.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 16 | 17 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_jwkotlin_player_view_example.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 16 | 17 | 26 | 27 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | License 2 | ======= 3 | 4 | Copyright © 2015 by JW Player. All Rights Reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | 12 | 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. 13 | 14 | THIS SOFTWARE IS PROVIDED BY JW PLAYER "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /app/src/main/java/com/jwplayer/opensourcedemo/MenuHelper.kt: -------------------------------------------------------------------------------- 1 | package com.jwplayer.opensourcedemo 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import android.view.Menu 6 | 7 | object MenuHelper { 8 | 9 | fun fillInMenu(menu: Menu, clazz: Any, context: Context){ 10 | if (clazz::class == JWPlayerViewExample::class){ 11 | menu.add("JWKotlinPlayerViewExample").setOnMenuItemClickListener { 12 | context.startActivity(Intent(context, JWKotlinPlayerViewExample::class.java)) 13 | true 14 | } 15 | menu.add("JWPlayerFragmentExample").setOnMenuItemClickListener { 16 | context.startActivity(Intent(context, JWPlayerFragmentExample::class.java)) 17 | true 18 | } 19 | }else if (clazz::class == JWKotlinPlayerViewExample::class){ 20 | menu.add("JWPlayerViewExample").setOnMenuItemClickListener { 21 | context.startActivity(Intent(context, JWPlayerViewExample::class.java)) 22 | true 23 | } 24 | menu.add("JWPlayerFragmentExample").setOnMenuItemClickListener { 25 | context.startActivity(Intent(context, JWPlayerFragmentExample::class.java)) 26 | true 27 | } 28 | }else if(clazz::class == JWPlayerFragmentExample::class){ 29 | menu.add("JWPlayerViewExample").setOnMenuItemClickListener { 30 | context.startActivity(Intent(context, JWPlayerViewExample::class.java)) 31 | true 32 | } 33 | menu.add("JWKotlinPlayerViewExample").setOnMenuItemClickListener { 34 | context.startActivity(Intent(context, JWKotlinPlayerViewExample::class.java)) 35 | true 36 | } 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 15 | 20 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 35 | 36 | 39 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/jwplayer/opensourcedemo/CastOptionsProvider.java: -------------------------------------------------------------------------------- 1 | package com.jwplayer.opensourcedemo; 2 | 3 | import android.content.Context; 4 | 5 | import com.google.android.gms.cast.CastMediaControlIntent; 6 | import com.google.android.gms.cast.framework.CastOptions; 7 | import com.google.android.gms.cast.framework.OptionsProvider; 8 | import com.google.android.gms.cast.framework.SessionProvider; 9 | import com.google.android.gms.cast.framework.media.CastMediaOptions; 10 | import com.google.android.gms.cast.framework.media.MediaIntentReceiver; 11 | import com.google.android.gms.cast.framework.media.NotificationOptions; 12 | 13 | import java.util.Arrays; 14 | import java.util.List; 15 | 16 | 17 | public class CastOptionsProvider implements OptionsProvider { 18 | 19 | /** 20 | * The Application Id to use, currently the Default Media Receiver. 21 | */ 22 | private static final String DEFAULT_APPLICATION_ID = CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID; 23 | 24 | @Override 25 | public CastOptions getCastOptions(Context context) { 26 | 27 | final NotificationOptions notificationOptions = new NotificationOptions.Builder() 28 | .setActions(Arrays.asList( 29 | MediaIntentReceiver.ACTION_SKIP_NEXT, 30 | MediaIntentReceiver.ACTION_TOGGLE_PLAYBACK, 31 | MediaIntentReceiver.ACTION_STOP_CASTING), new int[]{1, 2}) 32 | .setTargetActivityClassName(JWPlayerViewExample.class.getName()) 33 | .build(); 34 | 35 | final CastMediaOptions mediaOptions = new CastMediaOptions.Builder() 36 | .setNotificationOptions(notificationOptions) 37 | .build(); 38 | 39 | return new CastOptions.Builder() 40 | .setReceiverApplicationId(DEFAULT_APPLICATION_ID) 41 | .setCastMediaOptions(mediaOptions) 42 | .build(); 43 | } 44 | 45 | @Override 46 | public List getAdditionalSessionProviders(Context appContext) { 47 | return null; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'org.jetbrains.kotlin.android' 3 | 4 | android { 5 | compileSdk 34 6 | defaultConfig { 7 | minSdkVersion 24 8 | targetSdkVersion 34 9 | versionCode 1 10 | versionName "1.0" 11 | applicationId "com.jwplayer.opensourcedemo" 12 | multiDexEnabled true 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | 21 | buildFeatures { 22 | viewBinding true 23 | } 24 | 25 | compileOptions { 26 | sourceCompatibility JavaVersion.VERSION_17 27 | targetCompatibility JavaVersion.VERSION_17 28 | } 29 | namespace 'com.jwplayer.opensourcedemo' 30 | } 31 | 32 | 33 | ext.JWPlayerVersion = '4.23.0' 34 | 35 | ext.medai3ExoPlayerVersion = '1.4.1' 36 | 37 | dependencies { 38 | implementation 'androidx.appcompat:appcompat:1.6.1' 39 | implementation 'com.google.android.material:material:1.11.0' 40 | implementation 'androidx.constraintlayout:constraintlayout:2.1.4' 41 | 42 | implementation "com.jwplayer:jwplayer-core:$JWPlayerVersion" 43 | implementation "com.jwplayer:jwplayer-common:$JWPlayerVersion" 44 | implementation "com.jwplayer:jwplayer-chromecast:$JWPlayerVersion" 45 | implementation "com.jwplayer:jwplayer-ima:$JWPlayerVersion" 46 | 47 | // Specify kotlin-bom to avoid Duplicate Class Errors from mismatch kotlin versions 48 | implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.9.22")) 49 | 50 | // // AAR Builds 51 | // implementation fileTree(dir: 'libs', include: "jwplayer-core-${JWPlayerVersion}.aar") 52 | // implementation fileTree(dir: 'libs', include: "jwplayer-common-${JWPlayerVersion}.aar") 53 | // implementation fileTree(dir: 'libs', include: "jwplayer-chromecast-${JWPlayerVersion}.aar") 54 | // implementation fileTree(dir: 'libs', include: "jwplayer-ima-${JWPlayerVersion}.aar") 55 | // 56 | 57 | //// Only needed when building with AAR instead 58 | // implementation("androidx.media3:media3-exoplayer:$medai3ExoPlayerVersion") 59 | // implementation("androidx.media3:media3-exoplayer-dash:$medai3ExoPlayerVersion") 60 | // implementation("androidx.media3:media3-exoplayer-hls:$medai3ExoPlayerVersion") 61 | // implementation("androidx.media3:media3-exoplayer-smoothstreaming:$medai3ExoPlayerVersion") 62 | // implementation("androidx.media3:media3-ui:$medai3ExoPlayerVersion") 63 | // implementation("com.google.android.gms:play-services-cast-framework:21.3.0") 64 | // implementation 'com.squareup.picasso:picasso:2.71828' 65 | // implementation 'androidx.viewpager2:viewpager2:1.0.0' 66 | // implementation 'com.android.volley:volley:1.2.1' 67 | // implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1' 68 | // implementation("com.google.ads.interactivemedia.v3:interactivemedia:3.31.0") 69 | // implementation("com.google.android.gms:play-services-cast-framework:21.3.0") 70 | // implementation 'androidx.recyclerview:recyclerview:1.2.1' 71 | } -------------------------------------------------------------------------------- /app/src/main/java/com/jwplayer/opensourcedemo/JWPlayerFragmentExample.java: -------------------------------------------------------------------------------- 1 | package com.jwplayer.opensourcedemo; 2 | 3 | import android.os.Bundle; 4 | import android.view.KeyEvent; 5 | import android.view.Menu; 6 | import android.view.MenuItem; 7 | 8 | import androidx.annotation.NonNull; 9 | import androidx.appcompat.app.AppCompatActivity; 10 | import androidx.fragment.app.FragmentManager; 11 | import androidx.fragment.app.FragmentTransaction; 12 | 13 | import com.google.android.gms.cast.framework.CastButtonFactory; 14 | import com.jwplayer.pub.api.JWPlayer; 15 | import com.jwplayer.pub.api.JWPlayerSupportFragment; 16 | import com.jwplayer.pub.api.configuration.PlayerConfig; 17 | 18 | 19 | public class JWPlayerFragmentExample extends AppCompatActivity { 20 | 21 | 22 | private JWPlayerSupportFragment mPlayerFragment; 23 | 24 | private JWPlayer mPlayer; 25 | 26 | private CallbackScreen mCallbackScreen; 27 | 28 | @Override 29 | protected void onCreate(Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | setContentView(R.layout.activity_jwplayerfragment); 32 | 33 | // Construct a new JWPlayerSupportFragment (since we're using AppCompatActivity) 34 | mPlayerFragment = JWPlayerSupportFragment.newInstance(new PlayerConfig.Builder() 35 | .file("https://playertest.longtailvideo.com/adaptive/bipbop/gear4/prog_index.m3u8") 36 | .build()); 37 | 38 | // Attach the Fragment to our layout 39 | FragmentManager fm = getSupportFragmentManager(); 40 | FragmentTransaction ft = fm.beginTransaction(); 41 | ft.add(R.id.fragment_container, mPlayerFragment); 42 | ft.commit(); 43 | 44 | // Make sure all the pending fragment transactions have been completed, otherwise 45 | // mPlayerFragment.getPlayer() may return null 46 | fm.executePendingTransactions(); 47 | 48 | // Get a reference to the JWPlayerView from the fragment 49 | mPlayer = mPlayerFragment.getPlayer(); 50 | 51 | // Keep the screen on during playback 52 | new KeepScreenOnHandler(mPlayer, getWindow()); 53 | 54 | // Event Logging 55 | mCallbackScreen = findViewById(R.id.callback_screen); 56 | mCallbackScreen.registerListeners(mPlayer); 57 | } 58 | 59 | @Override 60 | public boolean onKeyDown(int keyCode, KeyEvent event) { 61 | // Exit fullscreen when the user pressed the Back button 62 | if (keyCode == KeyEvent.KEYCODE_BACK) { 63 | if (mPlayer.getFullscreen()) { 64 | mPlayer.setFullscreen(false, true); 65 | return false; 66 | } 67 | } 68 | return super.onKeyDown(keyCode, event); 69 | } 70 | 71 | 72 | @Override 73 | public boolean onCreateOptionsMenu(Menu menu) { 74 | getMenuInflater().inflate(R.menu.menu_jwplayerfragment, menu); 75 | 76 | // Register the MediaRouterButton 77 | CastButtonFactory.setUpMediaRouteButton(getApplicationContext(), menu, 78 | R.id.media_route_menu_item); 79 | 80 | MenuHelper.INSTANCE.fillInMenu(menu, this, this); 81 | 82 | return true; 83 | } 84 | 85 | @Override 86 | public boolean onOptionsItemSelected(@NonNull MenuItem item) { 87 | return super.onOptionsItemSelected(item); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /app/src/main/java/com/jwplayer/opensourcedemo/KeepScreenOnHandler.java: -------------------------------------------------------------------------------- 1 | package com.jwplayer.opensourcedemo; 2 | 3 | import android.view.Window; 4 | import android.view.WindowManager; 5 | 6 | import com.jwplayer.pub.api.JWPlayer; 7 | import com.jwplayer.pub.api.events.AdCompleteEvent; 8 | import com.jwplayer.pub.api.events.AdErrorEvent; 9 | import com.jwplayer.pub.api.events.AdPauseEvent; 10 | import com.jwplayer.pub.api.events.AdPlayEvent; 11 | import com.jwplayer.pub.api.events.AdSkippedEvent; 12 | import com.jwplayer.pub.api.events.CompleteEvent; 13 | import com.jwplayer.pub.api.events.ErrorEvent; 14 | import com.jwplayer.pub.api.events.EventType; 15 | import com.jwplayer.pub.api.events.PauseEvent; 16 | import com.jwplayer.pub.api.events.PlayEvent; 17 | import com.jwplayer.pub.api.events.listeners.AdvertisingEvents; 18 | import com.jwplayer.pub.api.events.listeners.VideoPlayerEvents; 19 | 20 | /** 21 | * Sets the FLAG_KEEP_SCREEN_ON flag during playback - disables it when playback is stopped 22 | */ 23 | public class KeepScreenOnHandler implements VideoPlayerEvents.OnPlayListener, 24 | VideoPlayerEvents.OnPauseListener, 25 | VideoPlayerEvents.OnCompleteListener, 26 | VideoPlayerEvents.OnErrorListener, 27 | AdvertisingEvents.OnAdPlayListener, 28 | AdvertisingEvents.OnAdPauseListener, 29 | AdvertisingEvents.OnAdCompleteListener, 30 | AdvertisingEvents.OnAdSkippedListener, 31 | AdvertisingEvents.OnAdErrorListener { 32 | 33 | /** 34 | * The application window 35 | */ 36 | private Window mWindow; 37 | 38 | public KeepScreenOnHandler(JWPlayer player, Window window) { 39 | player.addListener(EventType.PLAY, this); 40 | player.addListener(EventType.PAUSE, this); 41 | player.addListener(EventType.COMPLETE, this); 42 | player.addListener(EventType.ERROR,this); 43 | player.addListener(EventType.AD_PLAY, this); 44 | player.addListener(EventType.AD_PAUSE, this); 45 | player.addListener(EventType.AD_COMPLETE, this); 46 | player.addListener(EventType.AD_ERROR, this); 47 | mWindow = window; 48 | } 49 | 50 | private void updateWakeLock(boolean enable) { 51 | if (enable) { 52 | mWindow.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 53 | } else { 54 | mWindow.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 55 | } 56 | } 57 | 58 | @Override 59 | public void onError(ErrorEvent errorEvent) { 60 | updateWakeLock(false); 61 | } 62 | 63 | @Override 64 | public void onAdPlay(AdPlayEvent adPlayEvent) { 65 | updateWakeLock(true); 66 | } 67 | 68 | @Override 69 | public void onAdPause(AdPauseEvent adPauseEvent) { 70 | updateWakeLock(false); 71 | } 72 | 73 | @Override 74 | public void onAdComplete(AdCompleteEvent adCompleteEvent) { 75 | updateWakeLock(false); 76 | } 77 | 78 | @Override 79 | public void onAdSkipped(AdSkippedEvent adSkippedEvent) { 80 | updateWakeLock(false); 81 | } 82 | 83 | @Override 84 | public void onAdError(AdErrorEvent adErrorEvent) { 85 | updateWakeLock(false); 86 | } 87 | 88 | @Override 89 | public void onComplete(CompleteEvent completeEvent) { 90 | updateWakeLock(false); 91 | } 92 | 93 | @Override 94 | public void onPause(PauseEvent pauseEvent) { 95 | updateWakeLock(false); 96 | 97 | } 98 | 99 | @Override 100 | public void onPlay(PlayEvent playEvent) { 101 | updateWakeLock(true); 102 | 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /app/src/main/java/com/jwplayer/opensourcedemo/JWPlayerViewExample.java: -------------------------------------------------------------------------------- 1 | package com.jwplayer.opensourcedemo; 2 | 3 | import android.content.res.Configuration; 4 | import android.os.Bundle; 5 | import android.view.KeyEvent; 6 | import android.view.Menu; 7 | 8 | import androidx.appcompat.app.ActionBar; 9 | import androidx.appcompat.app.AppCompatActivity; 10 | 11 | import com.google.android.gms.cast.framework.CastContext; 12 | import com.jwplayer.pub.api.JWPlayer; 13 | import com.jwplayer.pub.api.configuration.PlayerConfig; 14 | import com.jwplayer.pub.api.events.EventType; 15 | import com.jwplayer.pub.api.events.FullscreenEvent; 16 | import com.jwplayer.pub.api.events.listeners.VideoPlayerEvents; 17 | import com.jwplayer.pub.api.license.LicenseUtil; 18 | import com.jwplayer.pub.view.JWPlayerView; 19 | 20 | 21 | public class JWPlayerViewExample extends AppCompatActivity 22 | implements VideoPlayerEvents.OnFullscreenListener { 23 | 24 | private JWPlayerView mPlayerView; 25 | 26 | private CastContext mCastContext; 27 | 28 | private CallbackScreen mCallbackScreen; 29 | private JWPlayer mPlayer; 30 | 31 | @Override 32 | protected void onCreate(Bundle savedInstanceState) { 33 | super.onCreate(savedInstanceState); 34 | setContentView(R.layout.activity_jwplayerview); 35 | 36 | // TODO: Add your license key 37 | new LicenseUtil().setLicenseKey(this, YOUR_LICENSE_KEY ); 38 | mPlayerView = findViewById(R.id.jwplayer); 39 | mPlayer = mPlayerView.getPlayer(this); 40 | 41 | 42 | // Handle hiding/showing of ActionBar 43 | mPlayer.addListener(EventType.FULLSCREEN, this); 44 | 45 | // Keep the screen on during playback 46 | new KeepScreenOnHandler(mPlayer, getWindow()); 47 | 48 | // Event Logging 49 | mCallbackScreen = findViewById(R.id.callback_screen); 50 | mCallbackScreen.registerListeners(mPlayer); 51 | 52 | // Load a media source 53 | PlayerConfig config = new PlayerConfig.Builder() 54 | .playlistUrl("https://cdn.jwplayer.com/v2/media/1sc0kL2N?format=json") 55 | .build(); 56 | 57 | mPlayer.setup(config); 58 | 59 | // Get a reference to the CastContext 60 | mCastContext = CastContext.getSharedInstance(this); 61 | } 62 | 63 | @Override 64 | public boolean onCreateOptionsMenu(Menu menu) { 65 | super.onCreateOptionsMenu(menu); 66 | MenuHelper.INSTANCE.fillInMenu(menu, this, this); 67 | return true; 68 | } 69 | 70 | 71 | @Override 72 | public void onConfigurationChanged(Configuration newConfig) { 73 | super.onConfigurationChanged(newConfig); 74 | if (!mPlayer.isInPictureInPictureMode()) { 75 | final boolean isFullscreen = newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE; 76 | mPlayer.setFullscreen(isFullscreen, true); 77 | } 78 | } 79 | 80 | @Override 81 | public boolean onKeyDown(int keyCode, KeyEvent event) { 82 | // Exit fullscreen when the user pressed the Back button 83 | if (keyCode == KeyEvent.KEYCODE_BACK) { 84 | if (mPlayer.getFullscreen()) { 85 | mPlayer.setFullscreen(false, true); 86 | return false; 87 | } 88 | } 89 | return super.onKeyDown(keyCode, event); 90 | } 91 | 92 | 93 | @Override 94 | public void onFullscreen(FullscreenEvent fullscreenEvent) { 95 | ActionBar actionBar = getSupportActionBar(); 96 | if (actionBar != null) { 97 | if (fullscreenEvent.getFullscreen()) { 98 | actionBar.hide(); 99 | } else { 100 | actionBar.show(); 101 | } 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /app/src/main/java/com/jwplayer/opensourcedemo/JWKotlinPlayerViewExample.kt: -------------------------------------------------------------------------------- 1 | package com.jwplayer.opensourcedemo 2 | 3 | import android.content.res.Configuration 4 | import android.os.Bundle 5 | import android.view.KeyEvent 6 | import android.view.Menu 7 | import androidx.appcompat.app.AppCompatActivity 8 | import com.google.android.gms.cast.framework.CastContext 9 | import com.jwplayer.opensourcedemo.MenuHelper.fillInMenu 10 | import com.jwplayer.opensourcedemo.databinding.ActivityJwkotlinPlayerViewExampleBinding 11 | import com.jwplayer.pub.api.JWPlayer 12 | import com.jwplayer.pub.api.configuration.PlayerConfig 13 | import com.jwplayer.pub.api.events.EventType 14 | import com.jwplayer.pub.api.events.FullscreenEvent 15 | import com.jwplayer.pub.api.events.listeners.VideoPlayerEvents 16 | import java.util.concurrent.Executors 17 | 18 | class JWKotlinPlayerViewExample : AppCompatActivity(), VideoPlayerEvents.OnFullscreenListener { 19 | 20 | private var mCastContext: CastContext? = null 21 | 22 | private lateinit var mPlayer: JWPlayer 23 | private lateinit var binding: ActivityJwkotlinPlayerViewExampleBinding 24 | 25 | override fun onCreate(savedInstanceState: Bundle?) { 26 | super.onCreate(savedInstanceState) 27 | binding = ActivityJwkotlinPlayerViewExampleBinding.inflate(layoutInflater) 28 | setContentView(binding.root) 29 | 30 | binding.jwplayer.getPlayerAsync(this,this) { 31 | mPlayer = it 32 | // Handle hiding/showing of ActionBar 33 | mPlayer.addListener(EventType.FULLSCREEN, this) 34 | 35 | // Keep the screen on during playback 36 | KeepScreenOnHandler(mPlayer, window) 37 | 38 | // Event Logging 39 | binding.callbackScreen.registerListeners(mPlayer) 40 | 41 | // Load a media source 42 | val config = PlayerConfig.Builder() 43 | .playlistUrl("https://cdn.jwplayer.com/v2/media/1sc0kL2N?format=json") 44 | .build() 45 | mPlayer.setup(config) 46 | } 47 | 48 | // Get a reference to the CastContext from a Task 49 | val instanceTask = CastContext.getSharedInstance(this, Executors.newSingleThreadExecutor()); 50 | instanceTask.addOnCompleteListener { 51 | mCastContext = it.result 52 | } 53 | 54 | } 55 | 56 | override fun onCreateOptionsMenu(menu: Menu): Boolean { 57 | super.onCreateOptionsMenu(menu) 58 | fillInMenu(menu, this, this) 59 | return true 60 | } 61 | 62 | override fun onConfigurationChanged(newConfig: Configuration) { 63 | super.onConfigurationChanged(newConfig) 64 | if (!mPlayer.isInPictureInPictureMode) { 65 | val isFullscreen = newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE 66 | mPlayer.setFullscreen(isFullscreen, true) 67 | } 68 | } 69 | 70 | override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { 71 | // Exit fullscreen when the user pressed the Back button 72 | if (keyCode == KeyEvent.KEYCODE_BACK) { 73 | if (mPlayer.fullscreen) { 74 | mPlayer.setFullscreen(false, true) 75 | return false 76 | } 77 | } 78 | return super.onKeyDown(keyCode, event) 79 | } 80 | 81 | 82 | override fun onFullscreen(fullscreenEvent: FullscreenEvent) { 83 | val actionBar = supportActionBar 84 | if (actionBar != null) { 85 | if (fullscreenEvent.fullscreen) { 86 | actionBar.hide() 87 | } else { 88 | actionBar.show() 89 | } 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_callback_screen.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 17 | 18 | 23 | 24 | 25 | 30 | 31 | 36 | 37 | 42 | 43 | 48 | 49 | 55 | 56 | 61 | 62 | 67 | 68 | 73 | 74 | 79 | 80 | 85 | 86 | 91 | 92 | 97 | 98 | 103 | 104 | 109 | 110 | 115 | 116 | 121 | 122 | 127 | 128 | 133 | 134 | 139 | 140 | 145 | 146 | 151 | 152 | 157 | 158 | 163 | 164 | 169 | 170 | 175 | 176 | 181 | 182 | 187 | 188 | 193 | 194 | 199 | 200 | 205 | 206 | 211 | 212 | 217 | 218 | 223 | 224 | 229 | 230 | 235 | 236 | 241 | 242 | 248 | 249 | 254 | 255 | 260 | 261 | 266 | 267 | 272 | 273 | 278 | 279 | 284 | 285 | 290 | 291 | 296 | 297 | 302 | 303 | 308 | 309 | 314 | 315 | 320 | 321 | 326 | 327 | 332 | 333 | 334 | 335 | 336 | 342 | 343 | 350 | 351 | 361 | 362 |