├── .gitignore ├── .gitmodules ├── .idea ├── gradle.xml └── runConfigurations.xml ├── .travis.yml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── .gitignore │ └── main │ ├── AndroidManifest.xml │ ├── assets │ └── font │ │ ├── Lato-Black.ttf │ │ ├── Lato-BlackItalic.ttf │ │ ├── Lato-Bold.ttf │ │ ├── Lato-BoldItalic.ttf │ │ ├── Lato-Hairline.ttf │ │ ├── Lato-HairlineItalic.ttf │ │ ├── Lato-Italic.ttf │ │ ├── Lato-Light.ttf │ │ ├── Lato-LightItalic.ttf │ │ └── Lato-Regular.ttf │ ├── java │ └── com │ │ └── yuneec │ │ └── example │ │ ├── GenericFileProvider.java │ │ ├── component │ │ ├── actitivty │ │ │ └── MainActivity.java │ │ ├── adapter │ │ │ └── MediaListAdapter.java │ │ ├── custom_callback │ │ │ ├── OnChangeListener.java │ │ │ └── VideoSurfaceHolderCallBack.java │ │ ├── fragment │ │ │ ├── ActionFragment.java │ │ │ ├── CameraFragment.java │ │ │ ├── CameraSettingsFragment.java │ │ │ ├── ConnectionFragment.java │ │ │ ├── GimbalFragment.java │ │ │ ├── MediaDownloadFragment.java │ │ │ ├── MissionFragment.java │ │ │ ├── St16Fragment.java │ │ │ └── TelemetryFragment.java │ │ ├── listeners │ │ │ ├── ActionListener.java │ │ │ ├── CameraListener.java │ │ │ ├── CameraModeListener.java │ │ │ ├── CameraSettingsListener.java │ │ │ ├── ConnectionListener.java │ │ │ ├── GimbalListener.java │ │ │ ├── TelemetryListener.java │ │ │ └── YuneecSt16Listener.java │ │ └── utils │ │ │ ├── Common.java │ │ │ └── Media.java │ │ ├── model │ │ └── MediaInfoEntry.java │ │ └── view │ │ ├── CustomButton.java │ │ ├── CustomEditTextView.java │ │ └── CustomTextView.java │ └── res │ ├── layout │ ├── action_layout.xml │ ├── camera_layout.xml │ ├── camera_setting_layout.xml │ ├── connection_layout.xml │ ├── custom_spinner_item.xml │ ├── gimbal_layout.xml │ ├── list_item.xml │ ├── main_activity.xml │ ├── media_download_layout.xml │ ├── mission_example.xml │ ├── spinner_item.xml │ ├── st16_layout.xml │ └── telemetry_example.xml │ ├── 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-w820dp │ └── dimens.xml │ ├── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml │ └── xml │ └── provider_paths.xml ├── astylerc ├── build.gradle ├── fix_style.sh ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── sitl ├── Dockerfile └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the ART/Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | # Android Studio captures folder 33 | captures/ 34 | 35 | # Intellij 36 | *.iml 37 | 38 | # User-specific configurations 39 | .idea/libraries/ 40 | .idea/workspace.xml 41 | .idea/tasks.xml 42 | .idea/.name 43 | .idea/compiler.xml 44 | .idea/copyright/profiles_settings.xml 45 | .idea/encodings.xml 46 | .idea/misc.xml 47 | .idea/modules.xml 48 | .idea/scopes/scope_settings.xml 49 | .idea/vcs.xml 50 | .idea/caches 51 | .idea/codeStyles 52 | 53 | # Keystore files 54 | *.jks 55 | 56 | # built Cpp stuff 57 | *.externalNativeBuild 58 | 59 | # DS_Store 60 | *.DS_Store 61 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YUNEEC/Yuneec-SDK-Android-Example/5feac26f415998fd3c221c1a2ee56c8275821744/.gitmodules -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 20 | 21 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: android 2 | jdk: oraclejdk8 3 | before_cache: 4 | - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock 5 | - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ 6 | cache: 7 | directories: 8 | - "$HOME/.gradle/caches/" 9 | - "$HOME/.gradle/wrapper/" 10 | env: 11 | global: 12 | - ANDROID_API=27 13 | - ANDROID_BUILD_TOOLS=27.0.3 14 | - ADB_INSTALL_TIMEOUT=5 15 | android: 16 | components: 17 | - tools 18 | - platform-tools 19 | - build-tools-$ANDROID_BUILD_TOOLS 20 | - android-$ANDROID_API 21 | - extra-google-m2repository 22 | - extra-android-m2repository 23 | - addon-google_apis-google-19 24 | - sys-img-armeabi-v7a-addon-google_apis-google-$ANDROID_API_LEVEL 25 | before_install: 26 | - mkdir -p "$ANDROID_HOME/licenses" 27 | - echo -e "\n8933bad161af4178b1185d1a37fbf41ea5269c55" > "$ANDROID_HOME/licenses/android-sdk-license" 28 | - echo -e "\n84831b9409646a918e30573bab4c9c91346d8abd" > "$ANDROID_HOME/licenses/android-sdk-preview-license" 29 | - chmod +x gradlew 30 | - "./gradlew dependencies || true" 31 | - export PATH=${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools 32 | - mkdir -p $HOME/bin && wget -P $HOME/bin https://s3.eu-central-1.amazonaws.com/e59024aeb5-287e-496c-fffe-6c230d1fe7e4/ci-resources/astyle && chmod +x $HOME/bin/astyle 33 | - PATH=$HOME/bin:$PATH 34 | script: 35 | - ./gradlew build 36 | - ./fix_style.sh . 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2017, YUNEEC 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Yuneec SDK Android example 2 | 3 | [![Build Status](https://travis-ci.com/YUNEEC/Yuneec-SDK-Android-Example.svg?token=5772mkLLvKwYKBhk4s9n&branch=master)](https://travis-ci.com/YUNEEC/Yuneec-SDK-Android-Example) 4 | 5 | ## Overview 6 | 7 | This is an Android app built out of the Yuneec Android SDK. 8 | 9 | ## Building 10 | 11 | The project has been created using Android Studio 2.3.x. 12 | 13 | ### Checkout this repo 14 | 15 | ``` 16 | git clone https://github.com/YUNEEC/Yuneec-SDK-Android-Example.git 17 | ``` 18 | 19 | ## Description 20 | 21 | This app uses the Yuneec Android SDK Library. To include the library in your application, 22 | you should add the following to the root build.grade: 23 | ``` 24 | allprojects { 25 | repositories { 26 | ... 27 | maven { url 'https://jitpack.io' } 28 | } 29 | } 30 | ``` 31 | 32 | Then, add the dependency to the app's build.gradle: 33 | ``` 34 | compile 'com.github.YUNEEC:Yuneec-SDK-Android:vX.Y.Z' 35 | ``` 36 | 37 | where X.Y.Z is the version to select. 38 | 39 | To see all the available versions, go to [Jitpack](https://jitpack.io). In the look up box paste YUNEEC/Yuneec-SDK-Android. 40 | 41 | Please choose the latest version of the SDK to integrate with your project. 42 | 43 | ## Use the Yuneec software in the loop (SITL) simulation for testing 44 | 45 | The Android app can be tested against the software simulation. 46 | 47 | The SITL can be used on Linux or Mac. The use in a virtualization environment such as VirtualBox is possible but generally not recommended for performance reasons. A headless instance can be run inside a Docker container, as explained [here](sitl). 48 | 49 | ### Installing Gazebo7 50 | 51 | #### Mac 52 | 53 | Tested on macOS 10.12. 54 | 55 | Make sure to have [homebrew](http://brew.sh). 56 | 57 | ``` 58 | brew cask install xquartz 59 | brew tap osrf/simulation 60 | brew update 61 | brew install gazebo7 62 | ``` 63 | OpenCV is required to run the simulation. 64 | ``` 65 | brew install opencv 66 | ``` 67 | 68 | #### Ubuntu 69 | 70 | Tested on Ubuntu 16.04. 71 | 72 | ``` 73 | sudo sh -c 'echo "deb http://packages.osrfoundation.org/gazebo/ubuntu-stable `lsb_release -cs` main" > /etc/apt/sources.list.d/gazebo-stable.list' 74 | wget http://packages.osrfoundation.org/gazebo.key -O - | sudo apt-key add - 75 | sudo apt-get update 76 | sudo apt-get install gazebo7 libgazebo7-dev 77 | ``` 78 | 79 | Instructions taken from [gazebosim.org](http://gazebosim.org/tutorials?tut=install_ubuntu&ver=7.0&cat=install). 80 | 81 | ### Get the SITL simulation 82 | 83 | Download the zip containing the SITL simulation for [macOS 10.12](https://d3qzlqwby7grio.cloudfront.net/H520/sitl/macOS/Yuneec-SITL-Simulation-macOS.zip) or [Ubuntu 16.04](https://d3qzlqwby7grio.cloudfront.net/H520/sitl/Linux/Yuneec-SITL-Simulation-Linux.zip). 84 | 85 | ### Run the simulation 86 | 87 | Use the included bash script to start the simulation environment: 88 | 89 | ``` 90 | cd Yuneec-SITL-simulation-xxx/ 91 | ./typhoon_sitl.bash 92 | ``` 93 | 94 | To run it without simulation GUI, use: 95 | 96 | ``` 97 | HEADLESS=1 ./typhoon_sitl.bash 98 | ``` 99 | 100 | Sometimes the simulation hangs on startup. If it happens, press Ctrl+C in the console and try again. 101 | 102 | To test if the simulation works, you can type `commander takeoff` or `commander land` in the `pxh>` shell. 103 | 104 | ### Use the Android emulator 105 | 106 | #### Port fowarding 107 | 108 | In order for the Android emulator in Android Studio to communicate with SITL, you need to redirect the UDP port between the host and the emulator. 109 | 110 | 111 | First, get the auth token: 112 | ``` 113 | cat ~/.emulator_console_auth_token 114 | ``` 115 | 116 | Then use telnet to configure the emulator: 117 | ``` 118 | telnet localhost 5554 119 | ``` 120 | 121 | Copy the token found above it and paste it authenticate the telnet session: 122 | ``` 123 | auth 124 | ``` 125 | 126 | Then, set up the redirect: 127 | ``` 128 | redir add udp:14540:14540 129 | ``` 130 | 131 | You can now leave telnet: 132 | ``` 133 | quit 134 | ``` 135 | 136 | ### Use a real Android device 137 | 138 | By default, the SITL simulation will only try to connect on localhost but not to a phone/tablet on the network. 139 | 140 | There are two options to connect to another IP: 141 | 142 | 1. Use broadcasting: This has the advantage that you don't need to determine the IP of the iOS device because it will pick it up automatically in the network. However, this can be a race if to devices are listening on the network. 143 | 144 | 2. Set the IP: This let's you choose the IP and avoid races for who gets to be the client. 145 | 146 | #### Use broadcasting: 147 | 148 | Start the SITL simuation and type the following in the `pxh>`: 149 | 150 | ``` 151 | param set MAV_BROADCAST 1 152 | param save 153 | ``` 154 | 155 | #### Set IP: 156 | 157 | Before starting the SITL simulation, open the file `posix-configs/SITL/init/ekf2/typhoon_h480` and look for this line: 158 | 159 | ``` 160 | mavlink start -u 14557 -r 4000000 -m custom -o 14540 161 | ``` 162 | 163 | then add the IP of the Android device in the local network with `-t`: 164 | ``` 165 | mavlink start -u 14557 -r 4000000 -m custom -o 14540 -t 192.168.0.X 166 | ``` 167 | 168 | ## License 169 | 170 | This example app is published under the [BSD 3-Clause license](LICENSE). 171 | 172 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /.externalNativeBuild 3 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 27 5 | buildToolsVersion '27.0.3' 6 | 7 | 8 | defaultConfig { 9 | applicationId "com.yuneec.yuneecandroidexample" 10 | minSdkVersion 19 11 | targetSdkVersion 27 12 | versionCode 1 13 | versionName "1.0" 14 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 15 | ndk { 16 | abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' 17 | } 18 | } 19 | buildTypes { 20 | release { 21 | minifyEnabled false 22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 23 | } 24 | } 25 | } 26 | 27 | dependencies { 28 | implementation fileTree(include: ['*.jar'], dir: 'libs') 29 | androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', { 30 | exclude group: 'com.android.support', module: 'support-annotations' 31 | }) 32 | implementation 'com.android.support:appcompat-v7:27.1.1' 33 | testImplementation 'junit:junit:4.12' 34 | implementation 'com.github.YUNEEC:Yuneec-SDK-Android:v0.14.5-1' 35 | implementation 'com.github.YUNEEC:Yuneec-RTSP-Player-Android:v0.1' 36 | } 37 | -------------------------------------------------------------------------------- /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/julianoes/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 | -------------------------------------------------------------------------------- /app/src/.gitignore: -------------------------------------------------------------------------------- 1 | /test 2 | /androidTest 3 | *. 4 | *~ 5 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 19 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 33 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /app/src/main/assets/font/Lato-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YUNEEC/Yuneec-SDK-Android-Example/5feac26f415998fd3c221c1a2ee56c8275821744/app/src/main/assets/font/Lato-Black.ttf -------------------------------------------------------------------------------- /app/src/main/assets/font/Lato-BlackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YUNEEC/Yuneec-SDK-Android-Example/5feac26f415998fd3c221c1a2ee56c8275821744/app/src/main/assets/font/Lato-BlackItalic.ttf -------------------------------------------------------------------------------- /app/src/main/assets/font/Lato-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YUNEEC/Yuneec-SDK-Android-Example/5feac26f415998fd3c221c1a2ee56c8275821744/app/src/main/assets/font/Lato-Bold.ttf -------------------------------------------------------------------------------- /app/src/main/assets/font/Lato-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YUNEEC/Yuneec-SDK-Android-Example/5feac26f415998fd3c221c1a2ee56c8275821744/app/src/main/assets/font/Lato-BoldItalic.ttf -------------------------------------------------------------------------------- /app/src/main/assets/font/Lato-Hairline.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YUNEEC/Yuneec-SDK-Android-Example/5feac26f415998fd3c221c1a2ee56c8275821744/app/src/main/assets/font/Lato-Hairline.ttf -------------------------------------------------------------------------------- /app/src/main/assets/font/Lato-HairlineItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YUNEEC/Yuneec-SDK-Android-Example/5feac26f415998fd3c221c1a2ee56c8275821744/app/src/main/assets/font/Lato-HairlineItalic.ttf -------------------------------------------------------------------------------- /app/src/main/assets/font/Lato-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YUNEEC/Yuneec-SDK-Android-Example/5feac26f415998fd3c221c1a2ee56c8275821744/app/src/main/assets/font/Lato-Italic.ttf -------------------------------------------------------------------------------- /app/src/main/assets/font/Lato-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YUNEEC/Yuneec-SDK-Android-Example/5feac26f415998fd3c221c1a2ee56c8275821744/app/src/main/assets/font/Lato-Light.ttf -------------------------------------------------------------------------------- /app/src/main/assets/font/Lato-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YUNEEC/Yuneec-SDK-Android-Example/5feac26f415998fd3c221c1a2ee56c8275821744/app/src/main/assets/font/Lato-LightItalic.ttf -------------------------------------------------------------------------------- /app/src/main/assets/font/Lato-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YUNEEC/Yuneec-SDK-Android-Example/5feac26f415998fd3c221c1a2ee56c8275821744/app/src/main/assets/font/Lato-Regular.ttf -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/GenericFileProvider.java: -------------------------------------------------------------------------------- 1 | package com.yuneec.example; 2 | 3 | import android.support.v4.content.FileProvider; 4 | 5 | // https://stackoverflow.com/questions/38200282#answer-38858040 6 | public class GenericFileProvider extends FileProvider { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/component/actitivty/MainActivity.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MainActivity.java Yuneec-SDK-Android-Example 3 | *

