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 |
16 |
17 |
18 |
21 |
22 |
27 |
28 |
29 |
32 |
33 |
38 |
39 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/spinner_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/st16_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
21 |
22 |
30 |
31 |
39 |
40 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/telemetry_example.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YUNEEC/Yuneec-SDK-Android-Example/5feac26f415998fd3c221c1a2ee56c8275821744/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YUNEEC/Yuneec-SDK-Android-Example/5feac26f415998fd3c221c1a2ee56c8275821744/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YUNEEC/Yuneec-SDK-Android-Example/5feac26f415998fd3c221c1a2ee56c8275821744/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YUNEEC/Yuneec-SDK-Android-Example/5feac26f415998fd3c221c1a2ee56c8275821744/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YUNEEC/Yuneec-SDK-Android-Example/5feac26f415998fd3c221c1a2ee56c8275821744/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 | #000000
7 | #FFFFFF
8 | #dbdbdb
9 | #FF8C00
10 | #F04C24
11 | #696969
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 | 16dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | YuneecAndroidExample
3 | Enter value in degree starting 0
4 | Set Yaw
5 | Enter value in degree (0 to -90)
6 | Set Pitch
7 | Rotate camera anti-clockwise
8 | Bring to Initial Forward Position
9 | Connection Status:
10 | Battery Percentage:
11 | Not connected to the drone
12 | Health Status:
13 | Unknown
14 | Please enter yaw degree, before clicking rotate button
15 |
16 | White Balance Mode
17 | Exposure Mode
18 | Exposure Compensation
19 | ISO Value
20 | Shutter Speed
21 | Get Resolution
22 | Get Photo Quality
23 | Photo Quality
24 | Get Photo Format
25 | Photo Format
26 | Get Video Format
27 | Video Format
28 | Get Video Resolution
29 | Video Resolution
30 | Get Metering
31 | Metering
32 |
33 | Color Mode
34 | Capture Picture
35 | Start Video
36 | Stop Video
37 | Start Capturing Photos
38 | Stop Capturing Photos
39 | Enter takeoff altitude in meters (Optional)
40 | Edit Camera Settings
41 |
42 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
15 |
16 |
22 |
23 |
29 |
30 |
37 |
38 |
49 |
50 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/provider_paths.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
--------------------------------------------------------------------------------
/astylerc:
--------------------------------------------------------------------------------
1 | indent=spaces=4
2 | style=java
3 | pad-oper
4 | pad-header
5 | unpad-paren
6 | lineend=linux
7 | add-braces
8 | indent-switches
9 | max-code-length=100
10 | keep-one-line-blocks
11 | keep-one-line-statements
12 | attach-namespaces
13 | max-continuation-indent=80
14 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | repositories {
4 | jcenter()
5 | google()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:3.1.2'
9 | classpath 'de.undercouch:gradle-download-task:3.3.0'
10 | }
11 | }
12 | allprojects {
13 | repositories {
14 | jcenter()
15 | maven {
16 | url 'https://jitpack.io'
17 | }
18 | google()
19 | }
20 | }
21 | task clean(type: Delete) {
22 | delete rootProject.buildDir
23 | }
24 |
25 | //android {
26 | // compileSdkVersion 23
27 | // buildToolsVersion '25.0.2'
28 | // compileOptions {
29 | // sourceCompatibility JavaVersion.VERSION_1_6
30 | // targetCompatibility JavaVersion.VERSION_1_6
31 | // }
32 | //}
33 | dependencies {
34 | }
35 |
--------------------------------------------------------------------------------
/fix_style.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # This script runs astyle and complains about lines that are too long
4 | # over all files ending in .h, .c, .cpp listed by git in the given
5 | # directory.
6 |
7 | # Check for the latest astyle version
8 | ASTYLE_VER_REQUIRED_1="Artistic Style Version 2.05.1"
9 | ASTYLE_VER_REQUIRED_2="Artistic Style Version 2.06"
10 | ASTYLE_VER_REQUIRED_3="Artistic Style Version 3.0"
11 | ASTYLE_VER_REQUIRED_4="Artistic Style Version 3.0.1"
12 |
13 | astyle_ver() {
14 | echo "At least ${ASTYLE_VER_REQUIRED_1} is required"
15 | echo "You can get the correct version here: https://sourceforge.net/projects/astyle/files/astyle/astyle%202.06/"
16 | }
17 |
18 | # check if astyle is installed
19 | condition=$(which astyle 2>/dev/null | grep -v "not found" | wc -l)
20 | if [ $condition -eq 0 ]; then
21 | echo "astyle is not installed"
22 | astyle_ver
23 | exit 1
24 | else
25 |
26 | ASTYLE_VER=`astyle --version`
27 |
28 | if [ "$ASTYLE_VER" != "$ASTYLE_VER_REQUIRED_1" -a \
29 | "$ASTYLE_VER" != "$ASTYLE_VER_REQUIRED_2" -a \
30 | "$ASTYLE_VER" != "$ASTYLE_VER_REQUIRED_3" -a \
31 | "$ASTYLE_VER" != "$ASTYLE_VER_REQUIRED_4" ];
32 | then
33 | echo "Error: you're using ${ASTYLE_VER}"
34 | echo "but should be using ${ASTYLE_VER_REQUIRED} instead"
35 | exit 1
36 | fi
37 | fi
38 |
39 | # Check that exactly one directory is given
40 | if [ $# -eq 0 ];
41 | then
42 | echo "No directory supplied"
43 | echo "Usage: ./fix_style.sh dir"
44 | exit 1
45 |
46 | elif [ $# -gt 1 ];
47 | then
48 | echo "Too many directories supplied"
49 | echo "Usage: ./fix_style.sh dir"
50 | exit 1
51 | fi
52 |
53 | # Ignore files listed in style-ignore.txt
54 | style_ignore="style-ignore.txt"
55 |
56 | # Find the directory of this script because the file astylerc should be
57 | # next to it.
58 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
59 |
60 | # Keep track of errors for the exit value
61 | error_found=false
62 |
63 | # Use colordiff if available
64 | if command -v colordiff >/dev/null 2>&1; then
65 | diff_cmd=colordiff
66 | else
67 | diff_cmd=diff
68 | fi
69 |
70 | cd $1 > /dev/null
71 |
72 | # Go through all .h .cpp and .java files listed by git
73 | # TODO: add -r argument to include all files
74 | files=`git ls-files | grep -E "\.h$|\.cpp$|\.java$"`
75 |
76 | while IFS= read file; do
77 |
78 | # We want to check if the file is in the list to ignore.
79 | # We do this in a brute force way by looping through every
80 | # line the ignore file and compare it against the filename.
81 | if [[ -f $SCRIPT_DIR/$style_ignore ]]; then
82 | need_to_ignore=false
83 | while IFS= read ignore; do
84 | if [[ `echo $1/$file | grep "$ignore"` ]]; then
85 | need_to_ignore=true
86 | fi
87 | done < "$SCRIPT_DIR/$style_ignore"
88 | fi
89 |
90 | if [ "$need_to_ignore" = true ]; then
91 | # Don't do the astyle and file length checks,
92 | # go to next file.
93 | continue
94 | fi
95 |
96 | # Run astyle with given astylerc
97 | echo "Check $file"
98 | astyle_result=`astyle --options=$SCRIPT_DIR/astylerc $file | grep "Formatted"`
99 |
100 | if [[ $astyle_result ]]; then
101 | echo "Formatted $file:"
102 | $diff_cmd $file $file.orig
103 | rm $file.orig
104 | error_found=true
105 | fi
106 |
107 | # TODO: this is disabled for now
108 | ## Go line by line
109 | #count=0
110 | #while IFS= read -r line; do
111 | # # Check for lines too long
112 | # len=${#line}
113 | # if [ $len -gt 100 ]; then
114 | # echo "Line $count too long"
115 | # error_found=true
116 | # fi
117 | # (( count++ ))
118 | #done < "$file"
119 |
120 | # We need to use this clunky way because otherwise
121 | # we lose the value of error_found.
122 | # See http://mywiki.wooledge.org/BashFAQ/024
123 | done < <(echo "$files")
124 |
125 | cd - > /dev/null
126 |
127 | if [ "$error_found" = true ]; then
128 | exit 1
129 | fi
130 |
131 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YUNEEC/Yuneec-SDK-Android-Example/5feac26f415998fd3c221c1a2ee56c8275821744/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon May 14 09:04:31 EDT 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 | include ':Yuneec-SDK-Android:yuneec_sdk'
3 |
--------------------------------------------------------------------------------
/sitl/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu:16.04
2 |
3 | RUN apt-get update
4 | RUN apt-get install -y apt-utils
5 | RUN apt-get install -y wget
6 | RUN apt-get install -y unzip
7 | RUN apt-get install -y lsb-release
8 |
9 | RUN echo "deb http://packages.osrfoundation.org/gazebo/ubuntu-stable `lsb_release -cs` main" > /etc/apt/sources.list.d/gazebo-stable.list
10 | RUN wget http://packages.osrfoundation.org/gazebo.key -O - | apt-key add -
11 |
12 | RUN apt-get update
13 | RUN apt-get install -y gazebo7 libgazebo7-dev
14 |
15 | RUN wget https://s3.eu-central-1.amazonaws.com/08f61bbd-8958-433e-8e83-5d79160fa0be/sitl/latest/Yuneec-SITL-Simulation-Linux.zip -P /root/
16 | RUN unzip /root/Yuneec-SITL-Simulation-Linux.zip -d /root/
17 | RUN mkdir /root/posix-configs/SITL/init/ekf2
18 | RUN cp /root/posix-configs/SITL/init/default/typhoon_h480 /root/posix-configs/SITL/init/ekf2/typhoon_h480
19 |
20 | EXPOSE 14540
21 | EXPOSE 14550
22 |
23 | WORKDIR /root
24 | CMD HEADLESS=1 /root/typhoon_sitl.bash
25 |
--------------------------------------------------------------------------------
/sitl/README.md:
--------------------------------------------------------------------------------
1 | # Running SITL in Docker
2 | ## Description
3 | This is an example of running SITL headless in a Docker container.
4 |
5 | ## Building the docker image
6 | From this directory, run:
7 |
8 | $ docker build -t yuneec-sitl .
9 |
10 | An image called `yuneec-sitl` should be created. Note that the latest version of the SITL simulator is downloaded at that point.
11 |
12 | ## Running a SITL container
13 | Run the following command:
14 |
15 | $ docker run -it yuneec-sitl
16 |
17 | More details on how to use the SITL simulation can be found [here](https://github.com/YUNEEC/Yuneec-SDK-Android-Example-prerelease#run-the-simulation).
18 |
--------------------------------------------------------------------------------