├── settings.gradle ├── app ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── drawable-hdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── drawable-mdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── drawable-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── drawable-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── values │ │ │ │ ├── colors.xml │ │ │ │ ├── strings.xml │ │ │ │ ├── styles.xml │ │ │ │ └── dimens.xml │ │ │ ├── menu │ │ │ │ └── menu_chat.xml │ │ │ ├── values-w820dp │ │ │ │ └── dimens.xml │ │ │ └── layout │ │ │ │ └── activity_chat.xml │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── tokbox │ │ │ └── android │ │ │ └── demo │ │ │ └── learningopentok │ │ │ ├── WebServiceCoordinator.java │ │ │ └── ChatActivity.java │ └── androidTest │ │ └── java │ │ └── com │ │ └── tokbox │ │ └── android │ │ └── demo │ │ └── learningopentok │ │ └── ApplicationTest.java ├── config.gradle.sample ├── proguard-rules.pro └── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── .github └── workflows │ └── metrics.yml ├── gradle.properties ├── CONTRIBUTING.md ├── gradlew.bat ├── README.md ├── test.html ├── CODE_OF_CONDUCT.md └── gradlew /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | config.gradle 3 | *.jar 4 | *.so -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/learning-opentok-android/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/learning-opentok-android/HEAD/app/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/learning-opentok-android/HEAD/app/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/learning-opentok-android/HEAD/app/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/learning-opentok-android/HEAD/app/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | -------------------------------------------------------------------------------- /app/config.gradle.sample: -------------------------------------------------------------------------------- 1 | // Replace the chatServerUrl with the root of the domain where your chat server is hosted. 2 | // Do not include the trailing slash. 3 | project.ext.chatServerUrl = "http://myhost.herokuapp.com" -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Learning OpenTok 5 | Settings 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | local.properties 3 | build/ 4 | .DS_Store 5 | 6 | # Ignoring all IDE files is better for sample code purposes 7 | .idea 8 | *.iml 9 | 10 | # Typical project recommendations from JetBrains 11 | #.idea/workspace.xml 12 | #.idea/tasks.xml -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Apr 11 13:20:26 PDT 2017 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-3.3-all.zip 7 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_chat.xml: -------------------------------------------------------------------------------- 1 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/tokbox/android/demo/learningopentok/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.tokbox.android.demo.learningopentok; 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 | } -------------------------------------------------------------------------------- /.github/workflows/metrics.yml: -------------------------------------------------------------------------------- 1 | name: Aggregit 2 | 3 | on: 4 | schedule: 5 | - cron: "0 0 * * *" 6 | 7 | jobs: 8 | recordMetrics: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: michaeljolley/aggregit@v1 12 | with: 13 | githubToken: ${{ secrets.GITHUB_TOKEN }} 14 | project_id: ${{ secrets.project_id }} 15 | private_key: ${{ secrets.private_key }} 16 | client_email: ${{ secrets.client_email }} 17 | firebaseDbUrl: ${{ secrets.firebaseDbUrl }} 18 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | 120dp 7 | 90dp 8 | 16dp 9 | 16dp 10 | 2dp 11 | 12 | -------------------------------------------------------------------------------- /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 /Users/ankur/Developer/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 | -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply from: 'config.gradle' 3 | 4 | android { 5 | compileSdkVersion 21 6 | buildToolsVersion '25.0.0' 7 | 8 | defaultConfig { 9 | applicationId "com.tokbox.android.demo.learningopentok" 10 | minSdkVersion 19 11 | targetSdkVersion 21 12 | versionCode 1 13 | versionName "1.0" 14 | } 15 | 16 | compileOptions { 17 | sourceCompatibility JavaVersion.VERSION_1_7 18 | targetCompatibility JavaVersion.VERSION_1_7 19 | } 20 | buildTypes { 21 | release { 22 | minifyEnabled false 23 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 24 | } 25 | } 26 | } 27 | 28 | android.buildTypes.each { type -> 29 | type.buildConfigField 'String', 'CHAT_SERVER_URL', "\"$chatServerUrl\"" 30 | } 31 | 32 | dependencies { 33 | compile 'com.opentok.android:opentok-android-sdk:2.11.0' 34 | compile 'com.android.support:appcompat-v7:21.0.2' 35 | compile 'com.android.volley:volley:1.0.0' 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_chat.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 12 | 13 | 17 | 18 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | For anyone looking to get involved to this project, we are glad to hear from you. Here are a few types of contributions 4 | that we would be interested in hearing about. 5 | 6 | - Bug fixes 7 | - If you find a bug, please first report it using Github Issues. 8 | - Issues that have already been identified as a bug will be labelled `bug`. 9 | - If you'd like to submit a fix for a bug, send a Pull Request from your own fork and mention the Issue number. 10 | - Include a test that isolates the bug and verifies that it was fixed. 11 | - New Features 12 | - If you'd like to accomplish something in the library that it doesn't already do, describe the problem in a new Github Issue. 13 | - Issues that have been identified as a feature request will be labelled `enhancement`. 14 | - If you'd like to implement the new feature, please wait for feedback from the project maintainers before spending too much time writing the code. In some cases, `enhancement`s may not align well with the project objectives at the time. 15 | - Tests, Documentation, Miscellaneous 16 | - If you think the test coverage could be improved, the documentation could be clearer, you've got an alternative implementation of something that may have more advantages, or any other change we would still be glad hear about it. 17 | - If its a trivial change, go ahead and send a Pull Request with the changes you have in mind 18 | - If not, open a Github Issue to discuss the idea first. 19 | 20 | ## Requirements 21 | 22 | For a contribution to be accepted: 23 | 24 | - The test suite must be complete and pass 25 | - Code must follow existing styling conventions 26 | - Commit messages must be descriptive. Related issues should be mentioned by number. 27 | 28 | If the contribution doesn't meet these criteria, a maintainer will discuss it with you on the Issue. You can still continue to add more commits to the branch you have sent the Pull Request from. 29 | 30 | ## How To 31 | 32 | 1. Fork this repository on GitHub. 33 | 1. Clone/fetch your fork to your local development machine. 34 | 1. Create a new branch (e.g. `issue-12`, `feat.add_foo`, etc) and check it out. 35 | 1. Make your changes and commit them. (Did the tests pass?) 36 | 1. Push your new branch to your fork. (e.g. `git push myname issue-12`) 37 | 1. Open a Pull Request from your new branch to the original fork's `master` branch. 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/tokbox/android/demo/learningopentok/WebServiceCoordinator.java: -------------------------------------------------------------------------------- 1 | package com.tokbox.android.demo.learningopentok; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | 6 | import com.android.volley.Request; 7 | import com.android.volley.RequestQueue; 8 | import com.android.volley.Response; 9 | import com.android.volley.VolleyError; 10 | import com.android.volley.toolbox.JsonObjectRequest; 11 | import com.android.volley.toolbox.Volley; 12 | 13 | import org.json.JSONException; 14 | import org.json.JSONObject; 15 | 16 | public class WebServiceCoordinator { 17 | 18 | private static final String CHAT_SERVER_URL = "https://yoursubdomain.herokuapp.com"; 19 | private static final String SESSION_INFO_ENDPOINT = CHAT_SERVER_URL + "/session"; 20 | 21 | private static final String LOG_TAG = WebServiceCoordinator.class.getSimpleName(); 22 | 23 | private final Context context; 24 | private Listener delegate; 25 | 26 | public WebServiceCoordinator(Context context, Listener delegate) { 27 | this.context = context; 28 | this.delegate = delegate; 29 | } 30 | 31 | public void fetchSessionConnectionData() { 32 | RequestQueue reqQueue = Volley.newRequestQueue(context); 33 | reqQueue.add(new JsonObjectRequest(Request.Method.GET, SESSION_INFO_ENDPOINT, null, new Response.Listener() { 34 | @Override 35 | public void onResponse(JSONObject response) { 36 | try { 37 | String apiKey = response.getString("apiKey"); 38 | String sessionId = response.getString("sessionId"); 39 | String token = response.getString("token"); 40 | 41 | Log.i(LOG_TAG, apiKey); 42 | Log.i(LOG_TAG, sessionId); 43 | Log.i(LOG_TAG, token); 44 | 45 | delegate.onSessionConnectionDataReady(apiKey, sessionId, token); 46 | 47 | } catch (JSONException e) { 48 | delegate.onWebServiceCoordinatorError(e); 49 | } 50 | } 51 | }, new Response.ErrorListener() { 52 | @Override 53 | public void onErrorResponse(VolleyError error) { 54 | delegate.onWebServiceCoordinatorError(error); 55 | } 56 | })); 57 | } 58 | 59 | public static interface Listener { 60 | void onSessionConnectionDataReady(String apiKey, String sessionId, String token); 61 | void onWebServiceCoordinatorError(Exception error); 62 | } 63 | } 64 | 65 | -------------------------------------------------------------------------------- /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 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 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 Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ⚠️ This repository is no longer maintained. If you are looking for OpenTok Android SDK samples please check the [opentok-android-sdk-samples](https://github.com/opentok/opentok-android-sdk-samples) repository. 2 | 3 | 4 | ## Learning OpenTok Android Sample App 5 | 6 | Tokbox is now known as Vonage 7 | 8 | This sample app shows how to accomplish basic tasks using the 9 | [OpenTok Android SDK](https://tokbox.com/opentok/libraries/client/android/). 10 | It connects the user with another client so that they can share an OpenTok audio-video 11 | chat session. The app uses the OpenTok Android SDK to implement the following: 12 | 13 | * Connect to an OpenTok session 14 | * Publish an audio-video stream to the session 15 | * Subscribe to another client's audio-video stream 16 | * Record the session, stop the recording, and view the recording 17 | * Implement text chat 18 | * Use a simple custom audio driver for audio input and output 19 | * Use a custom video renderer 20 | * Use a simple custom video capturer 21 | * Use a custom video capturer that uses the device camera 22 | * Publish a screen-sharing stream 23 | * Use video capturer to obtain still screen captures of the camera used by a publisher 24 | 25 | For a full description and walk-through of this code, go to 26 | https://tokbox.com/developer/tutorials/android/. 27 | 28 | The code for this sample is found the following git branches: 29 | 30 | * *basics* -- This branch contains a completed version of the [Basic Video Chat Tutorial](https://tokbox.com/developer/tutorials/android/basic-video-chat/). 31 | 32 | * *archiving* -- This branch shows you how to record the session. 33 | 34 | * *signaling.step-1* -- This branch shows you how to use the OpenTok signaling API. 35 | 36 | * *signaling.step-2* -- This branch shows you how to implement text chat using the OpenTok 37 | signaling API. 38 | 39 | * *signaling.step-3* -- This branch adds some UI improvements for the text chat feature. 40 | 41 | * *audio-driver.step-1* -- This branch shows you how to implement a custom audio driver that 42 | uses a simple audio capturer. 43 | 44 | * *audio-driver.step-2* -- This branch shows you how to implement a custom audio driver that 45 | uses a simple audio renderer. 46 | 47 | * *basic-renderer* -- This branch shows the basics of implementing a custom video renderer 48 | for an OpenTok subscriber. 49 | 50 | * *basic-capturer* -- This branch shows the basics of implementing a custom video capturer 51 | for an OpenTok publisher. 52 | 53 | * *camera-capturer* -- This branch shows you how to use a custom video capturer using 54 | the device camera as the video source. 55 | 56 | * *screensharing* -- This branch shows you how to use the device's screen (instead of a 57 | camera) as the video source for a published stream. 58 | 59 | ## Development and Contributing 60 | 61 | Interested in contributing? We :heart: pull requests! See the [Contribution](CONTRIBUTING.md) guidelines. 62 | 63 | ## Getting Help 64 | 65 | We love to hear from you so if you have questions, comments or find a bug in the project, let us know! You can either: 66 | 67 | - Open an issue on this repository 68 | - See for support options 69 | - Tweet at us! We're [@VonageDev](https://twitter.com/VonageDev) on Twitter 70 | - Or [join the Vonage Developer Community Slack](https://developer.nexmo.com/community/slack) 71 | 72 | ## Further Reading 73 | 74 | - Check out the Developer Documentation at 75 | -------------------------------------------------------------------------------- /test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 |
8 |
9 | 10 | 125 | 126 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | - Demonstrating empathy and kindness toward other people 21 | - Being respectful of differing opinions, viewpoints, and experiences 22 | - Giving and gracefully accepting constructive feedback 23 | - Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | - Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | - The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | - Trolling, insulting or derogatory comments, and personal or political attacks 33 | - Public or private harassment 34 | - Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | - Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | devrel@vonage.com. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 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 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /app/src/main/java/com/tokbox/android/demo/learningopentok/ChatActivity.java: -------------------------------------------------------------------------------- 1 | package com.tokbox.android.demo.learningopentok; 2 | 3 | import android.support.v7.app.ActionBarActivity; 4 | import android.os.Bundle; 5 | import android.util.Log; 6 | import android.view.Menu; 7 | import android.view.MenuItem; 8 | import android.widget.FrameLayout; 9 | 10 | import com.opentok.android.Session; 11 | import com.opentok.android.Stream; 12 | import com.opentok.android.Publisher; 13 | import com.opentok.android.PublisherKit; 14 | import com.opentok.android.Subscriber; 15 | import com.opentok.android.SubscriberKit; 16 | import com.opentok.android.BaseVideoRenderer; 17 | import com.opentok.android.OpentokError; 18 | 19 | 20 | public class ChatActivity extends ActionBarActivity implements WebServiceCoordinator.Listener, 21 | Session.SessionListener, PublisherKit.PublisherListener, SubscriberKit.SubscriberListener { 22 | 23 | private static final String LOG_TAG = ChatActivity.class.getSimpleName(); 24 | 25 | // Suppressing this warning. mWebServiceCoordinator will get GarbageCollected if it is local. 26 | @SuppressWarnings("FieldCanBeLocal") 27 | private WebServiceCoordinator mWebServiceCoordinator; 28 | 29 | private String mApiKey; 30 | private String mSessionId; 31 | private String mToken; 32 | private Session mSession; 33 | private Publisher mPublisher; 34 | private Subscriber mSubscriber; 35 | 36 | private FrameLayout mPublisherViewContainer; 37 | private FrameLayout mSubscriberViewContainer; 38 | 39 | @Override 40 | protected void onCreate(Bundle savedInstanceState) { 41 | super.onCreate(savedInstanceState); 42 | setContentView(R.layout.activity_chat); 43 | 44 | // initialize view objects from your layout 45 | mPublisherViewContainer = (FrameLayout)findViewById(R.id.publisher_container); 46 | mSubscriberViewContainer = (FrameLayout)findViewById(R.id.subscriber_container); 47 | 48 | // initialize WebServiceCoordinator and kick off request for necessary data 49 | mWebServiceCoordinator = new WebServiceCoordinator(this, this); 50 | mWebServiceCoordinator.fetchSessionConnectionData(); 51 | } 52 | 53 | @Override 54 | public boolean onCreateOptionsMenu(Menu menu) { 55 | // Inflate the menu; this adds items to the action bar if it is present. 56 | getMenuInflater().inflate(R.menu.menu_chat, menu); 57 | return true; 58 | } 59 | 60 | @Override 61 | public boolean onOptionsItemSelected(MenuItem item) { 62 | // Handle action bar item clicks here. The action bar will 63 | // automatically handle clicks on the Home/Up button, so long 64 | // as you specify a parent activity in AndroidManifest.xml. 65 | int id = item.getItemId(); 66 | 67 | //noinspection SimplifiableIfStatement 68 | if (id == R.id.action_settings) { 69 | return true; 70 | } 71 | 72 | return super.onOptionsItemSelected(item); 73 | } 74 | 75 | private void initializeSession() { 76 | mSession = new Session.Builder(this, mApiKey, mSessionId).build(); 77 | mSession.setSessionListener(this); 78 | mSession.connect(mToken); 79 | } 80 | 81 | private void initializePublisher() { 82 | // initialize Publisher and set this object to listen to Publisher events 83 | mPublisher = new Publisher.Builder(this).build(); 84 | mPublisher.setPublisherListener(this); 85 | 86 | // set publisher video style to fill view 87 | mPublisher.getRenderer().setStyle(BaseVideoRenderer.STYLE_VIDEO_SCALE, 88 | BaseVideoRenderer.STYLE_VIDEO_FILL); 89 | mPublisherViewContainer.addView(mPublisher.getView()); 90 | } 91 | 92 | private void logOpenTokError(OpentokError opentokError) { 93 | Log.e(LOG_TAG, "Error Domain: " + opentokError.getErrorDomain().name()); 94 | Log.e(LOG_TAG, "Error Code: " + opentokError.getErrorCode().name()); 95 | } 96 | 97 | /* Web Service Coordinator delegate methods */ 98 | 99 | @Override 100 | public void onSessionConnectionDataReady(String apiKey, String sessionId, String token) { 101 | mApiKey = apiKey; 102 | mSessionId = sessionId; 103 | mToken = token; 104 | 105 | initializeSession(); 106 | initializePublisher(); 107 | } 108 | 109 | @Override 110 | public void onWebServiceCoordinatorError(Exception error) { 111 | Log.e(LOG_TAG, "Web Service error: " + error.getMessage()); 112 | } 113 | 114 | /* Session Listener methods */ 115 | 116 | @Override 117 | public void onConnected(Session session) { 118 | Log.i(LOG_TAG, "Session Connected"); 119 | 120 | if (mPublisher != null) { 121 | mSession.publish(mPublisher); 122 | } 123 | } 124 | 125 | @Override 126 | public void onDisconnected(Session session) { 127 | Log.i(LOG_TAG, "Session Disconnected"); 128 | } 129 | 130 | @Override 131 | public void onStreamReceived(Session session, Stream stream) { 132 | Log.i(LOG_TAG, "Stream Received"); 133 | 134 | if (mSubscriber == null) { 135 | mSubscriber = new Subscriber.Builder(this, stream).build(); 136 | mSubscriber.setSubscriberListener(this); 137 | mSubscriber.getRenderer().setStyle(BaseVideoRenderer.STYLE_VIDEO_SCALE, 138 | BaseVideoRenderer.STYLE_VIDEO_FILL); 139 | mSession.subscribe(mSubscriber); 140 | } 141 | } 142 | 143 | @Override 144 | public void onStreamDropped(Session session, Stream stream) { 145 | Log.i(LOG_TAG, "Stream Dropped"); 146 | 147 | if (mSubscriber != null) { 148 | mSubscriber = null; 149 | mSubscriberViewContainer.removeAllViews(); 150 | } 151 | } 152 | 153 | @Override 154 | public void onError(Session session, OpentokError opentokError) { 155 | logOpenTokError(opentokError); 156 | } 157 | 158 | /* Publisher Listener methods */ 159 | 160 | @Override 161 | public void onStreamCreated(PublisherKit publisherKit, Stream stream) { 162 | Log.i(LOG_TAG, "Publisher Stream Created"); 163 | } 164 | 165 | @Override 166 | public void onStreamDestroyed(PublisherKit publisherKit, Stream stream) { 167 | Log.i(LOG_TAG, "Publisher Stream Destroyed"); 168 | } 169 | 170 | @Override 171 | public void onError(PublisherKit publisherKit, OpentokError opentokError) { 172 | logOpenTokError(opentokError); 173 | } 174 | 175 | /* Subscriber Listener methods */ 176 | 177 | @Override 178 | public void onConnected(SubscriberKit subscriberKit) { 179 | Log.i(LOG_TAG, "Subscriber Connected"); 180 | 181 | mSubscriberViewContainer.addView(mSubscriber.getView()); 182 | } 183 | 184 | @Override 185 | public void onDisconnected(SubscriberKit subscriberKit) { 186 | Log.i(LOG_TAG, "Subscriber Disconnected"); 187 | } 188 | 189 | @Override 190 | public void onError(SubscriberKit subscriberKit, OpentokError opentokError) { 191 | logOpenTokError(opentokError); 192 | } 193 | } 194 | --------------------------------------------------------------------------------