4 | * Copyright @ 2016-2017 Yuneec. All rights reserved. 5 | */ 6 | 7 | package com.yuneec.example.component.actitivty; 8 | 9 | import android.content.Context; 10 | import android.os.Build; 11 | import android.os.Bundle; 12 | import android.support.v4.app.FragmentActivity; 13 | import android.support.v4.app.FragmentTabHost; 14 | import android.support.v4.content.ContextCompat; 15 | import android.util.Log; 16 | import android.view.View; 17 | import android.widget.Button; 18 | import android.widget.TextView; 19 | 20 | import com.yuneec.example.R; 21 | import com.yuneec.example.component.custom_callback.OnChangeListener; 22 | import com.yuneec.example.component.fragment.ActionFragment; 23 | import com.yuneec.example.component.fragment.CameraFragment; 24 | import com.yuneec.example.component.fragment.CameraSettingsFragment; 25 | import com.yuneec.example.component.fragment.ConnectionFragment; 26 | import com.yuneec.example.component.fragment.GimbalFragment; 27 | import com.yuneec.example.component.fragment.MediaDownloadFragment; 28 | import com.yuneec.example.component.fragment.St16Fragment; 29 | import com.yuneec.example.component.fragment.TelemetryFragment; 30 | import com.yuneec.example.component.listeners.ConnectionListener; 31 | import com.yuneec.example.component.utils.Common; 32 | import com.yuneec.sdk.Camera; 33 | 34 | /** 35 | * Simple example based on the Yuneec SDK for Android 36 | *

37 | * The example has 3 tabs (fragments) called Telemetry, Action, Mission. 38 | */ 39 | public class MainActivity 40 | extends FragmentActivity 41 | implements OnChangeListener { 42 | 43 | private FragmentTabHost mTabHost; 44 | 45 | private Context context; 46 | 47 | private Button mediaCapture; 48 | 49 | private static final String TAG = MainActivity.class.getCanonicalName(); 50 | 51 | private CameraFragment cameraFragment = null; 52 | 53 | @Override 54 | protected void onCreate(Bundle savedInstanceState) { 55 | 56 | super.onCreate(savedInstanceState); 57 | setContentView(R.layout.main_activity); 58 | context = this; 59 | mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost); 60 | mTabHost.setup(this, getSupportFragmentManager(), R.id.tabcontent); 61 | mTabHost.addTab(mTabHost.newTabSpec("connection") 62 | .setIndicator("Home"), ConnectionFragment.class, null); 63 | mTabHost.addTab(mTabHost.newTabSpec("camera") 64 | .setIndicator("Camera"), CameraFragment.class, null); 65 | mTabHost.addTab(mTabHost.newTabSpec("actions") 66 | .setIndicator("Actions"), ActionFragment.class, null); 67 | mTabHost.addTab(mTabHost.newTabSpec("gimbal") 68 | .setIndicator("Gimbal"), GimbalFragment.class, null); 69 | mTabHost.addTab(mTabHost.newTabSpec("media-download") 70 | .setIndicator("Media Download"), MediaDownloadFragment.class, null); 71 | mTabHost.addTab(mTabHost.newTabSpec("telemetry") 72 | .setIndicator("Telemetry"), TelemetryFragment.class, null); 73 | if (isSt16()) { 74 | mTabHost.addTab(mTabHost.newTabSpec("st16") 75 | .setIndicator("St16"), St16Fragment.class, null); 76 | } 77 | 78 | for (int i = 0; i < mTabHost.getTabWidget().getChildCount(); i++) { 79 | View v = mTabHost.getTabWidget().getChildAt(i); 80 | TextView tv = (TextView) v.findViewById(android.R.id.title); 81 | tv.setTextColor(ContextCompat.getColor(this, R.color.orangeDark)); 82 | tv.setTextSize(16); 83 | } 84 | 85 | } 86 | 87 | @Override 88 | protected void onStart() { 89 | 90 | super.onStart(); 91 | registerListeners(); 92 | } 93 | 94 | @Override 95 | protected void onStop() { 96 | 97 | super.onStop(); 98 | unRegisterListeners(); 99 | 100 | } 101 | 102 | private void registerListeners() { 103 | 104 | ConnectionListener.registerConnectionListener(this); 105 | } 106 | 107 | private void unRegisterListeners() { 108 | 109 | ConnectionListener.unRegisterConnectionListener(); 110 | } 111 | 112 | @Override 113 | public void publishConnectionStatus(final String connectionStatus) { 114 | 115 | runOnUiThread(new Runnable() { 116 | 117 | @Override 118 | public void run() { 119 | 120 | Log.d(TAG, connectionStatus); 121 | ConnectionFragment fragment = (ConnectionFragment) getSupportFragmentManager().findFragmentByTag( 122 | "connection"); 123 | fragment.setConnectionStateView(connectionStatus); 124 | 125 | } 126 | }); 127 | } 128 | 129 | @Override 130 | public void publishBatteryChangeStatus(final String batteryStatus) { 131 | 132 | runOnUiThread(new Runnable() { 133 | 134 | @Override 135 | public void run() { 136 | 137 | //Log.d(TAG, batteryStatus); 138 | ConnectionFragment fragment = (ConnectionFragment) getSupportFragmentManager().findFragmentByTag( 139 | "connection"); 140 | fragment.setBatterStateView(batteryStatus); 141 | 142 | } 143 | }); 144 | } 145 | 146 | @Override 147 | public void publishHealthChangeStatus(final String healthStatus) { 148 | 149 | runOnUiThread(new Runnable() { 150 | 151 | @Override 152 | public void run() { 153 | 154 | //Log.d(TAG, healthStatus); 155 | ConnectionFragment fragment = (ConnectionFragment) getSupportFragmentManager().findFragmentByTag( 156 | "connection"); 157 | fragment.setDroneHealthView(healthStatus); 158 | 159 | } 160 | }); 161 | } 162 | 163 | @Override 164 | public void publishCameraResult(final String result) { 165 | runOnUiThread(new Runnable() { 166 | 167 | @Override 168 | public void run() { 169 | Log.d(TAG, result); 170 | if (cameraFragment == null) { 171 | cameraFragment = (CameraFragment) 172 | getSupportFragmentManager().findFragmentByTag("camera"); 173 | } 174 | if (!result.equals("Success")) { 175 | Common.makeToast(context, "Error! Please make sure SD card is inserted and try again"); 176 | if (cameraFragment.getCameraMode().equals(Camera.Mode.PHOTO) 177 | && cameraFragment.getIsPhotoInterval()) { 178 | mediaCapture = (Button) findViewById(R.id.photo_interval); 179 | if (mediaCapture.getText().equals(getString(R.string.stop_photo_interval))) { 180 | mediaCapture.setText(getString(R.string.photo_interval)); 181 | } 182 | cameraFragment.setIsPhotoInterval(false); 183 | } 184 | if (cameraFragment.getCameraMode().equals(Camera.Mode.VIDEO)) { 185 | mediaCapture = (Button) findViewById(R.id.video); 186 | if (mediaCapture.getText().equals(getString(R.string.stop_video))) { 187 | mediaCapture.setText(getString(R.string.video)); 188 | } 189 | } 190 | } else { 191 | if (cameraFragment.getCameraMode().equals(Camera.Mode.VIDEO)) { 192 | mediaCapture = (Button) findViewById(R.id.video); 193 | if (mediaCapture.getText().equals(getString(R.string.video))) { 194 | mediaCapture.setText(getString(R.string.stop_video)); 195 | } else { 196 | mediaCapture.setText(getString(R.string.video)); 197 | } 198 | 199 | } else if (cameraFragment.getCameraMode().equals(Camera.Mode.PHOTO) 200 | && cameraFragment.getIsPhotoInterval()) { 201 | mediaCapture = (Button) findViewById(R.id.photo_interval); 202 | if (mediaCapture.getText().equals(getString(R.string.photo_interval))) { 203 | mediaCapture.setText(getString(R.string.stop_photo_interval)); 204 | } else { 205 | mediaCapture.setText(getString(R.string.photo_interval)); 206 | cameraFragment.setIsPhotoInterval(false); 207 | } 208 | 209 | } else { 210 | Common.makeToast(context, "Picture Capture Successful"); 211 | } 212 | } 213 | } 214 | }); 215 | } 216 | 217 | @Override 218 | public void publishActionResult(final String result) { 219 | runOnUiThread(new Runnable() { 220 | 221 | @Override 222 | public void run() { 223 | Common.makeToast(context, result); 224 | } 225 | }); 226 | } 227 | 228 | @Override 229 | public void publishYuneecSt16Result(final String result) { 230 | runOnUiThread(new Runnable() { 231 | 232 | @Override 233 | public void run() { 234 | Common.makeToast(context, result); 235 | } 236 | }); 237 | } 238 | 239 | @Override 240 | public void publishCameraModeResult(final Camera.Mode mode, final String result) { 241 | runOnUiThread(new Runnable() { 242 | @Override 243 | public void run() { 244 | if (!result.equals("Success")) { 245 | Common.makeToast(context, "Please make sure SD card is inserted and try again"); 246 | } else { 247 | if (cameraFragment == null) { 248 | cameraFragment = (CameraFragment) 249 | getSupportFragmentManager().findFragmentByTag("camera"); 250 | } 251 | cameraFragment.setCameraMode(mode); 252 | if (mode.equals(Camera.Mode.PHOTO) && !cameraFragment.getIsPhotoInterval()) { 253 | Camera.asyncTakePhoto(); 254 | } else if (mode.equals(Camera.Mode.VIDEO)) { 255 | mediaCapture = (Button) findViewById(R.id.video); 256 | if (mediaCapture.getText().equals(getString(R.string.video))) { 257 | Camera.asyncStartVideo(); 258 | } else { 259 | Camera.asyncStopVideo(); 260 | } 261 | } else { 262 | mediaCapture = (Button) findViewById(R.id.photo_interval); 263 | if (mediaCapture.getText().equals(getString(R.string.photo_interval))) { 264 | Camera.asyncStartPhotoInterval(Common.defaultPhotoIntervalInSeconds); 265 | } else { 266 | Camera.asyncStopPhotoInterval(); 267 | } 268 | } 269 | } 270 | } 271 | }); 272 | } 273 | 274 | public boolean isSt16() { 275 | return Build.MODEL.equals("anzhen4_mrd7_w"); 276 | } 277 | } 278 | 279 | -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/component/adapter/MediaListAdapter.java: -------------------------------------------------------------------------------- 1 | package com.yuneec.example.component.adapter; 2 | 3 | import android.content.Context; 4 | import android.graphics.Color; 5 | import android.support.v4.content.ContextCompat; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.BaseAdapter; 10 | import android.widget.TextView; 11 | 12 | import com.yuneec.example.R; 13 | import com.yuneec.example.component.fragment.CameraFragment; 14 | import com.yuneec.example.model.MediaInfoEntry; 15 | import com.yuneec.sdk.Camera; 16 | 17 | import java.util.ArrayList; 18 | 19 | /** 20 | * Created by sushmas on 8/29/17. 21 | */ 22 | 23 | public class MediaListAdapter 24 | extends BaseAdapter { 25 | 26 | private ArrayList entries; 27 | 28 | private LayoutInflater inflater; 29 | 30 | public MediaListAdapter(Context context, 31 | ArrayList list) { 32 | 33 | entries = list; 34 | inflater = LayoutInflater.from(context); 35 | } 36 | 37 | public MediaInfoEntry entryFromMediaInfo(Camera.MediaInfo mediaInfo) { 38 | 39 | MediaInfoEntry entry = new MediaInfoEntry(); 40 | entry.path = mediaInfo.path; 41 | entry.description = String.format("%.1f MiB", mediaInfo.size_mib); 42 | // We want to split "100MEDIA/YUN00001.jpg" to "YUN00001.jpg" 43 | String[] parts = entry.path.split("/"); 44 | entry.title = parts[1]; 45 | 46 | return entry; 47 | } 48 | 49 | public void setEntries(ArrayList list) { 50 | 51 | entries.clear(); 52 | for (Camera.MediaInfo item : list) { 53 | entries.add(entryFromMediaInfo(item)); 54 | } 55 | } 56 | 57 | @Override 58 | public int getCount() { 59 | 60 | return entries.size(); 61 | } 62 | 63 | @Override 64 | public MediaInfoEntry getItem(int index) { 65 | 66 | return entries.get(index); 67 | } 68 | 69 | @Override 70 | public long getItemId(int index) { 71 | 72 | return index; 73 | } 74 | 75 | public View getView(int index, 76 | View convertView, 77 | ViewGroup parent) { 78 | 79 | MediaListAdapter.ViewHolder holder; 80 | if (convertView == null) { 81 | convertView = inflater.inflate(R.layout.list_item, null); 82 | holder = new MediaListAdapter.ViewHolder(); 83 | holder.text1 = (TextView) convertView.findViewById(R.id.text1); 84 | holder.text2 = (TextView) convertView.findViewById(R.id.text2); 85 | 86 | convertView.setTag(holder); 87 | } else { 88 | holder = (MediaListAdapter.ViewHolder) convertView.getTag(); 89 | } 90 | 91 | MediaInfoEntry entry = entries.get(index); 92 | holder.text1.setText(entry.title); 93 | holder.text2.setText(entry.description); 94 | 95 | if (entry.downloaded) { 96 | convertView.setBackgroundColor(Color.parseColor("#F04C24")); 97 | holder.text1.setBackgroundColor(Color.parseColor("#F04C24")); 98 | holder.text2.setBackgroundColor(Color.parseColor("#F04C24")); 99 | } else { 100 | convertView.setBackgroundColor(Color.WHITE); 101 | holder.text1.setBackgroundColor(Color.WHITE); 102 | holder.text2.setBackgroundColor(Color.WHITE); 103 | } 104 | 105 | return convertView; 106 | } 107 | 108 | class ViewHolder { 109 | 110 | TextView text1, text2; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/component/custom_callback/OnChangeListener.java: -------------------------------------------------------------------------------- 1 | package com.yuneec.example.component.custom_callback; 2 | 3 | import com.yuneec.sdk.Camera; 4 | 5 | /** 6 | * Created by sushma on 8/18/17. 7 | */ 8 | 9 | public interface OnChangeListener { 10 | 11 | void publishConnectionStatus(String connectionStatus); 12 | 13 | void publishBatteryChangeStatus(String batteryStatus); 14 | 15 | void publishHealthChangeStatus(String healthStatus); 16 | 17 | void publishCameraResult(String result); 18 | 19 | void publishActionResult(String result); 20 | 21 | void publishYuneecSt16Result(String result); 22 | 23 | void publishCameraModeResult(Camera.Mode mode, String result); 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/component/custom_callback/VideoSurfaceHolderCallBack.java: -------------------------------------------------------------------------------- 1 | package com.yuneec.example.component.custom_callback; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | import android.view.Surface; 6 | import android.view.SurfaceHolder; 7 | 8 | import com.yuneec.example.component.utils.Common; 9 | 10 | /** 11 | * Created by sushma on 8/14/17. 12 | */ 13 | 14 | public class VideoSurfaceHolderCallBack 15 | implements SurfaceHolder.Callback { 16 | 17 | private Surface surface; 18 | 19 | private Context context; 20 | 21 | private final static String TAG = VideoSurfaceHolderCallBack.class.getCanonicalName(); 22 | 23 | @Override 24 | public void surfaceCreated(SurfaceHolder holder) { 25 | 26 | preparePlayer(); 27 | } 28 | 29 | @Override 30 | public void surfaceChanged(SurfaceHolder holder, 31 | int format, 32 | int width, 33 | int height) { 34 | 35 | surface = holder.getSurface(); 36 | Log.d(TAG, "Surface changed"); 37 | } 38 | 39 | @Override 40 | public void surfaceDestroyed(SurfaceHolder holder) { 41 | // TODO: remove player 42 | } 43 | 44 | public void preparePlayer() { 45 | // TODO: add player 46 | } 47 | 48 | 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/component/fragment/ActionFragment.java: -------------------------------------------------------------------------------- 1 | /** 2 | * ActionFragment.java 3 | * Yuneec-SDK-Android-Example 4 | *

5 | * Copyright @ 2016-2017 Yuneec. 6 | * All rights reserved. 7 | */ 8 | package com.yuneec.example.component.fragment; 9 | 10 | import android.os.Bundle; 11 | import android.support.v4.app.Fragment; 12 | import android.util.Log; 13 | import android.view.LayoutInflater; 14 | import android.view.ViewGroup; 15 | import android.view.View; 16 | import android.widget.EditText; 17 | import android.widget.Toast; 18 | 19 | import com.yuneec.example.R; 20 | import com.yuneec.example.component.listeners.ActionListener; 21 | import com.yuneec.example.component.utils.Media; 22 | import com.yuneec.sdk.Action; 23 | 24 | public class ActionFragment extends Fragment implements View.OnClickListener { 25 | /**Create view*/ 26 | View mView; 27 | /** Input for the takeoff altitude */ 28 | EditText setHeight; 29 | /** Get the fly height */ 30 | EditText getHeight; 31 | 32 | Action.ResultListener listener; 33 | 34 | private static final String TAG = ActionFragment.class.getCanonicalName(); 35 | 36 | @Override 37 | public View onCreateView(LayoutInflater inflater, 38 | ViewGroup container, Bundle savedInstanceState) { 39 | super.onCreate(savedInstanceState); 40 | initView(inflater, container); 41 | return mView; 42 | } 43 | 44 | @Override 45 | public void onStart() { 46 | 47 | super.onStart(); 48 | registerListener(); 49 | listener = ActionListener.getActionResultListener(getActivity()); 50 | } 51 | 52 | @Override 53 | public void onStop() { 54 | 55 | super.onStop(); 56 | unRegisterListener(); 57 | } 58 | 59 | private void initView(LayoutInflater inflater, 60 | ViewGroup container) { 61 | mView = inflater.inflate(R.layout.action_layout, container, false); 62 | mView.findViewById(R.id.arm_button).setOnClickListener(this); 63 | mView.findViewById(R.id.disarm_button).setOnClickListener(this); 64 | mView.findViewById(R.id.takeoff_button).setOnClickListener(this); 65 | mView.findViewById(R.id.land_button).setOnClickListener(this); 66 | mView.findViewById(R.id.return_to_launch_button).setOnClickListener(this); 67 | mView.findViewById(R.id.kill_button).setOnClickListener(this); 68 | setHeight = (EditText) mView.findViewById(R.id.takeoff_altitude); 69 | } 70 | 71 | private void registerListener() { 72 | ActionListener.registerActionListener(); 73 | } 74 | 75 | private void unRegisterListener() { 76 | ActionListener.unRegisterActionListener(); 77 | } 78 | 79 | @Override 80 | public void onClick(View v) { 81 | Media.vibrate(getActivity()); 82 | switch (v.getId()) { 83 | case R.id.arm_button: 84 | Action.armAsync(listener); 85 | break; 86 | case R.id.disarm_button: 87 | Action.disarmAsync(listener); 88 | break; 89 | case R.id.takeoff_button: 90 | if (!setHeight.getText().toString().trim().isEmpty()) { 91 | Double altitude = Double.parseDouble(setHeight.getText().toString()); 92 | Action.setAltitudeM(altitude); 93 | Log.d(TAG, "Altitude set"); 94 | } 95 | Action.takeoffAsync(listener); 96 | break; 97 | case R.id.land_button: 98 | Action.landAsync(listener); 99 | break; 100 | case R.id.return_to_launch_button: 101 | Action.returnToLaunchAsync(listener); 102 | break; 103 | case R.id.kill_button: 104 | Action.killAsync(listener); 105 | break; 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/component/fragment/CameraFragment.java: -------------------------------------------------------------------------------- 1 | /** 2 | * CameraFragment.java Yuneec-SDK-Android-Example 3 | *

4 | * Copyright @ 2016-2017 Yuneec. All rights reserved. 5 | */ 6 | 7 | package com.yuneec.example.component.fragment; 8 | 9 | import android.content.Context; 10 | import android.graphics.Color; 11 | import android.media.Ringtone; 12 | import android.media.RingtoneManager; 13 | import android.net.Uri; 14 | import android.os.Bundle; 15 | import android.support.v4.app.DialogFragment; 16 | import android.support.v4.app.Fragment; 17 | import android.support.v4.widget.SwipeRefreshLayout; 18 | import android.util.Log; 19 | import android.view.*; 20 | import android.widget.BaseAdapter; 21 | import android.widget.Button; 22 | import android.widget.TextView; 23 | import android.widget.Toast; 24 | 25 | import com.yuneec.example.R; 26 | import com.yuneec.example.component.custom_callback.VideoSurfaceHolderCallBack; 27 | import com.yuneec.example.component.listeners.CameraListener; 28 | import com.yuneec.example.component.listeners.CameraModeListener; 29 | import com.yuneec.example.component.utils.Common; 30 | import com.yuneec.example.component.utils.Media; 31 | import com.yuneec.sdk.Camera; 32 | import com.yuneec.videostreaming.RTSPPlayer; 33 | import com.yuneec.videostreaming.VideoPlayer; 34 | import com.yuneec.videostreaming.VideoPlayerException; 35 | 36 | import java.io.IOException; 37 | 38 | 39 | public class CameraFragment 40 | extends Fragment implements 41 | View.OnClickListener { 42 | 43 | private View rootView; 44 | 45 | private static final String TAG = CameraFragment.class.getCanonicalName(); 46 | 47 | private Toast toast = null; 48 | 49 | Button capturePicture; 50 | 51 | Button video; 52 | 53 | Button photoInterval; 54 | 55 | private Button cameraSettings; 56 | 57 | private Camera.Mode cameraMode = Camera.Mode.UNKNOWN; 58 | 59 | private boolean isPhotoInterval = false; 60 | 61 | private SurfaceView videoSurfaceView; 62 | 63 | private Surface videoSurface; 64 | 65 | private SurfaceHolder videoSurfaceHolder; 66 | 67 | private RTSPPlayer videoPlayer; 68 | 69 | 70 | public Camera.Mode getCameraMode() { 71 | return cameraMode; 72 | } 73 | 74 | public void setCameraMode(Camera.Mode cameraMode) { 75 | this.cameraMode = cameraMode; 76 | } 77 | 78 | public boolean getIsPhotoInterval() { 79 | return isPhotoInterval; 80 | } 81 | 82 | public void setIsPhotoInterval(boolean photoInterval) { 83 | isPhotoInterval = photoInterval; 84 | } 85 | 86 | @Override 87 | public void onCreate(Bundle savedInstanceState) { 88 | 89 | super.onCreate(savedInstanceState); 90 | } 91 | 92 | @Override 93 | public View onCreateView(LayoutInflater inflater, 94 | ViewGroup container, 95 | Bundle savedInstanceState) { 96 | 97 | super.onCreate(savedInstanceState); 98 | setRetainInstance(true); 99 | initViews(inflater, container); 100 | videoPlayer = (RTSPPlayer) VideoPlayer.getPlayer(VideoPlayer.PlayerType.LIVE_STREAM); 101 | addOnClickListeners(); 102 | return rootView; 103 | } 104 | 105 | @Override 106 | public void onStart() { 107 | super.onStart(); 108 | initVideoPlayer(); 109 | registerListeners(); 110 | } 111 | 112 | @Override 113 | public void onStop() { 114 | 115 | super.onStop(); 116 | deInitVideoPlayer(); 117 | unRegisterListeners(); 118 | } 119 | 120 | @Override 121 | public void onPause() { 122 | super.onPause(); 123 | try { 124 | videoPlayer.stop(); 125 | } catch (VideoPlayerException e) { 126 | e.printStackTrace(); 127 | } 128 | } 129 | 130 | @Override 131 | public void onResume() { 132 | super.onResume(); 133 | try { 134 | if (!videoPlayer.isPlaying()) { 135 | videoPlayer.start(); 136 | } 137 | } catch (VideoPlayerException e) { 138 | e.printStackTrace(); 139 | } 140 | } 141 | 142 | @Override 143 | public void onDestroyView() { 144 | super.onDestroyView(); 145 | } 146 | 147 | private void initVideoPlayer() { 148 | if (!Common.isConnected) { 149 | Common.makeToast(getActivity(), "Not connected to the drone!"); 150 | } else { 151 | videoPlayer.initializePlayer(); 152 | try { 153 | videoPlayer.setDataSource(Common.VideoStreamUrl); 154 | } catch (IOException e) { 155 | Log.e(TAG, e.getMessage()); 156 | e.printStackTrace(); 157 | } catch (VideoPlayerException e) { 158 | e.printStackTrace(); 159 | } 160 | } 161 | } 162 | 163 | private void deInitVideoPlayer() { 164 | try { 165 | videoPlayer.stop(); 166 | videoPlayer.releasePlayer(); 167 | } catch (VideoPlayerException e) { 168 | e.printStackTrace(); 169 | } 170 | } 171 | 172 | private void initViews(LayoutInflater inflater, 173 | ViewGroup container) { 174 | 175 | rootView = inflater.inflate(R.layout.camera_layout, container, false); 176 | capturePicture = (Button) rootView.findViewById(R.id.capturePicture); 177 | video = (Button) rootView.findViewById(R.id.video); 178 | photoInterval = (Button) rootView.findViewById(R.id.photo_interval); 179 | cameraSettings = (Button) rootView.findViewById(R.id.camera_settings); 180 | videoSurfaceView = (SurfaceView) rootView.findViewById(R.id.video_view); 181 | videoSurfaceHolder = videoSurfaceView.getHolder(); 182 | videoSurfaceHolder.addCallback(new SurfaceHolder.Callback() { 183 | 184 | @Override 185 | public void surfaceCreated(SurfaceHolder holder) { 186 | videoSurface = holder.getSurface(); 187 | try { 188 | videoPlayer.setSurface(videoSurface); 189 | } catch (VideoPlayerException e) { 190 | e.printStackTrace(); 191 | } 192 | } 193 | 194 | @Override 195 | public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 196 | videoSurface = holder.getSurface(); 197 | try { 198 | videoPlayer.setSurface(videoSurface); 199 | videoPlayer.start(); 200 | } catch (VideoPlayerException e) { 201 | e.printStackTrace(); 202 | } 203 | } 204 | 205 | @Override 206 | public void surfaceDestroyed(SurfaceHolder holder) { 207 | try { 208 | videoPlayer.setSurface(null); 209 | } catch (VideoPlayerException e) { 210 | e.printStackTrace(); 211 | } 212 | } 213 | }); 214 | } 215 | 216 | private void registerListeners() { 217 | CameraListener.registerCameraListener(getActivity()); 218 | CameraModeListener.registerCameraModeListener(getActivity()); 219 | } 220 | 221 | private void unRegisterListeners() { 222 | CameraModeListener.unRegisterCameraModeListener(); 223 | CameraListener.unRegisterCameraListener(); 224 | } 225 | 226 | 227 | private void addOnClickListeners() { 228 | capturePicture.setOnClickListener(this); 229 | video.setOnClickListener(this); 230 | photoInterval.setOnClickListener(this); 231 | cameraSettings.setOnClickListener(this); 232 | } 233 | 234 | @Override 235 | public void onClick(View v) { 236 | if (Common.isConnected) { 237 | Media.vibrate(getActivity()); 238 | switch (v.getId()) { 239 | case R.id.capturePicture: 240 | if (!getCameraMode().equals(Camera.Mode.PHOTO)) { 241 | Camera.setMode(Camera.Mode.PHOTO, CameraModeListener.getCameraModeListener()); 242 | } else { 243 | Camera.asyncTakePhoto(); 244 | } 245 | break; 246 | case R.id.video: 247 | if (!getCameraMode().equals(Camera.Mode.VIDEO)) { 248 | Camera.setMode(Camera.Mode.VIDEO, CameraModeListener.getCameraModeListener()); 249 | } else { 250 | if (video.getText().equals(getString(R.string.video))) { 251 | Camera.asyncStartVideo(); 252 | } else { 253 | Camera.asyncStopVideo(); 254 | } 255 | } 256 | break; 257 | case R.id.photo_interval: 258 | Media.vibrate(getActivity()); 259 | setIsPhotoInterval(true); 260 | if (!getCameraMode().equals(Camera.Mode.PHOTO)) { 261 | Camera.setMode(Camera.Mode.PHOTO, CameraModeListener.getCameraModeListener()); 262 | } else { 263 | if (photoInterval.getText().equals(getString(R.string.photo_interval))) { 264 | Camera.asyncStartPhotoInterval(Common.defaultPhotoIntervalInSeconds); 265 | } else { 266 | Camera.asyncStopPhotoInterval(); 267 | } 268 | } 269 | break; 270 | case R.id.camera_settings: 271 | DialogFragment settingsDialogFragment = new CameraSettingsFragment(); 272 | settingsDialogFragment.show(getFragmentManager(), "settings"); 273 | Media.vibrate(getActivity()); 274 | break; 275 | } 276 | } else { 277 | Common.makeToast(getActivity(), "Please Connect To The Drone"); 278 | } 279 | 280 | 281 | } 282 | } 283 | -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/component/fragment/CameraSettingsFragment.java: -------------------------------------------------------------------------------- 1 | /** 2 | * CameraSettingsFragment.java 3 | * Yuneec-SDK-Android-Example 4 | *

5 | * Copyright @ 2016-2017 Yuneec. 6 | * All rights reserved. 7 | */ 8 | package com.yuneec.example.component.fragment; 9 | 10 | import android.os.Bundle; 11 | import android.support.v4.app.DialogFragment; 12 | import android.support.v4.app.Fragment; 13 | import android.util.Log; 14 | import android.view.LayoutInflater; 15 | import android.view.ViewGroup; 16 | import android.view.View; 17 | import android.view.WindowManager; 18 | import android.widget.AdapterView; 19 | import android.widget.ArrayAdapter; 20 | import android.widget.Button; 21 | import android.widget.EditText; 22 | import android.widget.Spinner; 23 | import android.widget.TextView; 24 | 25 | import com.yuneec.example.R; 26 | import com.yuneec.example.component.listeners.CameraModeListener; 27 | import com.yuneec.example.component.listeners.CameraSettingsListener; 28 | import com.yuneec.example.component.utils.Common; 29 | import com.yuneec.example.component.utils.Media; 30 | import com.yuneec.example.view.CustomButton; 31 | import com.yuneec.example.view.CustomEditTextView; 32 | import com.yuneec.example.view.CustomTextView; 33 | import com.yuneec.sdk.Camera; 34 | 35 | import java.util.ArrayList; 36 | import java.util.EnumSet; 37 | import java.util.List; 38 | 39 | public class CameraSettingsFragment extends DialogFragment implements View.OnClickListener, 40 | AdapterView.OnItemSelectedListener { 41 | 42 | View rootView; 43 | 44 | Spinner wb_spinner; 45 | 46 | Spinner color_mode_spinner; 47 | 48 | Spinner exposure_spinner; 49 | 50 | Spinner ex_com_spinner; 51 | 52 | Spinner shutter_speed_spinner; 53 | 54 | Spinner iso_spinner; 55 | 56 | TextView ex_com_view; 57 | 58 | TextView iso_view; 59 | 60 | TextView shutter_speed_view; 61 | 62 | Camera.ShutterSpeedS shutterSpeedS = new Camera.ShutterSpeedS(); 63 | 64 | Spinner photo_format_spinner; 65 | 66 | Spinner photo_quality_spinner; 67 | 68 | Spinner video_format_spinner; 69 | 70 | Spinner video_resolution_spinner; 71 | 72 | Spinner metering_spinner; 73 | 74 | CustomTextView photo_format_text; 75 | 76 | CustomTextView photo_quality_text; 77 | 78 | CustomTextView video_format_text; 79 | 80 | CustomTextView video_resolution_text; 81 | 82 | CustomTextView metering_text; 83 | 84 | CustomTextView resolution_text; 85 | 86 | CustomButton photo_format; 87 | 88 | CustomButton photo_quality; 89 | 90 | CustomButton video_format; 91 | 92 | CustomButton video_resolution; 93 | 94 | CustomButton metering; 95 | 96 | CustomButton resolution; 97 | 98 | private static final String TAG = CameraSettingsListener.class.getCanonicalName(); 99 | 100 | 101 | @Override 102 | public View onCreateView(LayoutInflater inflater, 103 | ViewGroup container, Bundle savedInstanceState) { 104 | super.onCreate(savedInstanceState); 105 | setRetainInstance(true); 106 | getDialog().setTitle("Camera Settings"); 107 | getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); 108 | initViews(inflater, container, savedInstanceState); 109 | return rootView; 110 | } 111 | 112 | @Override 113 | public void onStart() { 114 | super.onStart(); 115 | CameraSettingsListener.registerSettingsListener(); 116 | addOnClickListeners(); 117 | } 118 | 119 | @Override 120 | public void onStop() { 121 | 122 | super.onStop(); 123 | CameraSettingsListener.unRegisterCameraSettingsListeners(); 124 | } 125 | 126 | @Override 127 | public void onSaveInstanceState(Bundle outState) { 128 | super.onSaveInstanceState(outState); 129 | outState.putInt("wbSpinner", wb_spinner.getSelectedItemPosition()); 130 | outState.putInt("colorModeSpinner", color_mode_spinner.getSelectedItemPosition()); 131 | outState.putInt("exposureSpinner", exposure_spinner.getSelectedItemPosition()); 132 | outState.putInt("exComSpinner", ex_com_spinner.getSelectedItemPosition()); 133 | if (iso_spinner.getVisibility() == View.VISIBLE) { 134 | outState.putInt("isoSpinner", iso_spinner.getSelectedItemPosition()); 135 | } 136 | if (shutter_speed_spinner.getVisibility() == View.VISIBLE) { 137 | outState.putInt("shutterSpeedSpinner", shutter_speed_spinner.getSelectedItemPosition()); 138 | } 139 | } 140 | 141 | private void initViews(LayoutInflater inflater, 142 | ViewGroup container, Bundle savedInstanceState) { 143 | rootView = inflater.inflate(R.layout.camera_setting_layout, container, false); 144 | wb_spinner = (Spinner) rootView.findViewById(R.id.wb_dropdown); 145 | color_mode_spinner = (Spinner) rootView.findViewById(R.id.color_mode_dropdown); 146 | exposure_spinner = (Spinner) rootView.findViewById(R.id.exposure_mode_dropdown); 147 | ex_com_spinner = (Spinner) rootView.findViewById(R.id.exposure_com_dropdown); 148 | shutter_speed_spinner = (Spinner) rootView.findViewById(R.id.shutter_speed_dropdown); 149 | iso_spinner = (Spinner) rootView.findViewById(R.id.iso_dropdown); 150 | ex_com_view = (TextView) rootView.findViewById(R.id.ex_com_text); 151 | iso_view = (TextView) rootView.findViewById(R.id.iso_val); 152 | shutter_speed_view = (TextView) rootView.findViewById(R.id.shutter_speed); 153 | if (savedInstanceState != null) { 154 | wb_spinner.setSelection(savedInstanceState.getInt("wbSpinner")); 155 | color_mode_spinner.setSelection(savedInstanceState.getInt("colorModeSpinner")); 156 | exposure_spinner.setSelection(savedInstanceState.getInt("exposureSpinner")); 157 | ex_com_spinner.setSelection(savedInstanceState.getInt("exComSpinner")); 158 | if (iso_spinner.getVisibility() == View.VISIBLE) { 159 | iso_spinner.setSelection(savedInstanceState.getInt("isoSpinner")); 160 | } 161 | if (shutter_speed_spinner.getVisibility() == View.VISIBLE) { 162 | shutter_speed_spinner.setSelection(savedInstanceState.getInt("shutterSpeedSpinner")); 163 | } 164 | } 165 | photo_format_spinner = (Spinner) rootView.findViewById(R.id.photo_format_dropdown); 166 | photo_quality_spinner = (Spinner) rootView.findViewById(R.id.photo_quality_dropdown); 167 | video_format_spinner = (Spinner) rootView.findViewById(R.id.video_format_dropdown); 168 | video_resolution_spinner = (Spinner) rootView.findViewById(R.id.video_resolution_dropdown); 169 | metering_spinner = (Spinner) rootView.findViewById(R.id.metering_dropdown); 170 | 171 | photo_format_text = (CustomTextView) rootView.findViewById(R.id.photo_format_text); 172 | photo_quality_text = (CustomTextView) rootView.findViewById(R.id.photo_quality_text); 173 | video_format_text = (CustomTextView) rootView.findViewById(R.id.video_format_text); 174 | video_resolution_text = (CustomTextView) rootView.findViewById(R.id.video_resolution_text); 175 | resolution_text = (CustomTextView) rootView.findViewById(R.id.resolution_text); 176 | metering_text = (CustomTextView) rootView.findViewById(R.id.metering_text); 177 | 178 | photo_format = (CustomButton) rootView.findViewById(R.id.get_photo_format); 179 | photo_quality = (CustomButton) rootView.findViewById(R.id.get_photo_quality); 180 | video_format = (CustomButton) rootView.findViewById(R.id.get_video_format); 181 | video_resolution = (CustomButton) rootView.findViewById(R.id.get_video_resolution); 182 | resolution = (CustomButton) rootView.findViewById(R.id.get_resolution); 183 | metering = (CustomButton) rootView.findViewById(R.id.get_metering); 184 | } 185 | 186 | private void addOnClickListeners() { 187 | addItemsOnSpinner(); 188 | /* work around for https://stackoverflow.com/questions/2562248/how-to-keep-onitemselected-from-firing-off-on-a-newly-instantiated-spinner*/ 189 | setSelection(); 190 | wb_spinner.setOnItemSelectedListener(this); 191 | color_mode_spinner.setOnItemSelectedListener(this); 192 | exposure_spinner.setOnItemSelectedListener(this); 193 | ex_com_spinner.setOnItemSelectedListener(this); 194 | shutter_speed_spinner.setOnItemSelectedListener(this); 195 | iso_spinner.setOnItemSelectedListener(this); 196 | photo_format_spinner.setOnItemSelectedListener(this); 197 | photo_quality_spinner.setOnItemSelectedListener(this); 198 | video_format_spinner.setOnItemSelectedListener(this); 199 | video_resolution_spinner.setOnItemSelectedListener(this); 200 | metering_spinner.setOnItemSelectedListener(this); 201 | photo_format.setOnClickListener(this); 202 | photo_quality.setOnClickListener(this); 203 | video_format.setOnClickListener(this); 204 | video_resolution.setOnClickListener(this); 205 | resolution.setOnClickListener(this); 206 | metering.setOnClickListener(this); 207 | } 208 | 209 | private void setSelection() { 210 | wb_spinner.setSelection(0, false); 211 | color_mode_spinner.setSelection(0, false); 212 | exposure_spinner.setSelection(0, false); 213 | ex_com_spinner.setSelection(0, false); 214 | shutter_speed_spinner.setSelection(0, false); 215 | iso_spinner.setSelection(0, false); 216 | photo_format_spinner.setSelection(0, false); 217 | photo_quality_spinner.setSelection(0, false); 218 | video_format_spinner.setSelection(0, false); 219 | video_resolution_spinner.setSelection(0, false); 220 | metering_spinner.setSelection(0, false); 221 | } 222 | 223 | public void addItemsOnSpinner() { 224 | List wbList = 225 | new ArrayList<>(EnumSet.allOf(Camera.WhiteBalance.class)); 226 | ArrayAdapter wbAdapter = new ArrayAdapter<>(getActivity(), 227 | R.layout.spinner_item, wbList); 228 | wb_spinner.setAdapter(wbAdapter); 229 | 230 | List colorModeList = 231 | new ArrayList<>(EnumSet.allOf(Camera.ColorMode.class)); 232 | ArrayAdapter colorModeAdapter = new ArrayAdapter<>(getActivity(), 233 | R.layout.spinner_item, colorModeList); 234 | color_mode_spinner.setAdapter(colorModeAdapter); 235 | 236 | List exposureModeList = 237 | new ArrayList<>(EnumSet.allOf(Camera.ExposureMode.class)); 238 | ArrayAdapter exposureModeAdapter = new ArrayAdapter<>(getActivity(), 239 | R.layout.spinner_item, exposureModeList); 240 | exposure_spinner.setAdapter(exposureModeAdapter); 241 | 242 | List exposureComList = new ArrayList<>(); 243 | exposureComList.add(-2.0f); 244 | exposureComList.add(-1.5f); 245 | exposureComList.add(-1.0f); 246 | exposureComList.add(-0.5f); 247 | exposureComList.add(0.0f); 248 | exposureComList.add(0.5f); 249 | exposureComList.add(1.0f); 250 | exposureComList.add(1.5f); 251 | exposureComList.add(2.0f); 252 | 253 | ArrayAdapter exposureComAdapter = new ArrayAdapter<>(getActivity(), 254 | R.layout.spinner_item, exposureComList); 255 | ex_com_spinner.setAdapter(exposureComAdapter); 256 | 257 | List isoValLIst = new ArrayList<>(); 258 | 259 | isoValLIst.add(100); 260 | isoValLIst.add(150); 261 | isoValLIst.add(200); 262 | isoValLIst.add(300); 263 | isoValLIst.add(400); 264 | isoValLIst.add(600); 265 | isoValLIst.add(800); 266 | isoValLIst.add(1600); 267 | isoValLIst.add(3200); 268 | 269 | ArrayAdapter isoAdapter = new ArrayAdapter<>(getActivity(), 270 | R.layout.spinner_item, isoValLIst); 271 | iso_spinner.setAdapter(isoAdapter); 272 | 273 | 274 | List shutterSpeedList = new ArrayList<>(); 275 | shutterSpeedList.add("4"); 276 | shutterSpeedList.add("3"); 277 | shutterSpeedList.add("2"); 278 | shutterSpeedList.add("1"); 279 | shutterSpeedList.add("1/30"); 280 | shutterSpeedList.add("1/60"); 281 | shutterSpeedList.add("1/125"); 282 | shutterSpeedList.add("1/250"); 283 | shutterSpeedList.add("1/500"); 284 | shutterSpeedList.add("1/1000"); 285 | shutterSpeedList.add("1/2000"); 286 | shutterSpeedList.add("1/4000"); 287 | shutterSpeedList.add("1/8000"); 288 | 289 | 290 | 291 | ArrayAdapter shutterSpeedAdapter = new ArrayAdapter<>(getActivity(), 292 | R.layout.spinner_item, shutterSpeedList); 293 | shutter_speed_spinner.setAdapter(shutterSpeedAdapter); 294 | 295 | List photoQualityList = 296 | new ArrayList<>(EnumSet.allOf(Camera.PhotoQuality.class)); 297 | ArrayAdapter photoQualityArrayAdapter = new ArrayAdapter<>(getActivity(), 298 | R.layout.spinner_item, photoQualityList); 299 | photo_quality_spinner.setAdapter(photoQualityArrayAdapter); 300 | 301 | List photoFormatList = 302 | new ArrayList<>(EnumSet.allOf(Camera.PhotoFormat.class)); 303 | ArrayAdapter photoFormatArrayAdapter = new ArrayAdapter<>(getActivity(), 304 | R.layout.spinner_item, photoFormatList); 305 | photo_format_spinner.setAdapter(photoFormatArrayAdapter); 306 | 307 | List videoFormatList = 308 | new ArrayList<>(EnumSet.allOf(Camera.VideoFormat.class)); 309 | ArrayAdapter videoFormatArrayAdapter = new ArrayAdapter<>(getActivity(), 310 | R.layout.spinner_item, videoFormatList); 311 | video_format_spinner.setAdapter(videoFormatArrayAdapter); 312 | 313 | List videoResolutionList = 314 | new ArrayList<>(EnumSet.allOf(Camera.VideoResolution.class)); 315 | ArrayAdapter videoResolutionArrayAdapter = new ArrayAdapter<>(getActivity(), 316 | R.layout.spinner_item, videoResolutionList); 317 | video_resolution_spinner.setAdapter(videoResolutionArrayAdapter); 318 | 319 | List meteringList = 320 | new ArrayList<>(EnumSet.allOf(Camera.Metering.Mode.class)); 321 | ArrayAdapter meteringArrayAdapter = new ArrayAdapter<>(getActivity(), 322 | R.layout.spinner_item, meteringList); 323 | metering_spinner.setAdapter(meteringArrayAdapter); 324 | } 325 | 326 | 327 | @Override 328 | public void onClick(View v) { 329 | if (Common.isConnected) { 330 | Media.vibrate(getActivity()); 331 | switch (v.getId()) { 332 | case R.id.get_resolution: 333 | Log.d(TAG, "resolution button clicked"); 334 | Camera.getResolution(CameraSettingsListener.getResolutionListener()); 335 | break; 336 | 337 | case R.id.get_photo_format: 338 | Log.d(TAG, "photo format button clicked"); 339 | Camera.getPhotoFormat(CameraSettingsListener.getPhotoFormatListener()); 340 | break; 341 | 342 | case R.id.get_photo_quality: 343 | Log.d(TAG, "photo quality button clicked"); 344 | Camera.getPhotoQuality(CameraSettingsListener.getPhotoQualityListener()); 345 | break; 346 | 347 | case R.id.get_video_format: 348 | Log.d(TAG, "video format button clicked"); 349 | Camera.getVideoFormat(CameraSettingsListener.getVideoFormatListener()); 350 | break; 351 | 352 | case R.id.get_video_resolution: 353 | Log.d(TAG, "video resolution button clicked"); 354 | Camera.getVideoResolution(CameraSettingsListener.getVideoResolutionListener()); 355 | break; 356 | 357 | case R.id.get_metering: 358 | Log.d(TAG, "metering button clicked"); 359 | Camera.getMetering(CameraSettingsListener.getMeteringListener()); 360 | break; 361 | } 362 | } else { 363 | Common.makeToast(getActivity(), "Please Connect To The Drone"); 364 | } 365 | } 366 | 367 | @Override 368 | public void onItemSelected(AdapterView adapterView, View view, int i, long l) { 369 | Media.vibrate(getActivity()); 370 | switch (adapterView.getId()) { 371 | case R.id.wb_dropdown: 372 | Log.d(TAG, "wb selected"); 373 | Camera.WhiteBalance wbSelection = (Camera.WhiteBalance) wb_spinner.getSelectedItem(); 374 | Camera.setWhiteBalance(wbSelection, CameraSettingsListener.getWhiteBalanceListener()); 375 | break; 376 | case R.id.color_mode_dropdown: 377 | Log.d(TAG, "color mode selected"); 378 | Camera.ColorMode colorModeSelection = (Camera.ColorMode) color_mode_spinner.getSelectedItem(); 379 | Camera.setColorMode(colorModeSelection, CameraSettingsListener.getColorModeListener()); 380 | break; 381 | case R.id.exposure_mode_dropdown: 382 | Log.d(TAG, "em selected"); 383 | Camera.ExposureMode exposureModeSelection = (Camera.ExposureMode) 384 | exposure_spinner.getSelectedItem(); 385 | if (exposureModeSelection == Camera.ExposureMode.AUTO 386 | || exposureModeSelection == Camera.ExposureMode.UNKNOWN) { 387 | ex_com_spinner.setVisibility(View.VISIBLE); 388 | ex_com_view.setVisibility(View.VISIBLE); 389 | iso_view.setVisibility(View.GONE); 390 | iso_spinner.setVisibility(View.GONE); 391 | shutter_speed_spinner.setVisibility(View.GONE); 392 | shutter_speed_view.setVisibility(View.GONE); 393 | Camera.setExposureMode(exposureModeSelection, CameraSettingsListener.getExposureModeListener()); 394 | } else { 395 | ex_com_spinner.setVisibility(View.GONE); 396 | ex_com_view.setVisibility(View.GONE); 397 | iso_spinner.setVisibility(View.VISIBLE); 398 | iso_view.setVisibility(View.VISIBLE); 399 | shutter_speed_spinner.setVisibility(View.VISIBLE); 400 | shutter_speed_view.setVisibility(View.VISIBLE); 401 | Camera.setExposureMode(exposureModeSelection, CameraSettingsListener.getExposureModeListener()); 402 | } 403 | break; 404 | case R.id.exposure_com_dropdown: 405 | Log.d(TAG, "eval selected"); 406 | Float exposure_com_selection = (Float) ex_com_spinner.getSelectedItem(); 407 | Camera.setExposureValue(exposure_com_selection, CameraSettingsListener.getExposureValueListener()); 408 | break; 409 | case R.id.iso_dropdown: 410 | Log.d(TAG, "iso selected"); 411 | int iso_selection = (int) iso_spinner.getSelectedItem(); 412 | Camera.setISOValue(iso_selection, CameraSettingsListener.getIsoValueListener()); 413 | break; 414 | case R.id.shutter_speed_dropdown: 415 | Log.d(TAG, "shutter speed selected"); 416 | switch (shutter_speed_spinner.getSelectedItemPosition() + 1) { 417 | case 1: 418 | shutterSpeedS.numerator = 4; 419 | shutterSpeedS.denominator = 1; 420 | Log.d(TAG, shutterSpeedS.denominator + ""); 421 | Camera.setShutterSpeed(shutterSpeedS, CameraSettingsListener.getShutterSpeedListener()); 422 | break; 423 | case 2: 424 | shutterSpeedS.numerator = 3; 425 | shutterSpeedS.denominator = 1; 426 | Log.d(TAG, shutterSpeedS.denominator + ""); 427 | Camera.setShutterSpeed(shutterSpeedS, CameraSettingsListener.getShutterSpeedListener()); 428 | break; 429 | case 3: 430 | shutterSpeedS.numerator = 2; 431 | shutterSpeedS.denominator = 1; 432 | Log.d(TAG, shutterSpeedS.denominator + ""); 433 | Camera.setShutterSpeed(shutterSpeedS, CameraSettingsListener.getShutterSpeedListener()); 434 | break; 435 | case 4: 436 | shutterSpeedS.numerator = 1; 437 | shutterSpeedS.denominator = 1; 438 | Log.d(TAG, shutterSpeedS.denominator + ""); 439 | Camera.setShutterSpeed(shutterSpeedS, CameraSettingsListener.getShutterSpeedListener()); 440 | break; 441 | case 5: 442 | shutterSpeedS.numerator = 1; 443 | shutterSpeedS.denominator = 30; 444 | Log.d(TAG, shutterSpeedS.denominator + ""); 445 | Camera.setShutterSpeed(shutterSpeedS, CameraSettingsListener.getShutterSpeedListener()); 446 | break; 447 | case 6: 448 | shutterSpeedS.numerator = 1; 449 | shutterSpeedS.denominator = 60; 450 | Log.d(TAG, shutterSpeedS.denominator + ""); 451 | Camera.setShutterSpeed(shutterSpeedS, CameraSettingsListener.getShutterSpeedListener()); 452 | break; 453 | case 7: 454 | shutterSpeedS.numerator = 1; 455 | shutterSpeedS.denominator = 125; 456 | Log.d(TAG, shutterSpeedS.denominator + ""); 457 | Camera.setShutterSpeed(shutterSpeedS, CameraSettingsListener.getShutterSpeedListener()); 458 | break; 459 | case 8: 460 | shutterSpeedS.numerator = 1; 461 | shutterSpeedS.denominator = 250; 462 | Log.d(TAG, shutterSpeedS.denominator + ""); 463 | Camera.setShutterSpeed(shutterSpeedS, CameraSettingsListener.getShutterSpeedListener()); 464 | break; 465 | case 9: 466 | shutterSpeedS.numerator = 1; 467 | shutterSpeedS.denominator = 500; 468 | Log.d(TAG, shutterSpeedS.denominator + ""); 469 | Camera.setShutterSpeed(shutterSpeedS, CameraSettingsListener.getShutterSpeedListener()); 470 | break; 471 | case 10: 472 | shutterSpeedS.numerator = 1; 473 | shutterSpeedS.denominator = 1000; 474 | Log.d(TAG, shutterSpeedS.denominator + ""); 475 | Camera.setShutterSpeed(shutterSpeedS, CameraSettingsListener.getShutterSpeedListener()); 476 | break; 477 | case 11: 478 | shutterSpeedS.numerator = 1; 479 | shutterSpeedS.denominator = 2000; 480 | Log.d(TAG, shutterSpeedS.denominator + ""); 481 | Camera.setShutterSpeed(shutterSpeedS, CameraSettingsListener.getShutterSpeedListener()); 482 | break; 483 | case 12: 484 | shutterSpeedS.numerator = 1; 485 | shutterSpeedS.denominator = 4000; 486 | Log.d(TAG, shutterSpeedS.denominator + ""); 487 | Camera.setShutterSpeed(shutterSpeedS, CameraSettingsListener.getShutterSpeedListener()); 488 | break; 489 | case 13: 490 | shutterSpeedS.numerator = 1; 491 | shutterSpeedS.denominator = 8000; 492 | Log.d(TAG, shutterSpeedS.denominator + ""); 493 | Camera.setShutterSpeed(shutterSpeedS, CameraSettingsListener.getShutterSpeedListener()); 494 | break; 495 | } 496 | break; 497 | case R.id.photo_format_dropdown: 498 | Log.d(TAG, "photo format selected"); 499 | Camera.PhotoFormat photoFormatSelection = (Camera.PhotoFormat) 500 | photo_format_spinner.getSelectedItem(); 501 | Camera.setPhotoFormat(photoFormatSelection, CameraSettingsListener.getPhotoFormatListener()); 502 | break; 503 | 504 | case R.id.photo_quality_dropdown: 505 | Log.d(TAG, "photo quality selected"); 506 | Camera.PhotoQuality photoQualitySelection = (Camera.PhotoQuality) 507 | photo_quality_spinner.getSelectedItem(); 508 | Camera.setPhotoQuality(photoQualitySelection, CameraSettingsListener.getPhotoQualityListener()); 509 | break; 510 | 511 | case R.id.video_format_dropdown: 512 | Log.d(TAG, "video format selected"); 513 | Camera.VideoFormat videoFormatSelection = (Camera.VideoFormat) 514 | video_format_spinner.getSelectedItem(); 515 | Camera.setVideoFormat(videoFormatSelection, CameraSettingsListener.getVideoFormatListener()); 516 | break; 517 | 518 | case R.id.video_resolution_dropdown: 519 | Log.d(TAG, "video resolution selected"); 520 | Camera.VideoResolution videoResolutionSelection = (Camera.VideoResolution) 521 | video_resolution_spinner.getSelectedItem(); 522 | Camera.setVideoResolution(videoResolutionSelection, 523 | CameraSettingsListener.getVideoResolutionListener()); 524 | break; 525 | case R.id.metering_dropdown: 526 | Log.d(TAG, "metering selected"); 527 | Camera.Metering metering = new Camera.Metering(); 528 | metering.mode = (Camera.Metering.Mode)metering_spinner.getSelectedItem(); 529 | Camera.setMetering(metering, CameraSettingsListener.getMeteringListener()); 530 | break; 531 | 532 | } 533 | 534 | } 535 | 536 | @Override 537 | public void onNothingSelected(AdapterView adapterView) { 538 | 539 | } 540 | } -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/component/fragment/ConnectionFragment.java: -------------------------------------------------------------------------------- 1 | package com.yuneec.example.component.fragment; 2 | 3 | 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | import android.support.v4.app.Fragment; 7 | import android.util.Log; 8 | import android.view.LayoutInflater; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import android.widget.TextView; 12 | 13 | import com.yuneec.example.R; 14 | import com.yuneec.example.component.listeners.CameraListener; 15 | import com.yuneec.example.component.listeners.TelemetryListener; 16 | import com.yuneec.example.component.utils.Common; 17 | 18 | /** 19 | * Created by sushma on 8/16/17. 20 | */ 21 | 22 | public class ConnectionFragment 23 | extends Fragment 24 | 25 | { 26 | 27 | private View rootView; 28 | 29 | TextView connectionStateView; 30 | 31 | TextView batteryStateView; 32 | 33 | TextView droneHealthView; 34 | 35 | private static final String TAG = ConnectionFragment.class.getCanonicalName(); 36 | 37 | 38 | @Override 39 | public void onCreate(Bundle savedInstanceState) { 40 | 41 | super.onCreate(savedInstanceState); 42 | Log.d(TAG, "on create"); 43 | } 44 | 45 | @Nullable 46 | @Override 47 | public View onCreateView(LayoutInflater inflater, 48 | ViewGroup container, 49 | Bundle savedInstanceState) { 50 | 51 | setRetainInstance(true); 52 | initViews(inflater, container); 53 | Log.d(TAG, "on create view"); 54 | return rootView; 55 | } 56 | 57 | @Override 58 | public void onStart() { 59 | 60 | super.onStart(); 61 | registerListeners(); 62 | 63 | } 64 | 65 | @Override 66 | public void onStop() { 67 | 68 | super.onStop(); 69 | unRegisterListeners(); 70 | } 71 | 72 | @Override 73 | public void onDestroyView() { 74 | 75 | super.onDestroyView(); 76 | } 77 | 78 | @Override 79 | public void onPause() { 80 | 81 | super.onPause(); 82 | } 83 | 84 | @Override 85 | public void onResume() { 86 | 87 | super.onResume(); 88 | } 89 | 90 | private void registerListeners() { 91 | 92 | TelemetryListener.registerBatteryListener(getActivity()); 93 | TelemetryListener.registerHealthListener(getActivity()); 94 | } 95 | 96 | private void unRegisterListeners() { 97 | 98 | TelemetryListener.unRegisterBatteryListener(); 99 | TelemetryListener.unRegisterHealthListener(); 100 | } 101 | 102 | @Override 103 | public void onViewStateRestored( 104 | @Nullable 105 | Bundle savedInstanceState) { 106 | 107 | super.onViewStateRestored(savedInstanceState); 108 | Log.d(TAG, "on restore"); 109 | connectionStateView.setText(Common.connectionStatus); 110 | batteryStateView.setText(Common.batteryStatus); 111 | droneHealthView.setText(Common.healthStatus); 112 | } 113 | 114 | private void initViews(LayoutInflater inflater, 115 | ViewGroup container) { 116 | 117 | rootView = inflater.inflate(R.layout.connection_layout, container, false); 118 | connectionStateView = (TextView) rootView.findViewById(R.id.connection_state); 119 | batteryStateView = (TextView) rootView.findViewById(R.id.battery_status); 120 | droneHealthView = (TextView) rootView.findViewById(R.id.health_status); 121 | } 122 | 123 | 124 | public void setConnectionStateView(String connectionStatus) { 125 | 126 | Common.connectionStatus = connectionStatus; 127 | connectionStateView.setText(connectionStatus); 128 | Log.d(TAG, "connection view text set"); 129 | } 130 | 131 | public void setBatterStateView(String batteryStatus) { 132 | 133 | Common.batteryStatus = batteryStatus; 134 | batteryStateView.setText(batteryStatus); 135 | } 136 | 137 | public void setDroneHealthView(String healthStatus) { 138 | 139 | Common.healthStatus = healthStatus; 140 | droneHealthView.setText(healthStatus); 141 | } 142 | 143 | 144 | } 145 | -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/component/fragment/GimbalFragment.java: -------------------------------------------------------------------------------- 1 | package com.yuneec.example.component.fragment; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v4.app.Fragment; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.Button; 10 | import android.widget.EditText; 11 | 12 | import com.yuneec.example.R; 13 | import com.yuneec.example.component.listeners.GimbalListener; 14 | import com.yuneec.example.component.utils.Common; 15 | import com.yuneec.example.component.utils.Media; 16 | import com.yuneec.sdk.Gimbal; 17 | 18 | /** 19 | * Created by sushma on 8/15/17. 20 | */ 21 | 22 | public class GimbalFragment 23 | extends Fragment 24 | implements View.OnClickListener { 25 | 26 | private View rootView; 27 | 28 | private Button rotateClockwise; 29 | 30 | private Button rotateToInitial; 31 | 32 | private EditText yawVal; 33 | 34 | private EditText pitchVal; 35 | 36 | private Button setPitch; 37 | 38 | @Override 39 | public void onCreate(Bundle savedInstanceState) { 40 | 41 | super.onCreate(savedInstanceState); 42 | } 43 | 44 | @Nullable 45 | @Override 46 | public View onCreateView(LayoutInflater inflater, 47 | ViewGroup container, 48 | Bundle savedInstanceState) { 49 | 50 | setRetainInstance(true); 51 | 52 | initViews(inflater, container); 53 | return rootView; 54 | } 55 | 56 | @Override 57 | public void onStart() { 58 | 59 | super.onStart(); 60 | registerListener(); 61 | } 62 | 63 | @Override 64 | public void onStop() { 65 | 66 | super.onStop(); 67 | unRegisterListener(); 68 | } 69 | 70 | 71 | private void initViews(LayoutInflater inflater, 72 | ViewGroup container) { 73 | 74 | rootView = inflater.inflate(R.layout.gimbal_layout, container, false); 75 | rotateClockwise = (Button) rootView.findViewById(R.id.rotate_camera_clockwise); 76 | rotateClockwise.setOnClickListener(this); 77 | yawVal = (EditText) rootView.findViewById(R.id.yaw_degree); 78 | pitchVal = (EditText) rootView.findViewById(R.id.pitch_degree); 79 | rotateToInitial = (Button) rootView.findViewById(R.id.rotate_to_initial); 80 | rotateToInitial.setOnClickListener(this); 81 | setPitch = (Button) rootView.findViewById(R.id.set_pitch); 82 | setPitch.setOnClickListener(this); 83 | } 84 | 85 | private void registerListener() { 86 | 87 | GimbalListener.registerGimbalListener(); 88 | } 89 | 90 | private void unRegisterListener() { 91 | 92 | GimbalListener.unRegisterGimbalListener(); 93 | } 94 | 95 | @Override 96 | public void onClick(View v) { 97 | 98 | switch (v.getId()) { 99 | case R.id.rotate_camera_clockwise: 100 | Media.vibrate(getActivity()); 101 | if (yawVal.getText().toString().isEmpty()) { 102 | Common.makeToast(getActivity(), "Please enter yaw degree, before clicking rotate button"); 103 | } else { 104 | try { 105 | float yawDeg = Float.parseFloat(yawVal.getText().toString()); 106 | Gimbal.asyncSetPitchAndYawOfJni(Common.currentPitch, yawDeg, 107 | GimbalListener.getGimbaListener()); 108 | Common.currentYaw = yawDeg; 109 | } catch (Exception e) { 110 | Common.makeToast(getActivity(), "Please enter a valid value for yaw degree"); 111 | } 112 | } 113 | 114 | break; 115 | case R.id.rotate_to_initial: 116 | Media.vibrate(getActivity()); 117 | Gimbal.asyncSetPitchAndYawOfJni(0, 0, GimbalListener.getGimbaListener()); 118 | Common.currentYaw = 0; 119 | Common.currentPitch = 0; 120 | break; 121 | case R.id.set_pitch: 122 | Media.vibrate(getActivity()); 123 | if (pitchVal.getText().toString().isEmpty()) { 124 | Common.makeToast(getActivity(), "Please enter pitch degree, before clicking rotate button"); 125 | } else { 126 | try { 127 | float pitchDeg = Float.parseFloat(pitchVal.getText().toString()); 128 | Gimbal.asyncSetPitchAndYawOfJni(pitchDeg, Common.currentYaw, 129 | GimbalListener.getGimbaListener()); 130 | Common.currentPitch = pitchDeg; 131 | } catch (Exception e) { 132 | Common.makeToast(getActivity(), "Please enter a valid value for pitch degree"); 133 | } 134 | } 135 | 136 | break; 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/component/fragment/MediaDownloadFragment.java: -------------------------------------------------------------------------------- 1 | package com.yuneec.example.component.fragment; 2 | 3 | /** 4 | * Created by sushmas on 8/29/17. 5 | */ 6 | 7 | import android.content.ActivityNotFoundException; 8 | import android.content.Context; 9 | import android.content.Intent; 10 | import android.os.Bundle; 11 | import android.support.v4.app.Fragment; 12 | import android.support.v4.content.FileProvider; 13 | import android.support.v4.widget.SwipeRefreshLayout; 14 | import android.view.LayoutInflater; 15 | import android.view.View; 16 | import android.view.ViewGroup; 17 | import android.webkit.MimeTypeMap; 18 | import android.widget.AdapterView; 19 | import android.widget.ListView; 20 | import android.widget.Toast; 21 | 22 | import com.yuneec.example.R; 23 | import com.yuneec.example.component.adapter.MediaListAdapter; 24 | import com.yuneec.example.component.listeners.CameraListener; 25 | import com.yuneec.example.component.utils.Common; 26 | import com.yuneec.example.model.MediaInfoEntry; 27 | import com.yuneec.sdk.Camera; 28 | 29 | import java.io.File; 30 | import java.util.ArrayList; 31 | 32 | /** 33 | * This fragment allows users to view and download pictures and video taken from the drone 34 | */ 35 | 36 | public class MediaDownloadFragment extends Fragment implements 37 | SwipeRefreshLayout.OnRefreshListener { 38 | 39 | private View rootView; 40 | 41 | private Camera.MediaInfosListener mediaInfoslistener; 42 | private MediaListAdapter adapter; 43 | SwipeRefreshLayout swipeLayout; 44 | private boolean downloadingMedia = false; 45 | private Toast toast = null; 46 | 47 | @Override 48 | public void onCreate(Bundle savedInstanceState) { 49 | 50 | super.onCreate(savedInstanceState); 51 | ArrayList emptyList = new ArrayList(); 52 | 53 | adapter = new MediaListAdapter(getActivity(), emptyList); 54 | } 55 | 56 | @Override 57 | public View onCreateView(LayoutInflater inflater, 58 | ViewGroup container, 59 | Bundle savedInstanceState) { 60 | 61 | super.onCreate(savedInstanceState); 62 | setRetainInstance(true); 63 | initViews(inflater, container); 64 | return rootView; 65 | } 66 | 67 | @Override 68 | public void onStart() { 69 | 70 | super.onStart(); 71 | //registerListener(); 72 | } 73 | 74 | @Override 75 | public void onStop() { 76 | 77 | super.onStop(); 78 | //unRegisterListener(); 79 | } 80 | 81 | @Override 82 | public void onPause() { 83 | 84 | super.onPause(); 85 | } 86 | 87 | @Override 88 | public void onResume() { 89 | 90 | super.onResume(); 91 | 92 | } 93 | 94 | @Override 95 | public void onDestroyView() { 96 | 97 | super.onDestroyView(); 98 | } 99 | 100 | 101 | private void initViews(LayoutInflater inflater, 102 | ViewGroup container) { 103 | 104 | rootView = inflater.inflate(R.layout.media_download_layout, container, false); 105 | mediaInfoslistener = new Camera.MediaInfosListener() { 106 | @Override 107 | public void getMediaInfosCallback(final Camera.Result result, 108 | final ArrayList mediaInfos) { 109 | getActivity().runOnUiThread(new Runnable() { 110 | public void run() { 111 | adapter.setEntries(mediaInfos); 112 | adapter.notifyDataSetChanged(); 113 | updateToast(result.resultStr + ", found " + mediaInfos.size() + " media items"); 114 | swipeLayout.setRefreshing(false); 115 | } 116 | }); 117 | } 118 | 119 | }; 120 | 121 | swipeLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swiperefresh); 122 | swipeLayout.setOnRefreshListener(this); 123 | 124 | ListView lv = (ListView) rootView.findViewById(R.id.media_info_list); 125 | lv.setAdapter(adapter); 126 | 127 | lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { 128 | 129 | @Override 130 | public void onItemClick(AdapterView adapterView, View view, int i, long l) { 131 | 132 | final MediaInfoEntry entry = adapter.getItem(i); 133 | 134 | if (entry.downloaded) { 135 | openFile(entry); 136 | } else { 137 | downloadFile(entry); 138 | } 139 | } 140 | 141 | private String localPath(String title) { 142 | // TODO: should check if there is a SD card inserted. 143 | File path = rootView.getContext().getExternalFilesDir(null); 144 | //System.out.println("Download to: " + path); 145 | // Create dir if not already existing 146 | if (path.mkdirs()) { 147 | System.out.println("Created: " + path); 148 | } else { 149 | System.out.println("Could not create: " + path); 150 | } 151 | return path + "/" + title; 152 | } 153 | 154 | private void downloadFile(final MediaInfoEntry entry) { 155 | 156 | // Ignore clicks while downloading something else, this is because we can 157 | // only have one listener at a time. 158 | if (downloadingMedia) { 159 | return; 160 | } 161 | 162 | downloadingMedia = true; 163 | Camera.MediaListener mediaListener = new Camera.MediaListener() { 164 | @Override 165 | public void getMediaCallback(final Camera.Result result, final int progress) { 166 | getActivity().runOnUiThread(new Runnable() { 167 | public void run() { 168 | if (result.resultID != Camera.Result.ResultID.IN_PROGRESS) { 169 | 170 | updateToast("Download: " + result.resultStr); 171 | 172 | if (result.resultID == Camera.Result.ResultID.SUCCESS) { 173 | entry.downloaded = true; 174 | adapter.notifyDataSetChanged(); 175 | } 176 | downloadingMedia = false; 177 | } else { 178 | updateToast("Downloaded " + progress + " %"); 179 | } 180 | } 181 | }); 182 | } 183 | 184 | }; 185 | 186 | String localPath = localPath(entry.title); 187 | 188 | System.out.println("Fetching " + entry.path + " to " + localPath); 189 | 190 | // FIXME: Note that we overwrite the mediaListener here, so the old one will 191 | // now be the same as the new one. 192 | Camera.getMediaAsync(localPath, entry.path, mediaListener); 193 | } 194 | 195 | private void openFile(MediaInfoEntry entry) { 196 | 197 | // Some file open magic taken from: 198 | //http://stackoverflow.com/questions/6265298#answer-6381479 199 | 200 | String localPath = localPath(entry.title); 201 | File file = new File(localPath); 202 | 203 | MimeTypeMap myMime = MimeTypeMap.getSingleton(); 204 | Intent newIntent = new Intent(Intent.ACTION_VIEW); 205 | 206 | String fileExtension = fileExt(localPath); 207 | String mimeType = myMime.getMimeTypeFromExtension(fileExtension); 208 | 209 | Context context = rootView.getContext(); 210 | 211 | // Taken from https://stackoverflow.com/questions/38200282#answer-38858040 212 | newIntent.setDataAndType(FileProvider.getUriForFile(context, 213 | context.getApplicationContext().getPackageName() + ".yuneec.sdk.example.provider", 214 | file), 215 | mimeType); 216 | newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 217 | newIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 218 | 219 | try { 220 | rootView.getContext().startActivity(newIntent); 221 | } catch (ActivityNotFoundException e) { 222 | updateToast("No handler for this type of file."); 223 | } 224 | } 225 | 226 | private String fileExt(String url) { 227 | if (url.indexOf("?") > -1) { 228 | url = url.substring(0, url.indexOf("?")); 229 | } 230 | if (url.lastIndexOf(".") == -1) { 231 | return null; 232 | } else { 233 | String ext = url.substring(url.lastIndexOf(".") + 1); 234 | if (ext.indexOf("%") > -1) { 235 | ext = ext.substring(0, ext.indexOf("%")); 236 | } 237 | if (ext.indexOf("/") > -1) { 238 | ext = ext.substring(0, ext.indexOf("/")); 239 | } 240 | return ext.toLowerCase(); 241 | } 242 | } 243 | }); 244 | 245 | 246 | // Trigger a manual refresh when the view is created. 247 | swipeLayout.setRefreshing(true); 248 | refreshIndex(); 249 | 250 | } 251 | 252 | 253 | /*private void registerListener() { 254 | 255 | CameraListener.registerCameraListener(getActivity()); 256 | } 257 | 258 | private void unRegisterListener() { 259 | 260 | CameraListener.unRegisterCameraListener(); 261 | }*/ 262 | 263 | @Override 264 | public void onRefresh() { 265 | refreshIndex(); 266 | } 267 | 268 | public void refreshIndex() { 269 | Camera.getMediaInfosAsync(mediaInfoslistener); 270 | } 271 | 272 | private void updateToast(String text) { 273 | if (toast == null) { 274 | toast = Common.makeToast(getActivity(), text); 275 | } else { 276 | toast.setText(text); 277 | toast.show(); 278 | } 279 | 280 | } 281 | } 282 | -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/component/fragment/MissionFragment.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MissionFragment.java 3 | * Yuneec-SDK-Android-Example 4 | *

5 | * Copyright @ 2016-2017 Yuneec. 6 | * All rights reserved. 7 | */ 8 | package com.yuneec.example.component.fragment; 9 | 10 | import android.os.Bundle; 11 | import android.support.v4.app.Fragment; 12 | import android.view.LayoutInflater; 13 | import android.view.View; 14 | import android.view.ViewGroup; 15 | import android.widget.Toast; 16 | 17 | import com.yuneec.example.R; 18 | import com.yuneec.sdk.Mission; 19 | import com.yuneec.sdk.MissionItem; 20 | 21 | import java.util.ArrayList; 22 | 23 | 24 | public class MissionFragment extends Fragment implements View.OnClickListener { 25 | 26 | View rootView; 27 | 28 | Mission.ResultListener resultListener; 29 | Mission.ProgressListener progressListener; 30 | 31 | @Override 32 | public View onCreateView(LayoutInflater inflater, 33 | ViewGroup container, Bundle savedInstanceState) { 34 | super.onCreate(savedInstanceState); 35 | 36 | rootView = inflater.inflate(R.layout.mission_example, container, false); 37 | 38 | resultListener = new Mission.ResultListener() { 39 | @Override 40 | public void onResultCallback(final Mission.Result result) { 41 | getActivity().runOnUiThread(new Runnable() { 42 | public void run() { 43 | Toast.makeText(rootView.getContext(), result.resultStr, 44 | Toast.LENGTH_LONG).show(); 45 | } 46 | }); 47 | } 48 | }; 49 | 50 | progressListener = new Mission.ProgressListener() { 51 | @Override 52 | public void onProgressUpdate(final int current, final int total) { 53 | getActivity().runOnUiThread(new Runnable() { 54 | public void run() { 55 | String text = String.format("Reached %d of %d", current, total); 56 | Toast.makeText(rootView.getContext(), text, Toast.LENGTH_LONG).show(); 57 | } 58 | }); 59 | } 60 | }; 61 | 62 | rootView.findViewById(R.id.mission_send_button).setOnClickListener(this); 63 | rootView.findViewById(R.id.mission_start_button).setOnClickListener(this); 64 | rootView.findViewById(R.id.mission_pause_button).setOnClickListener(this); 65 | 66 | return rootView; 67 | } 68 | 69 | static public MissionItem makeMissionItem(double latitudeDeg, double longitudeM, 70 | float relativeAltitudeM, 71 | MissionItem.CameraAction cameraAction, 72 | float gimbalPitchDeg, float gimbalYawDeg) { 73 | 74 | MissionItem newItem = new MissionItem(); 75 | newItem.setPosition(latitudeDeg, longitudeM); 76 | newItem.setRelativeAltitude(relativeAltitudeM); 77 | newItem.setCameraAction(cameraAction); 78 | newItem.setGimbalPitchAndYaw(gimbalPitchDeg, gimbalYawDeg); 79 | return newItem; 80 | } 81 | 82 | @Override 83 | public void onClick(View view) { 84 | 85 | switch (view.getId()) { 86 | case R.id.mission_send_button: 87 | 88 | ArrayList missionItems = new ArrayList(); 89 | missionItems.add(makeMissionItem(47.40328702, 8.45186958, 10.0f, 90 | MissionItem.CameraAction.START_VIDEO, 0.0f, 0.0f)); 91 | missionItems.add(makeMissionItem(47.40321712, 8.45205203, 10.0f, MissionItem.CameraAction.NONE, 92 | -30.0f, 30.0f)); 93 | missionItems.add(makeMissionItem(47.40309596, 8.45195392, 10.0f, MissionItem.CameraAction.NONE, 94 | -60.0f, -30.0f)); 95 | missionItems.add(makeMissionItem(47.40302956, 8.45213636, 10.0f, MissionItem.CameraAction.NONE, 96 | -90.0f, 0.0f)); 97 | missionItems.add(makeMissionItem(47.40314839, 8.45223619, 10.0f, 98 | MissionItem.CameraAction.STOP_VIDEO, 0.0f, 0.0f)); 99 | missionItems.add(makeMissionItem(47.40309014, 8.45241003, 10.0f, 100 | MissionItem.CameraAction.TAKE_PHOTO, -90.0f, 0.0f)); 101 | missionItems.add(makeMissionItem(47.40285248, 8.45218627, 10.0f, 102 | MissionItem.CameraAction.TAKE_PHOTO, -90.0f, 0.0f)); 103 | missionItems.add(makeMissionItem(47.40289092, 8.45208473, 10.0f, 104 | MissionItem.CameraAction.TAKE_PHOTO, -45.0f, 0.0f)); 105 | missionItems.add(makeMissionItem(47.40292812, 8.45200039, 10.0f, 106 | MissionItem.CameraAction.TAKE_PHOTO, -45.0f, 90.0f)); 107 | missionItems.add(makeMissionItem(47.40296548, 8.45189884, 10.0f, 108 | MissionItem.CameraAction.TAKE_PHOTO, 0.0f, -90.0f)); 109 | missionItems.add(makeMissionItem(47.40301907, 8.45175942, 10.0f, 110 | MissionItem.CameraAction.TAKE_PHOTO, 0.0f, 90.0f)); 111 | 112 | Mission.subscribeProgress(progressListener); 113 | Mission.sendMissionAsync(missionItems, resultListener); 114 | break; 115 | 116 | case R.id.mission_start_button: 117 | Mission.startMissionAsync(resultListener); 118 | break; 119 | 120 | case R.id.mission_pause_button: 121 | Mission.pauseMissionAsync(resultListener); 122 | break; 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/component/fragment/St16Fragment.java: -------------------------------------------------------------------------------- 1 | /** 2 | * ActionFragment.java 3 | * Yuneec-SDK-Android-Example 4 | *

5 | * Copyright @ 2016-2017 Yuneec. 6 | * All rights reserved. 7 | */ 8 | package com.yuneec.example.component.fragment; 9 | 10 | import android.os.Bundle; 11 | import android.support.v4.app.Fragment; 12 | import android.util.Log; 13 | import android.view.LayoutInflater; 14 | import android.view.View; 15 | import android.view.ViewGroup; 16 | 17 | import com.yuneec.example.R; 18 | import com.yuneec.example.component.listeners.YuneecSt16Listener; 19 | import com.yuneec.example.component.utils.Media; 20 | import com.yuneec.sdk.YuneecSt16; 21 | 22 | public class St16Fragment extends Fragment implements View.OnClickListener { 23 | /**Create view*/ 24 | View mView; 25 | 26 | YuneecSt16.ResultListener resultListener; 27 | YuneecSt16.M4VersionListener versionListener; 28 | 29 | private static final String TAG = St16Fragment.class.getCanonicalName(); 30 | 31 | @Override 32 | public View onCreateView(LayoutInflater inflater, 33 | ViewGroup container, Bundle savedInstanceState) { 34 | super.onCreate(savedInstanceState); 35 | initView(inflater, container); 36 | return mView; 37 | } 38 | 39 | @Override 40 | public void onStart() { 41 | 42 | super.onStart(); 43 | registerListener(); 44 | resultListener = YuneecSt16Listener.getYuneecSt16ResultListener(); 45 | versionListener = YuneecSt16Listener.getYuneecSt16VersionListener(); 46 | } 47 | 48 | @Override 49 | public void onStop() { 50 | 51 | super.onStop(); 52 | unRegisterListener(); 53 | } 54 | 55 | private void initView(LayoutInflater inflater, 56 | ViewGroup container) { 57 | mView = inflater.inflate(R.layout.st16_layout, container, false); 58 | mView.findViewById(R.id.pair_button).setOnClickListener(this); 59 | mView.findViewById(R.id.unpair_button).setOnClickListener(this); 60 | mView.findViewById(R.id.check_paired_button).setOnClickListener(this); 61 | mView.findViewById(R.id.get_m4_version).setOnClickListener(this); 62 | } 63 | 64 | private void registerListener() { 65 | YuneecSt16Listener.registerYuneecSt16Listeners(getActivity()); 66 | } 67 | 68 | private void unRegisterListener() { 69 | YuneecSt16Listener.unRegisterYuneecSt16Listeners(); 70 | } 71 | 72 | @Override 73 | public void onClick(View v) { 74 | Media.vibrate(getActivity()); 75 | switch (v.getId()) { 76 | case R.id.pair_button: 77 | YuneecSt16.pairAsync(resultListener); 78 | break; 79 | case R.id.unpair_button: 80 | YuneecSt16.unpairAsync(resultListener); 81 | break; 82 | case R.id.check_paired_button: 83 | YuneecSt16.checkPairedAsync(resultListener); 84 | break; 85 | case R.id.get_m4_version: 86 | YuneecSt16.getM4VersionAsync(versionListener); 87 | break; 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/component/fragment/TelemetryFragment.java: -------------------------------------------------------------------------------- 1 | /** 2 | * TelemetryFragment.java 3 | * Yuneec-SDK-Android-Example 4 | *

5 | * Copyright @ 2016-2017 Yuneec. 6 | * All rights reserved. 7 | */ 8 | package com.yuneec.example.component.fragment; 9 | 10 | import android.content.Context; 11 | import android.os.Bundle; 12 | import android.support.v4.app.Fragment; 13 | import android.util.Log; 14 | import android.view.LayoutInflater; 15 | import android.view.View; 16 | import android.view.ViewGroup; 17 | import android.widget.BaseAdapter; 18 | import android.widget.ListView; 19 | import android.widget.TextView; 20 | 21 | import com.yuneec.example.R; 22 | import com.yuneec.example.component.listeners.TelemetryListener; 23 | import com.yuneec.sdk.Connection; 24 | import com.yuneec.sdk.Telemetry; 25 | 26 | import java.util.ArrayList; 27 | 28 | 29 | public class TelemetryFragment extends Fragment { 30 | 31 | private static final String TAG = TelemetryFragment.class.getCanonicalName(); 32 | 33 | class TelemetryIndices { 34 | public final static int LATITUDE = 0; 35 | public final static int LONGITUDE = 1; 36 | public final static int RELATIVE_ALTITUDE = 2; 37 | public final static int BATTERY = 3; 38 | public final static int ROLL = 4; 39 | public final static int PITCH = 5; 40 | public final static int YAW = 6; 41 | public final static int VELOCITY_NORTH = 7; 42 | public final static int VELOCITY_EAST = 8; 43 | public final static int VELOCITY_UP = 9; 44 | public final static int FLIGHT_MODE = 10; 45 | public final static int HEALTH = 11; 46 | public final static int GPS_NO_OF_SATELLITES = 12; 47 | public final static int HOME_POSITION_LATITUDE = 13; 48 | public final static int HOME_POSITION_LONGITUDE = 14; 49 | public final static int IS_ARMED = 15; 50 | public final static int VEHICLE_POSITION = 16; 51 | public final static int RC_STATUS = 17; 52 | } 53 | 54 | ; 55 | 56 | private ListviewTelemetryAdapter adapter; 57 | 58 | public class TelemetryEntry { 59 | 60 | public TelemetryEntry(String new_description, String new_unit) { 61 | description = new_description; 62 | unit = new_unit; 63 | value = "-"; 64 | } 65 | 66 | public String description; 67 | public String value; 68 | public String unit; 69 | } 70 | 71 | public class ListviewTelemetryAdapter extends BaseAdapter { 72 | private ArrayList entries; 73 | private LayoutInflater inflater; 74 | 75 | public ListviewTelemetryAdapter(Context context, ArrayList list) { 76 | entries = list; 77 | inflater = LayoutInflater.from(context); 78 | } 79 | 80 | @Override 81 | public int getCount() { 82 | return entries.size(); 83 | } 84 | 85 | @Override 86 | public Object getItem(int index) { 87 | return entries.get(index); 88 | } 89 | 90 | public void setItemValue(int index, String new_value) { 91 | entries.get(index).value = new_value; 92 | } 93 | 94 | @Override 95 | public long getItemId(int index) { 96 | return index; 97 | } 98 | 99 | public View getView(int index, View convertView, ViewGroup parent) { 100 | ViewHolder holder; 101 | if (convertView == null) { 102 | convertView = inflater.inflate(android.R.layout.simple_list_item_2, null); 103 | holder = new ViewHolder(); 104 | holder.text1 = (TextView) convertView.findViewById(android.R.id.text1); 105 | holder.text2 = (TextView) convertView.findViewById(android.R.id.text2); 106 | 107 | convertView.setTag(holder); 108 | } else { 109 | holder = (ViewHolder) convertView.getTag(); 110 | } 111 | 112 | holder.text1.setText(entries.get(index).description); 113 | holder.text2.setText(entries.get(index).value + " " + entries.get(index).unit); 114 | 115 | return convertView; 116 | } 117 | 118 | class ViewHolder { 119 | TextView text1, text2; 120 | } 121 | } 122 | 123 | public class PositionListener implements Telemetry.PositionListener { 124 | 125 | @Override 126 | public void onPositionCallback(Telemetry.Position position) { 127 | adapter.setItemValue(TelemetryIndices.RELATIVE_ALTITUDE, 128 | String.format("%.1f", position.relativeAltitudeM)); 129 | adapter.setItemValue(TelemetryIndices.LATITUDE, 130 | String.format("%.6f", position.latitudeDeg)); 131 | adapter.setItemValue(TelemetryIndices.LONGITUDE, 132 | String.format("%.6f", position.longitudeDeg)); 133 | 134 | getActivity().runOnUiThread(new Runnable() { 135 | public void run() { 136 | adapter.notifyDataSetChanged(); 137 | } 138 | }); 139 | } 140 | } 141 | 142 | public class AttitudeEulerAngleListener implements Telemetry.AttitudeEulerAngleListener { 143 | 144 | @Override 145 | public void onAttitudeEulerAngleCallback(Telemetry.AttitudeEulerAngle attitude) { 146 | 147 | adapter.setItemValue(TelemetryIndices.ROLL, 148 | String.format("%d", (int) attitude.rollDeg)); 149 | adapter.setItemValue(TelemetryIndices.PITCH, 150 | String.format("%d", (int) attitude.pitchDeg)); 151 | adapter.setItemValue(TelemetryIndices.YAW, 152 | String.format("%d", (int) attitude.yawDeg)); 153 | 154 | getActivity().runOnUiThread(new Runnable() { 155 | public void run() { 156 | adapter.notifyDataSetChanged(); 157 | } 158 | }); 159 | } 160 | } 161 | 162 | public class BatteryListener implements Telemetry.BatteryListener { 163 | 164 | @Override 165 | public void onBatteryCallback(Telemetry.Battery battery) { 166 | 167 | adapter.setItemValue(TelemetryIndices.BATTERY, 168 | String.format("%d", (int)(100 * battery.remainingPercent))); 169 | 170 | getActivity().runOnUiThread(new Runnable() { 171 | public void run() { 172 | adapter.notifyDataSetChanged(); 173 | } 174 | }); 175 | } 176 | } 177 | 178 | public class GroundSpeedNEDListener implements Telemetry.GroundSpeedNEDListener { 179 | 180 | @Override 181 | public void onGroundSpeedNEDCallback(Telemetry.GroundSpeedNED groundSpeedNED) { 182 | 183 | adapter.setItemValue(TelemetryIndices.VELOCITY_NORTH, 184 | String.format("%.1f", groundSpeedNED.velocityNorthMS)); 185 | adapter.setItemValue(TelemetryIndices.VELOCITY_EAST, 186 | String.format("%.1f", groundSpeedNED.velocityEastMS)); 187 | adapter.setItemValue(TelemetryIndices.VELOCITY_UP, 188 | String.format("%.1f", (-1) * groundSpeedNED.velocityDownMS)); 189 | 190 | getActivity().runOnUiThread(new Runnable() { 191 | public void run() { 192 | adapter.notifyDataSetChanged(); 193 | } 194 | }); 195 | } 196 | } 197 | 198 | public class FlightModeListener implements Telemetry.FlightModeListener { 199 | 200 | @Override 201 | public void onFlightModeCallback(Telemetry.FlightMode flightMode) { 202 | 203 | adapter.setItemValue(TelemetryIndices.FLIGHT_MODE, flightMode.flightModeStr); 204 | 205 | getActivity().runOnUiThread(new Runnable() { 206 | public void run() { 207 | adapter.notifyDataSetChanged(); 208 | } 209 | }); 210 | } 211 | } 212 | 213 | public class HealthListener implements Telemetry.HealthListener { 214 | 215 | @Override 216 | public void onHealthCallback(Telemetry.Health health) { 217 | 218 | boolean calibrationOk = health.accelerometerCalibrationOk && 219 | health.gyrometerCalibrationOk && 220 | health.magnetometerCalibrationOk && 221 | health.levelCalibrationOk; 222 | 223 | boolean positionOk = health.globalPositionOk && 224 | health.localPositionOk && 225 | health.homePositionOk; 226 | 227 | adapter.setItemValue(TelemetryIndices.HEALTH, 228 | String.format("calibration: %s, position: %s", 229 | calibrationOk ? "ok" : "not ok", 230 | positionOk ? "ok" : "not ok")); 231 | 232 | getActivity().runOnUiThread(new Runnable() { 233 | public void run() { 234 | adapter.notifyDataSetChanged(); 235 | } 236 | }); 237 | } 238 | } 239 | 240 | public class GPSInfoListener implements Telemetry.GPSInfoListener { 241 | 242 | @Override 243 | public void onGPSInfoCallback(Telemetry.GPSInfo gpsInfo) { 244 | adapter.setItemValue(TelemetryIndices.GPS_NO_OF_SATELLITES, String.valueOf(gpsInfo.numSatellites)); 245 | 246 | getActivity().runOnUiThread(new Runnable() { 247 | public void run() { 248 | adapter.notifyDataSetChanged(); 249 | } 250 | }); 251 | } 252 | } 253 | 254 | public class HomePositionListener implements Telemetry.HomePositionListener { 255 | 256 | @Override 257 | public void onHomePositionCallback(Telemetry.Position position) { 258 | adapter.setItemValue(TelemetryIndices.HOME_POSITION_LATITUDE, String.valueOf(position.latitudeDeg)); 259 | adapter.setItemValue(TelemetryIndices.HOME_POSITION_LONGITUDE, 260 | String.valueOf(position.longitudeDeg)); 261 | 262 | getActivity().runOnUiThread(new Runnable() { 263 | public void run() { 264 | adapter.notifyDataSetChanged(); 265 | } 266 | }); 267 | } 268 | } 269 | 270 | public class ArmedListener implements Telemetry.ArmedListener { 271 | 272 | @Override 273 | public void onIsArmedCallback(boolean b) { 274 | adapter.setItemValue(TelemetryIndices.IS_ARMED, String.valueOf(b)); 275 | 276 | getActivity().runOnUiThread(new Runnable() { 277 | public void run() { 278 | adapter.notifyDataSetChanged(); 279 | } 280 | }); 281 | } 282 | } 283 | 284 | public class InAirListener implements Telemetry.InAirListener { 285 | 286 | @Override 287 | public void onIsInAirCallback(boolean b) { 288 | if (b == true) { 289 | adapter.setItemValue(TelemetryIndices.VEHICLE_POSITION, "In Air"); 290 | } else if (b == false) { 291 | adapter.setItemValue(TelemetryIndices.VEHICLE_POSITION, "On Ground"); 292 | } else { 293 | Log.d(TAG, "Vehicle position" + b); 294 | } 295 | 296 | getActivity().runOnUiThread(new Runnable() { 297 | public void run() { 298 | adapter.notifyDataSetChanged(); 299 | } 300 | }); 301 | } 302 | } 303 | 304 | public class RCStatusListener implements Telemetry.RCStatusListener { 305 | 306 | @Override 307 | public void onRCStatusCallback(Telemetry.RCStatus rcStatus) { 308 | adapter.setItemValue(TelemetryIndices.RC_STATUS, String.format("%d", 309 | (int)(rcStatus.signalStrengthPercent))); 310 | 311 | getActivity().runOnUiThread(new Runnable() { 312 | public void run() { 313 | adapter.notifyDataSetChanged(); 314 | } 315 | }); 316 | } 317 | } 318 | 319 | 320 | @Override 321 | public void onCreate(Bundle savedInstanceState) { 322 | super.onCreate(savedInstanceState); 323 | 324 | ArrayList list = GetInitialTelemetrylist(); 325 | 326 | adapter = new ListviewTelemetryAdapter(getActivity(), list); 327 | 328 | subscribe(); 329 | } 330 | 331 | @Override 332 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 333 | Bundle savedInstanceState) { 334 | 335 | View rootView = inflater.inflate(R.layout.telemetry_example, container, false); 336 | 337 | ListView lv = (ListView) rootView.findViewById(R.id.telemetry_list); 338 | lv.setAdapter(adapter); 339 | 340 | return rootView; 341 | } 342 | 343 | private ArrayList GetInitialTelemetrylist() { 344 | final ArrayList list = new ArrayList(); 345 | list.add(TelemetryIndices.LATITUDE, new TelemetryEntry("Latitude", "deg")); 346 | list.add(TelemetryIndices.LONGITUDE, new TelemetryEntry("Longitude", "deg")); 347 | list.add(TelemetryIndices.RELATIVE_ALTITUDE, new TelemetryEntry("Altitude", "meters")); 348 | list.add(TelemetryIndices.BATTERY, new TelemetryEntry("Battery", "%")); 349 | list.add(TelemetryIndices.ROLL, new TelemetryEntry("Roll", "deg")); 350 | list.add(TelemetryIndices.PITCH, new TelemetryEntry("Pitch", "deg")); 351 | list.add(TelemetryIndices.YAW, new TelemetryEntry("Yaw", "deg")); 352 | list.add(TelemetryIndices.VELOCITY_NORTH, new TelemetryEntry("Velocity North", "m/s")); 353 | list.add(TelemetryIndices.VELOCITY_EAST, new TelemetryEntry("Velocity East", "m/s")); 354 | list.add(TelemetryIndices.VELOCITY_UP, new TelemetryEntry("Velocity Up", "m/s")); 355 | list.add(TelemetryIndices.FLIGHT_MODE, new TelemetryEntry("Flight mode", "")); 356 | list.add(TelemetryIndices.HEALTH, new TelemetryEntry("Health", "")); 357 | list.add(TelemetryIndices.GPS_NO_OF_SATELLITES, new TelemetryEntry("GPS Satellites", "")); 358 | list.add(TelemetryIndices.HOME_POSITION_LATITUDE, new TelemetryEntry("Home Position Latitude", 359 | "deg")); 360 | list.add(TelemetryIndices.HOME_POSITION_LONGITUDE, new TelemetryEntry("Home Position Longitude", 361 | "deg")); 362 | list.add(TelemetryIndices.IS_ARMED, new TelemetryEntry("Vehicle Armed", "")); 363 | list.add(TelemetryIndices.VEHICLE_POSITION, new TelemetryEntry("Vehicle Position", "")); 364 | list.add(TelemetryIndices.RC_STATUS, new TelemetryEntry("RC Signal Strength", "%")); 365 | return list; 366 | } 367 | 368 | private void subscribe() { 369 | Telemetry.setPositionListener(new PositionListener()); 370 | Telemetry.setGroundSpeedNEDListener(new GroundSpeedNEDListener()); 371 | Telemetry.setAttitudeEulerAngleListener(new AttitudeEulerAngleListener()); 372 | Telemetry.setBatteryListener(new BatteryListener()); 373 | Telemetry.setFlightModeListener(new FlightModeListener()); 374 | Telemetry.setHealthListener(new HealthListener()); 375 | Telemetry.setGPSInfoListener(new GPSInfoListener()); 376 | Telemetry.setHomePostionListener(new HomePositionListener()); 377 | Telemetry.setArmedListener(new ArmedListener()); 378 | Telemetry.setInAirListener(new InAirListener()); 379 | Telemetry.setRCStatusListener(new RCStatusListener()); 380 | } 381 | } 382 | -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/component/listeners/ActionListener.java: -------------------------------------------------------------------------------- 1 | package com.yuneec.example.component.listeners; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | 6 | import com.yuneec.example.component.custom_callback.OnChangeListener; 7 | import com.yuneec.sdk.Action; 8 | import com.yuneec.sdk.Gimbal; 9 | 10 | /** 11 | * Created by sushmas on 9/15/17. 12 | */ 13 | 14 | public class ActionListener { 15 | 16 | private static Action.ResultListener actionResultListener = null; 17 | 18 | private static final String TAG = ActionListener.class.getCanonicalName(); 19 | 20 | private static OnChangeListener onChangeListener; 21 | 22 | public static Action.ResultListener getActionResultListener(Context context) { 23 | onChangeListener = (OnChangeListener) context; 24 | if (actionResultListener == null) { 25 | Log.d(TAG, "Initialized action result listener"); 26 | actionResultListener = new Action.ResultListener() { 27 | @Override 28 | public void onResultCallback(Action.Result result) { 29 | Log.d(TAG, result.resultStr); 30 | } 31 | }; 32 | } 33 | 34 | return actionResultListener; 35 | } 36 | 37 | public static void registerActionListener() { 38 | 39 | if (actionResultListener == null) { 40 | Log.d(TAG, "Initialized action result listener"); 41 | actionResultListener = new Action.ResultListener() { 42 | @Override 43 | public void onResultCallback(Action.Result result) { 44 | onChangeListener.publishActionResult(result.resultStr); 45 | Log.d(TAG, result.resultStr); 46 | } 47 | }; 48 | } 49 | } 50 | 51 | public static void unRegisterActionListener() { 52 | 53 | if (actionResultListener != null) { 54 | actionResultListener = null; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/component/listeners/CameraListener.java: -------------------------------------------------------------------------------- 1 | package com.yuneec.example.component.listeners; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | 6 | import com.yuneec.example.component.custom_callback.OnChangeListener; 7 | import com.yuneec.sdk.Camera; 8 | 9 | /** 10 | * Created by sushma on 8/8/17. 11 | */ 12 | 13 | public class CameraListener { 14 | 15 | private static Camera.ResultListener cameraResultListener = null; 16 | 17 | private static final String TAG = CameraListener.class.getCanonicalName(); 18 | 19 | private static OnChangeListener onChangeListener; 20 | 21 | public static void registerCameraListener(Context context) { 22 | onChangeListener = (OnChangeListener) context; 23 | if (cameraResultListener == null) { 24 | Log.d(TAG, "Initialized camera result listener"); 25 | cameraResultListener = new Camera.ResultListener() { 26 | 27 | @Override 28 | public void resultCallback(Camera.Result result) { 29 | onChangeListener.publishCameraResult(result.resultStr); 30 | Log.d(TAG, result.resultStr); 31 | } 32 | 33 | 34 | }; 35 | Camera.setResultListener(cameraResultListener); 36 | } 37 | } 38 | 39 | public static void unRegisterCameraListener() { 40 | 41 | if (cameraResultListener != null) { 42 | cameraResultListener = null; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/component/listeners/CameraModeListener.java: -------------------------------------------------------------------------------- 1 | package com.yuneec.example.component.listeners; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | 6 | import com.yuneec.example.component.custom_callback.OnChangeListener; 7 | import com.yuneec.sdk.Camera; 8 | 9 | /** 10 | * Created by sushmas on 9/13/17. 11 | */ 12 | 13 | public class CameraModeListener { 14 | 15 | private static Camera.ModeListener cameraModeListener = null; 16 | 17 | private static final String TAG = CameraModeListener.class.getCanonicalName(); 18 | 19 | private static OnChangeListener onChangeListener; 20 | 21 | 22 | public static Camera.ModeListener getCameraModeListener() { 23 | return cameraModeListener; 24 | } 25 | 26 | public static void registerCameraModeListener(Context context) { 27 | onChangeListener = (OnChangeListener) context; 28 | if (cameraModeListener == null) { 29 | Log.d(TAG, "Initialized camera result listener"); 30 | cameraModeListener = new Camera.ModeListener() { 31 | 32 | @Override 33 | public void callback(Camera.Result result, Camera.Mode mode) { 34 | Log.d(TAG, mode + " mode set " + result.resultStr); 35 | onChangeListener.publishCameraModeResult(mode, result.resultStr); 36 | } 37 | 38 | }; 39 | } 40 | } 41 | 42 | public static void unRegisterCameraModeListener() { 43 | 44 | if (cameraModeListener != null) { 45 | cameraModeListener = null; 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/component/listeners/CameraSettingsListener.java: -------------------------------------------------------------------------------- 1 | package com.yuneec.example.component.listeners; 2 | 3 | import android.util.Log; 4 | 5 | import com.yuneec.sdk.Camera; 6 | 7 | /** 8 | * Created by sushmas on 9/7/17. 9 | */ 10 | 11 | public class CameraSettingsListener { 12 | 13 | private static Camera.WhiteBalanceListener whiteBalanceListener = null; 14 | 15 | private static Camera.ColorModeListener colorModeListener = null; 16 | 17 | private static Camera.ExposureModeListener exposureModeListener = null; 18 | 19 | private static Camera.ExposureValueListener exposureValueListener = null; 20 | 21 | private static Camera.ISOValueListener isoValueListener = null; 22 | 23 | private static Camera.ShutterSpeedListener shutterSpeedListener = null; 24 | 25 | private static Camera.PhotoFormatListener photoFormatListener = null; 26 | 27 | private static Camera.PhotoQualityListener photoQualityListener = null; 28 | 29 | private static Camera.VideoFormatListener videoFormatListener = null; 30 | 31 | private static Camera.VideoResolutionListener videoResolutionListener = null; 32 | 33 | private static Camera.MeteringListener meteringListener = null; 34 | 35 | private static Camera.ResolutionListener resolutionListener = null; 36 | 37 | private static final String TAG = CameraSettingsListener.class.getCanonicalName(); 38 | 39 | public static Camera.WhiteBalanceListener getWhiteBalanceListener() { 40 | return whiteBalanceListener; 41 | } 42 | 43 | public static Camera.ExposureValueListener getExposureValueListener() { 44 | return exposureValueListener; 45 | } 46 | 47 | public static Camera.ColorModeListener getColorModeListener() { 48 | return colorModeListener; 49 | } 50 | 51 | public static Camera.ExposureModeListener getExposureModeListener() { 52 | return exposureModeListener; 53 | } 54 | 55 | public static Camera.ISOValueListener getIsoValueListener() { 56 | return isoValueListener; 57 | } 58 | 59 | public static Camera.ShutterSpeedListener getShutterSpeedListener() { 60 | return shutterSpeedListener; 61 | } 62 | 63 | public static Camera.PhotoFormatListener getPhotoFormatListener() { 64 | return photoFormatListener; 65 | } 66 | 67 | public static Camera.PhotoQualityListener getPhotoQualityListener() { 68 | return photoQualityListener; 69 | } 70 | 71 | public static Camera.VideoFormatListener getVideoFormatListener() { 72 | return videoFormatListener; 73 | } 74 | 75 | public static Camera.VideoResolutionListener getVideoResolutionListener() { 76 | return videoResolutionListener; 77 | } 78 | 79 | public static Camera.MeteringListener getMeteringListener() { 80 | return meteringListener; 81 | } 82 | 83 | public static Camera.ResolutionListener getResolutionListener() { 84 | return resolutionListener; 85 | } 86 | 87 | public static void registerSettingsListener() { 88 | whiteBalanceListener = new Camera.WhiteBalanceListener() { 89 | @Override 90 | public void callback(final Camera.Result result, final Camera.WhiteBalance whiteBalance) { 91 | Log.d(TAG, result.resultStr); 92 | } 93 | }; 94 | 95 | colorModeListener = new Camera.ColorModeListener() { 96 | @Override 97 | public void callback(final Camera.Result result, final Camera.ColorMode colorMode) { 98 | Log.d(TAG, result.resultStr); 99 | } 100 | }; 101 | 102 | exposureModeListener = new Camera.ExposureModeListener() { 103 | @Override 104 | public void callback(final Camera.Result result, final Camera.ExposureMode exposureMode) { 105 | Log.d(TAG, result.resultStr); 106 | } 107 | }; 108 | 109 | exposureValueListener = new Camera.ExposureValueListener() { 110 | @Override 111 | public void callback(final Camera.Result result, final float exposureValue) { 112 | Log.d(TAG, result.resultStr); 113 | } 114 | }; 115 | 116 | 117 | isoValueListener = new Camera.ISOValueListener() { 118 | @Override 119 | public void callback(Camera.Result result, int i) { 120 | Log.d(TAG, result.resultStr); 121 | } 122 | }; 123 | 124 | shutterSpeedListener = new Camera.ShutterSpeedListener() { 125 | @Override 126 | public void callback(final Camera.Result result, final Camera.ShutterSpeedS shutterSpeedS) { 127 | Log.d(TAG, result.resultStr); 128 | } 129 | }; 130 | 131 | resolutionListener = new Camera.ResolutionListener() { 132 | 133 | @Override 134 | public void callback(Camera.Result result, Camera.Resolution resolution) { 135 | Log.d(TAG, resolution + " " + result.resultStr); 136 | Log.d(TAG, "Resolution: " + resolution.widthPixels + "x" + resolution.heightPixels + " " + 137 | result.resultStr); 138 | } 139 | }; 140 | 141 | photoFormatListener = new Camera.PhotoFormatListener() { 142 | 143 | @Override 144 | public void callback(Camera.Result result, Camera.PhotoFormat photoFormat) { 145 | Log.d(TAG, photoFormat + " " + result.resultStr); 146 | } 147 | }; 148 | 149 | photoQualityListener = new Camera.PhotoQualityListener() { 150 | 151 | @Override 152 | public void callback(Camera.Result result, Camera.PhotoQuality photoQuality) { 153 | Log.d(TAG, photoQuality + " " + result.resultStr); 154 | } 155 | }; 156 | 157 | videoFormatListener = new Camera.VideoFormatListener() { 158 | 159 | @Override 160 | public void callback(Camera.Result result, Camera.VideoFormat videoFormat) { 161 | Log.d(TAG, videoFormat + " " + result.resultStr); 162 | } 163 | }; 164 | 165 | videoResolutionListener = new Camera.VideoResolutionListener() { 166 | 167 | @Override 168 | public void callback(Camera.Result result, Camera.VideoResolution videoResolution) { 169 | Log.d(TAG, videoResolution + " " + result.resultStr); 170 | } 171 | }; 172 | 173 | meteringListener = new Camera.MeteringListener() { 174 | 175 | @Override 176 | public void callback(Camera.Result result, Camera.Metering metering) { 177 | Log.d(TAG, metering.mode + " " + result.resultStr); 178 | Log.d(TAG, "Metering: " + metering.spotScreenWidthPercent + " " + metering.spotScreenHeightPercent 179 | + " " + metering.mode + " " + result.resultStr); 180 | } 181 | }; 182 | 183 | 184 | } 185 | 186 | public static void unRegisterCameraSettingsListeners() { 187 | 188 | if (whiteBalanceListener != null) { 189 | whiteBalanceListener = null; 190 | } 191 | 192 | if (colorModeListener != null) { 193 | colorModeListener = null; 194 | } 195 | 196 | if (exposureModeListener != null) { 197 | exposureModeListener = null; 198 | } 199 | 200 | if (exposureValueListener != null) { 201 | exposureValueListener = null; 202 | } 203 | if (isoValueListener != null) { 204 | isoValueListener = null; 205 | } 206 | if (shutterSpeedListener != null) { 207 | shutterSpeedListener = null; 208 | } 209 | 210 | if (photoFormatListener != null) { 211 | photoFormatListener = null; 212 | } 213 | if (photoQualityListener != null) { 214 | photoQualityListener = null; 215 | } 216 | if (videoFormatListener != null) { 217 | videoFormatListener = null; 218 | } 219 | if (videoResolutionListener != null) { 220 | videoResolutionListener = null; 221 | } 222 | if (meteringListener != null) { 223 | meteringListener = null; 224 | } 225 | if (resolutionListener != null) { 226 | resolutionListener = null; 227 | } 228 | } 229 | } 230 | -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/component/listeners/ConnectionListener.java: -------------------------------------------------------------------------------- 1 | package com.yuneec.example.component.listeners; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | 6 | import com.yuneec.example.component.custom_callback.OnChangeListener; 7 | import com.yuneec.example.component.utils.Common; 8 | import com.yuneec.sdk.Connection; 9 | 10 | /** 11 | * Created by sushma on 8/8/17. 12 | */ 13 | 14 | public class ConnectionListener { 15 | 16 | private static Connection.Listener connectionListener = null; 17 | 18 | private static final String TAG = ConnectionListener.class.getCanonicalName(); 19 | 20 | private static OnChangeListener onConnectionChange; 21 | 22 | public static void registerConnectionListener(Context context) { 23 | 24 | onConnectionChange = (OnChangeListener) context; 25 | if (connectionListener == null) { 26 | connectionListener = new Connection.Listener() { 27 | 28 | @Override 29 | public void onDiscoverCallback() { 30 | Common.isConnected = true; 31 | onConnectionChange.publishConnectionStatus("Discovered Drone"); 32 | Log.d(TAG, "Connected"); 33 | 34 | } 35 | 36 | @Override 37 | public void onTimeoutCallback() { 38 | Common.isConnected = false; 39 | onConnectionChange.publishConnectionStatus("Timed Out! Reconnect"); 40 | Log.d(TAG, " Not Connected"); 41 | } 42 | }; 43 | 44 | Connection.Result result = Connection.addConnection(); 45 | if (result.resultID != Connection.Result.ResultID.SUCCESS) { 46 | onConnectionChange.publishConnectionStatus(result.resultStr); 47 | Log.d(TAG, result.resultStr); 48 | } 49 | 50 | Connection.addListener(connectionListener); 51 | } 52 | } 53 | 54 | public static void unRegisterConnectionListener() { 55 | 56 | Connection.removeConnection(); 57 | Common.connectionStatus = Common.connectionStatusDefault; 58 | if (connectionListener != null) { 59 | connectionListener = null; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/component/listeners/GimbalListener.java: -------------------------------------------------------------------------------- 1 | package com.yuneec.example.component.listeners; 2 | 3 | import android.util.Log; 4 | 5 | import com.yuneec.sdk.Gimbal; 6 | 7 | /** 8 | * Created by sushma on 8/15/17. 9 | */ 10 | 11 | public class GimbalListener { 12 | 13 | private static Gimbal.ResultListener gimbalResultListener = null; 14 | 15 | private static final String TAG = GimbalListener.class.getCanonicalName(); 16 | 17 | public static Gimbal.ResultListener getGimbaListener() { 18 | 19 | if (gimbalResultListener == null) { 20 | Log.d(TAG, "Initialized gimbal result listener"); 21 | gimbalResultListener = new Gimbal.ResultListener() { 22 | 23 | 24 | @Override 25 | public void onResultCallback(Gimbal.Result result) { 26 | 27 | Log.d(TAG, result.resultStr); 28 | } 29 | }; 30 | } 31 | 32 | return gimbalResultListener; 33 | } 34 | 35 | public static void registerGimbalListener() { 36 | 37 | if (gimbalResultListener == null) { 38 | Log.d(TAG, "Initialized gimbal result listener"); 39 | gimbalResultListener = new Gimbal.ResultListener() { 40 | 41 | 42 | @Override 43 | public void onResultCallback(Gimbal.Result result) { 44 | 45 | Log.d(TAG, result.resultStr); 46 | } 47 | }; 48 | } 49 | } 50 | 51 | public static void unRegisterGimbalListener() { 52 | 53 | if (gimbalResultListener != null) { 54 | gimbalResultListener = null; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/component/listeners/TelemetryListener.java: -------------------------------------------------------------------------------- 1 | package com.yuneec.example.component.listeners; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | 6 | import com.yuneec.example.component.custom_callback.OnChangeListener; 7 | import com.yuneec.example.component.utils.Common; 8 | import com.yuneec.sdk.Telemetry; 9 | 10 | /** 11 | * Created by sushma on 8/18/17. 12 | */ 13 | 14 | public class TelemetryListener { 15 | 16 | private static Telemetry.BatteryListener batteryListener = null; 17 | 18 | private static Telemetry.HealthListener healthListener = null; 19 | 20 | private static final String TAG = TelemetryListener.class.getCanonicalName(); 21 | 22 | private static OnChangeListener onChangeListener; 23 | 24 | public static void registerBatteryListener(final Context context) { 25 | 26 | onChangeListener = (OnChangeListener) context; 27 | if (batteryListener == null) { 28 | Log.d(TAG, "Initialized battery result listener"); 29 | batteryListener = new Telemetry.BatteryListener() { 30 | 31 | 32 | @Override 33 | public void onBatteryCallback(Telemetry.Battery battery) { 34 | 35 | ((OnChangeListener) context).publishBatteryChangeStatus( 36 | String.format("%d", (int)(100 * battery.remainingPercent))); 37 | //Log.d(TAG, String.format("%d", (int)(100 * battery.remainingPercent))); 38 | } 39 | }; 40 | } 41 | Telemetry.setBatteryListener(batteryListener); 42 | } 43 | 44 | public static void unRegisterBatteryListener() { 45 | 46 | Common.batteryStatus = Common.batteryStatusDefault; 47 | if (batteryListener != null) { 48 | batteryListener = null; 49 | } 50 | } 51 | 52 | public static void registerHealthListener(final Context context) { 53 | 54 | onChangeListener = (OnChangeListener) context; 55 | if (healthListener == null) { 56 | Log.d(TAG, "Initialized health result listener"); 57 | healthListener = new Telemetry.HealthListener() { 58 | 59 | @Override 60 | public void onHealthCallback(Telemetry.Health health) { 61 | 62 | boolean calibrationOk = health.accelerometerCalibrationOk && 63 | health.gyrometerCalibrationOk && 64 | health.magnetometerCalibrationOk && 65 | health.levelCalibrationOk; 66 | 67 | boolean positionOk = health.globalPositionOk && 68 | health.localPositionOk && 69 | health.homePositionOk; 70 | if (calibrationOk && positionOk) { 71 | ((OnChangeListener) context).publishHealthChangeStatus("Calibration and position is okay"); 72 | } else { 73 | if (calibrationOk) { 74 | ((OnChangeListener) context).publishHealthChangeStatus("Position is not okay"); 75 | 76 | } else { 77 | ((OnChangeListener) context).publishHealthChangeStatus("Calibration is not okay"); 78 | } 79 | } 80 | } 81 | }; 82 | } 83 | 84 | Telemetry.setHealthListener(healthListener); 85 | } 86 | 87 | public static void unRegisterHealthListener() { 88 | 89 | Common.healthStatus = Common.healthStatusDefault; 90 | if (healthListener != null) { 91 | healthListener = null; 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/component/listeners/YuneecSt16Listener.java: -------------------------------------------------------------------------------- 1 | package com.yuneec.example.component.listeners; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | 6 | import com.yuneec.example.component.custom_callback.OnChangeListener; 7 | import com.yuneec.sdk.YuneecSt16; 8 | 9 | /** 10 | * Created by Julian Oes on 11/29/17. 11 | * 12 | * TODO: this listeners have duplicate initialization code. This needs to be cleaned up. 13 | */ 14 | 15 | public class YuneecSt16Listener { 16 | 17 | private static YuneecSt16.ResultListener yuneecSt16ResultListener = null; 18 | private static YuneecSt16.ButtonStateListener yuneecSt16ButtonStateListener = null; 19 | private static YuneecSt16.SwitchStateListener yuneecSt16SwitchStateListener = null; 20 | private static YuneecSt16.GpsPositionListener yuneecSt16GpsListener = null; 21 | private static YuneecSt16.M4VersionListener yuneecSt16VersionListener = null; 22 | 23 | private static final String TAG = YuneecSt16Listener.class.getCanonicalName(); 24 | 25 | private static OnChangeListener onChangeListener; 26 | 27 | public static YuneecSt16.ResultListener getYuneecSt16ResultListener() { 28 | if (yuneecSt16ResultListener == null) { 29 | registerYuneecSt16ResultListener(); 30 | } 31 | return yuneecSt16ResultListener; 32 | } 33 | 34 | public static YuneecSt16.ButtonStateListener getYuneecSt16ButtonListener() { 35 | if (yuneecSt16ButtonStateListener == null) { 36 | registerYuneecSt16ButtonStateListener(); 37 | } 38 | 39 | return yuneecSt16ButtonStateListener; 40 | } 41 | 42 | public static YuneecSt16.SwitchStateListener getYuneecSt16SwitchListener() { 43 | if (yuneecSt16SwitchStateListener == null) { 44 | registerYuneecSt16SwitchStateListener(); 45 | } 46 | 47 | return yuneecSt16SwitchStateListener; 48 | } 49 | 50 | public static YuneecSt16.GpsPositionListener getYuneecSt16GpsPositionListener() { 51 | if (yuneecSt16GpsListener == null) { 52 | registerYuneecSt16GpsListener(); 53 | } 54 | 55 | return yuneecSt16GpsListener; 56 | } 57 | 58 | public static YuneecSt16.M4VersionListener getYuneecSt16VersionListener() { 59 | if (yuneecSt16VersionListener == null) { 60 | registerYuneecSt16VersionListener(); 61 | } 62 | 63 | return yuneecSt16VersionListener; 64 | } 65 | 66 | public static void registerYuneecSt16Listeners(Context context) { 67 | onChangeListener = (OnChangeListener) context; 68 | registerYuneecSt16ResultListener(); 69 | registerYuneecSt16ButtonStateListener(); 70 | registerYuneecSt16SwitchStateListener(); 71 | registerYuneecSt16GpsListener(); 72 | registerYuneecSt16VersionListener(); 73 | } 74 | 75 | private static void registerYuneecSt16ResultListener() { 76 | if (yuneecSt16ResultListener == null) { 77 | Log.d(TAG, "Initialized yuneecSt16 result listener"); 78 | yuneecSt16ResultListener = new YuneecSt16.ResultListener() { 79 | @Override 80 | public void onResultCallback(YuneecSt16.Result result) { 81 | Log.d(TAG, result.resultStr); 82 | onChangeListener.publishYuneecSt16Result(result.resultStr); 83 | } 84 | }; 85 | } 86 | } 87 | 88 | private static void registerYuneecSt16ButtonStateListener() { 89 | if (yuneecSt16ButtonStateListener == null) { 90 | Log.d(TAG, "Initialized yuneecSt16 button state listener"); 91 | yuneecSt16ButtonStateListener = new YuneecSt16.ButtonStateListener() { 92 | @Override 93 | public void onChangeCallback(YuneecSt16.ButtonId buttonId, YuneecSt16.ButtonState buttonState) { 94 | Log.d(TAG, "Button " + buttonId.toString() + " changed to " + buttonState.toString()); 95 | onChangeListener.publishYuneecSt16Result("Button " + buttonId.toString() + " changed to " + 96 | buttonState.toString()); 97 | } 98 | }; 99 | } 100 | YuneecSt16.setButtonStateListener(yuneecSt16ButtonStateListener); 101 | } 102 | 103 | private static void registerYuneecSt16SwitchStateListener() { 104 | if (yuneecSt16SwitchStateListener == null) { 105 | Log.d(TAG, "Initialized yuneecSt16 switch state listener"); 106 | yuneecSt16SwitchStateListener = new YuneecSt16.SwitchStateListener() { 107 | @Override 108 | public void onChangeCallback(YuneecSt16.SwitchId switchId, YuneecSt16.SwitchState switchState) { 109 | Log.d(TAG, "Switch " + switchId.toString() + " changed to " + switchState.toString()); 110 | onChangeListener.publishYuneecSt16Result("Switch " + switchId.toString() + " changed to " + 111 | switchState.toString()); 112 | } 113 | }; 114 | } 115 | YuneecSt16.setSwitchStateListener(yuneecSt16SwitchStateListener); 116 | } 117 | 118 | private static void registerYuneecSt16GpsListener() { 119 | if (yuneecSt16GpsListener == null) { 120 | Log.d(TAG, "Initialized yuneecSt16 GPS position listener"); 121 | yuneecSt16GpsListener = new YuneecSt16.GpsPositionListener() { 122 | @Override 123 | public void onCallback(YuneecSt16.GpsPosition gpsPosition) { 124 | Log.d(TAG, "ST16: Latitude: " + gpsPosition.latitudeDeg + ", longitude: " + 125 | gpsPosition.longitudeDeg); 126 | Log.d(TAG, "ST16: Altitude: " + gpsPosition.absoluteAltitudeM); 127 | Log.d(TAG, "ST16: Num satellites: " + gpsPosition.numSatellites); 128 | Log.d(TAG, "ST16: PDOP: " + gpsPosition.pdop); 129 | Log.d(TAG, "ST16: Speed: " + gpsPosition.speedMs); 130 | Log.d(TAG, "ST16: Heading: " + gpsPosition.headingDeg); 131 | // TODO: Display required Gps data to the user 132 | //onChangeListener.publishYuneecSt16Result("ST16: Latitude: " + gpsPosition.latitudeDeg + 133 | // ", longitude: " + 134 | // gpsPosition.longitudeDeg); 135 | } 136 | }; 137 | } 138 | YuneecSt16.setGpsPositionListener(yuneecSt16GpsListener); 139 | } 140 | 141 | private static void registerYuneecSt16VersionListener() { 142 | if (yuneecSt16VersionListener == null) { 143 | Log.d(TAG, "Initialized yuneecSt16 version listener"); 144 | yuneecSt16VersionListener = new YuneecSt16.M4VersionListener() { 145 | @Override 146 | public void onCallback(YuneecSt16.Result result, YuneecSt16.M4Version version) { 147 | if (result.resultID == YuneecSt16.Result.ResultID.SUCCESS) { 148 | Log.d(TAG, "ST16: Got version callback"); 149 | onChangeListener.publishYuneecSt16Result("Version: " + version.major + 150 | "." + 151 | version.minor + 152 | "." + 153 | version.patch); 154 | } else { 155 | Log.d(TAG, "ST16: could not get version"); 156 | } 157 | } 158 | }; 159 | } 160 | YuneecSt16.setGpsPositionListener(yuneecSt16GpsListener); 161 | } 162 | 163 | public static void unRegisterYuneecSt16Listeners() { 164 | 165 | if (yuneecSt16ResultListener != null) { 166 | yuneecSt16ResultListener = null; 167 | } 168 | 169 | if (yuneecSt16ButtonStateListener != null) { 170 | yuneecSt16ButtonStateListener = null; 171 | } 172 | 173 | if (yuneecSt16SwitchStateListener != null) { 174 | yuneecSt16SwitchStateListener = null; 175 | } 176 | 177 | if (yuneecSt16GpsListener != null) { 178 | yuneecSt16GpsListener = null; 179 | } 180 | 181 | if (yuneecSt16VersionListener != null) { 182 | yuneecSt16VersionListener = null; 183 | } 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/component/utils/Common.java: -------------------------------------------------------------------------------- 1 | package com.yuneec.example.component.utils; 2 | 3 | import android.content.Context; 4 | import android.graphics.Color; 5 | import android.support.v4.content.ContextCompat; 6 | import android.widget.TextView; 7 | import android.widget.Toast; 8 | 9 | import com.yuneec.example.R; 10 | 11 | /** 12 | * Created by sushma on 8/14/17. 13 | */ 14 | 15 | public class Common { 16 | 17 | public static final String VideoStreamUrl = "rtsp://192.168.42.1/live"; 18 | 19 | public static final int fixedRotationAngleDeg = 20; 20 | 21 | public static final String connectionStatusDefault = "Not connected to the drone"; 22 | 23 | public static final String batteryStatusDefault = "Unknown"; 24 | 25 | public static final String healthStatusDefault = "Unknown"; 26 | 27 | public static String connectionStatus = connectionStatusDefault; 28 | 29 | public static String healthStatus = healthStatusDefault; 30 | 31 | public static String batteryStatus = batteryStatusDefault; 32 | 33 | public static boolean isConnected = false; 34 | 35 | public static int defaultPhotoIntervalInSeconds = 4; 36 | 37 | public static Toast makeToast(Context context, String message) { 38 | Toast toast = Toast.makeText(context, message, Toast.LENGTH_SHORT); 39 | TextView v = (TextView) toast.getView().findViewById(android.R.id.message); 40 | v.setBackgroundColor(ContextCompat.getColor(context, R.color.greyDark)); 41 | v.setTextColor(ContextCompat.getColor(context, R.color.white)); 42 | toast.show(); 43 | return toast; 44 | } 45 | 46 | public static float currentYaw = 0.0f; 47 | public static float currentPitch = 0.0f; 48 | 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/component/utils/Media.java: -------------------------------------------------------------------------------- 1 | package com.yuneec.example.component.utils; 2 | 3 | import android.content.Context; 4 | import android.os.Vibrator; 5 | 6 | /** 7 | * Created by sushmas on 9/13/17. 8 | */ 9 | 10 | public class Media { 11 | public static void vibrate(Context context) { 12 | Vibrator vibe = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); 13 | vibe.vibrate(100); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/model/MediaInfoEntry.java: -------------------------------------------------------------------------------- 1 | package com.yuneec.example.model; 2 | 3 | /** 4 | * Created by sushmas on 8/29/17. 5 | */ 6 | 7 | public class MediaInfoEntry { 8 | 9 | public String path; 10 | 11 | public String title; 12 | 13 | public String description; 14 | 15 | public boolean downloaded = false; 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/view/CustomButton.java: -------------------------------------------------------------------------------- 1 | package com.yuneec.example.view; 2 | 3 | import android.content.Context; 4 | import android.graphics.Typeface; 5 | import android.util.AttributeSet; 6 | import android.widget.Button; 7 | 8 | /** 9 | * Created by sushmas on 9/15/17. 10 | */ 11 | 12 | public class CustomButton extends android.support.v7.widget.AppCompatButton { 13 | 14 | 15 | public CustomButton(Context context) { 16 | super(context); 17 | init(); 18 | } 19 | 20 | public CustomButton(Context context, AttributeSet attrs) { 21 | super(context, attrs); 22 | init(); 23 | } 24 | 25 | public CustomButton(Context context, AttributeSet attrs, int defStyleAttr) { 26 | super(context, attrs, defStyleAttr); 27 | init(); 28 | } 29 | 30 | public void init() { 31 | Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "font/Lato-Regular.ttf"); 32 | setTypeface(tf, 0); 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/view/CustomEditTextView.java: -------------------------------------------------------------------------------- 1 | package com.yuneec.example.view; 2 | 3 | import android.content.Context; 4 | import android.graphics.Typeface; 5 | import android.util.AttributeSet; 6 | 7 | /** 8 | * Created by sushmas on 10/25/17. 9 | */ 10 | 11 | public class CustomEditTextView extends android.support.v7.widget.AppCompatEditText { 12 | 13 | public CustomEditTextView(Context context, AttributeSet attrs, int defStyle) { 14 | super(context, attrs, defStyle); 15 | init(); 16 | } 17 | 18 | public CustomEditTextView(Context context, AttributeSet attrs) { 19 | super(context, attrs); 20 | init(); 21 | } 22 | 23 | public CustomEditTextView(Context context) { 24 | super(context); 25 | init(); 26 | } 27 | 28 | public void init() { 29 | Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "font/Lato-Regular.ttf"); 30 | setTypeface(tf, 1); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/yuneec/example/view/CustomTextView.java: -------------------------------------------------------------------------------- 1 | package com.yuneec.example.view; 2 | 3 | import android.content.Context; 4 | import android.graphics.Typeface; 5 | import android.util.AttributeSet; 6 | 7 | 8 | /** 9 | * Created by sushmas on 9/15/17. 10 | */ 11 | 12 | public class CustomTextView extends android.support.v7.widget.AppCompatTextView { 13 | 14 | public CustomTextView(Context context, AttributeSet attrs, int defStyle) { 15 | super(context, attrs, defStyle); 16 | init(); 17 | } 18 | 19 | public CustomTextView(Context context, AttributeSet attrs) { 20 | super(context, attrs); 21 | init(); 22 | } 23 | 24 | public CustomTextView(Context context) { 25 | super(context); 26 | init(); 27 | } 28 | 29 | public void init() { 30 | Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "font/Lato-Regular.ttf"); 31 | setTypeface(tf, 1); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/res/layout/action_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | 14 | 21 | 22 | 30 | 31 | 38 | 39 | 47 | 48 | 56 | 57 | 65 | 66 | 67 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /app/src/main/res/layout/camera_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 13 | 14 | 20 | 21 | 27 | 28 | 34 | 35 | 36 | 37 | 43 | 44 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/layout/camera_setting_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 12 | 13 | 17 | 18 | 21 | 22 | 29 | 30 | 35 | 36 | 37 | 38 | 41 | 49 | 50 | 55 | 56 | 57 | 60 | 67 | 68 | 73 | 74 | 75 | 78 | 86 | 87 | 92 | 93 | 94 | 97 | 106 | 107 | 113 | 114 | 115 | 118 | 127 | 128 | 134 | 135 | 136 | 139 | 147 | 148 | 153 | 154 | 155 | 158 | 166 | 167 | 172 | 173 | 174 | 177 | 185 | 186 | 191 | 192 | 193 | 196 | 204 | 205 | 210 | 211 | 212 | 215 | 223 | 224 | 229 | 230 | 231 | 232 | 235 | 241 | 242 | 249 | 250 | 251 | 254 | 260 | 261 | 268 | 269 | 270 | 273 | 279 | 280 | 287 | 288 | 289 | 290 | 293 | 299 | 300 | 307 | 308 | 309 | 312 | 318 | 319 | 326 | 327 | 328 | 331 | 337 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | -------------------------------------------------------------------------------- /app/src/main/res/layout/connection_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 15 | 21 | 22 | 29 | 30 | 31 | 32 | 37 | 38 | 39 | 45 | 46 | 53 | 54 | 55 | 56 | 61 | 62 | 63 | 69 | 70 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /app/src/main/res/layout/custom_spinner_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /app/src/main/res/layout/gimbal_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 18 | 19 | 24 | 25 | 31 | 32 | 42 | 43 | 48 | 49 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /app/src/main/res/layout/list_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 13 | 14 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/layout/main_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 18 | 19 | 25 | 26 | 27 | 32 | 33 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /app/src/main/res/layout/media_download_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/layout/mission_example.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 |