├── README.md
├── app
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── app
│ │ └── akexorcist
│ │ └── ioiocamerarobot
│ │ ├── constant
│ │ ├── Command.java
│ │ ├── DirectionState.java
│ │ └── ExtraKey.java
│ │ ├── controller
│ │ ├── ConnectionManager.java
│ │ ├── ControllerActivity.java
│ │ ├── ControllerSetupActivity.java
│ │ └── JoyStickManager.java
│ │ ├── ioio
│ │ ├── CameraManager.java
│ │ ├── ConnectionManager.java
│ │ ├── IOIOControllerActivity.java
│ │ ├── IOIOService.java
│ │ ├── IOIOSetupActivity.java
│ │ └── OrientationManager.java
│ │ ├── menu
│ │ └── MenuActivity.java
│ │ ├── splashscreen
│ │ └── SplashScreenActivity.java
│ │ └── utils
│ │ ├── JoyStickView.java
│ │ └── Utilities.java
│ └── res
│ ├── anim
│ ├── fade_in.xml
│ └── fade_out.xml
│ ├── animator
│ ├── fade_in.xml
│ ├── fade_out.xml
│ ├── set_menu_slide_down.xml
│ ├── set_menu_slide_up.xml
│ └── set_splashscreen.xml
│ ├── drawable-hdpi
│ └── ic_launcher.png
│ ├── drawable-ldpi
│ └── ic_launcher.png
│ ├── drawable-mdpi
│ ├── button_cancel_normal.png
│ ├── button_cancel_pressed.png
│ ├── button_center.png
│ ├── button_down_normal.png
│ ├── button_down_pressed.png
│ ├── button_downleft_normal.png
│ ├── button_downleft_pressed.png
│ ├── button_downright_normal.png
│ ├── button_downright_pressed.png
│ ├── button_flash_off_normal.png
│ ├── button_flash_off_pressed.png
│ ├── button_flash_on_normal.png
│ ├── button_flash_on_pressed.png
│ ├── button_focus_normal.png
│ ├── button_focus_pressed.png
│ ├── button_left_normal.png
│ ├── button_left_pressed.png
│ ├── button_login_normal.png
│ ├── button_login_pressed.png
│ ├── button_mode_control_normal.png
│ ├── button_mode_control_pressed.png
│ ├── button_mode_ioio_normal.png
│ ├── button_mode_ioio_pressed.png
│ ├── button_right_normal.png
│ ├── button_right_pressed.png
│ ├── button_snap_normal.png
│ ├── button_snap_pressed.png
│ ├── button_start_normal.png
│ ├── button_start_pressed.png
│ ├── button_up_normal.png
│ ├── button_up_pressed.png
│ ├── button_upleft_normal.png
│ ├── button_upleft_pressed.png
│ ├── button_upright_normal.png
│ ├── button_upright_pressed.png
│ ├── center.png
│ ├── dialog_header_control.png
│ ├── dialog_header_ioio.png
│ ├── edittext_bg.png
│ ├── ic_launcher.png
│ ├── image_button.png
│ ├── image_button_bg.png
│ ├── image_divider.png
│ ├── logo_inex.jpg
│ ├── seekbar_bg.9.png
│ ├── seekbar_stripe_bg.png
│ ├── spinner_bg_normal.png
│ ├── spinner_bg_pressed.png
│ ├── spinner_dropdownlist_normal.png
│ └── spinner_dropdownlist_pressed.png
│ ├── drawable-xhdpi
│ ├── button_cancel_normal.png
│ ├── button_cancel_pressed.png
│ ├── button_center.png
│ ├── button_down_normal.png
│ ├── button_down_pressed.png
│ ├── button_downleft_normal.png
│ ├── button_downleft_pressed.png
│ ├── button_downright_normal.png
│ ├── button_downright_pressed.png
│ ├── button_flash_off_normal.png
│ ├── button_flash_off_pressed.png
│ ├── button_flash_on_normal.png
│ ├── button_flash_on_pressed.png
│ ├── button_focus_normal.png
│ ├── button_focus_pressed.png
│ ├── button_left_normal.png
│ ├── button_left_pressed.png
│ ├── button_login_normal.png
│ ├── button_login_pressed.png
│ ├── button_mode_control_normal.png
│ ├── button_mode_control_pressed.png
│ ├── button_mode_ioio_normal.png
│ ├── button_mode_ioio_pressed.png
│ ├── button_right_normal.png
│ ├── button_right_pressed.png
│ ├── button_snap_normal.png
│ ├── button_snap_pressed.png
│ ├── button_start_normal.png
│ ├── button_start_pressed.png
│ ├── button_up_normal.png
│ ├── button_up_pressed.png
│ ├── button_upleft_normal.png
│ ├── button_upleft_pressed.png
│ ├── button_upright_normal.png
│ ├── button_upright_pressed.png
│ ├── center.png
│ ├── dialog_header_control.png
│ ├── dialog_header_ioio.png
│ ├── edittext_bg.png
│ ├── ic_launcher.png
│ ├── image_button.png
│ ├── image_button_bg.png
│ ├── image_divider.png
│ ├── logo_inex.jpg
│ ├── seekbar_bg.9.png
│ ├── seekbar_stripe_bg.png
│ ├── spinner_bg_normal.png
│ ├── spinner_bg_pressed.png
│ ├── spinner_dropdownlist_normal.png
│ └── spinner_dropdownlist_pressed.png
│ ├── drawable-xxhdpi
│ └── ic_launcher.png
│ ├── drawable
│ ├── button_cancel.xml
│ ├── button_down.xml
│ ├── button_downleft.xml
│ ├── button_downright.xml
│ ├── button_flash.xml
│ ├── button_focus.xml
│ ├── button_left.xml
│ ├── button_login.xml
│ ├── button_mode_control.xml
│ ├── button_mode_ioio.xml
│ ├── button_right.xml
│ ├── button_snap.xml
│ ├── button_start.xml
│ ├── button_up.xml
│ ├── button_upleft.xml
│ ├── button_upright.xml
│ ├── seekbar_progress.xml
│ ├── spinner_background.xml
│ └── spinner_dropdownlist.xml
│ ├── layout
│ ├── activity_controller.xml
│ ├── activity_controller_connection.xml
│ ├── activity_ioio.xml
│ ├── activity_ioio_setup.xml
│ ├── activity_main.xml
│ ├── activity_splashscreen.xml
│ ├── dialog_camera_size.xml
│ ├── view_simple_text.xml
│ └── view_simple_textview.xml
│ ├── values-large
│ └── dimens.xml
│ ├── values-normal
│ └── dimens.xml
│ ├── values-small
│ └── dimens.xml
│ ├── values-xlarge
│ └── dimens.xml
│ ├── values
│ ├── colors.xml
│ ├── strings.xml
│ └── styles.xml
│ └── xml
│ └── accessory_filter.xml
├── build.gradle
├── doc
├── Screenshot_2015-09-06-00-15-35_framed.png
├── Screenshot_2015-09-06-00-16-05_framed.png
├── Screenshot_20150906-001533_framed.png
├── Screenshot_20150910-151759_framed.png
├── circuit-thumbnail.jpg
├── circuit.ai
├── circuit.jpg
├── connection-01.jpg
├── connection-02.jpg
└── header.jpg
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # IOIO-CameraRobot
4 | IOIO Robot Car with Real-time Camera from Android Device that Controlled with Another Android Device via WiFi.
5 |
6 |
7 | Parts List
8 | ===========================
9 | + IOIO Board x1
10 | + Bluetooth Dongle x1
11 | + Pololu TB6612FNG Dual Motor Driver x2
12 | + 5V DC Motor x4
13 | + 7.4V LiPo Battery x1
14 | + Android Phone x2
15 | + Any Robot Chassis
16 |
17 |
18 | Hardware Instructions
19 | ===========================
20 | 
21 |
22 | + (IOIO) Pin 1 <> AIN1 (TB6612 Left)
23 | + (IOIO) Pin 2 <> AIN2 (TB6612 Left)
24 | + (IOIO) Pin 3 <> PWMA (TB6612 Left)
25 | + (IOIO) Pin 4 <> PWMB (TB6612 Left)
26 | + (IOIO) Pin 5 <> BIN2 (TB6612 Left)
27 | + (IOIO) Pin 6 <> BIN1 (TB6612 Left)
28 | + (IOIO) Pin 16 <> AIN1 (TB6612 Right)
29 | + (IOIO) Pin 17 <> AIN2 (TB6612 Right)
30 | + (IOIO) Pin 13 <> PWMA (TB6612 Right)
31 | + (IOIO) Pin 14 <> PWMB (TB6612 Right)
32 | + (IOIO) Pin 18 <> BIN2 (TB6612 Right)
33 | + (IOIO) Pin 19 <> BIN1 (TB6612 Right)
34 |
35 |
36 | Download Application
37 | ===========================
38 |
39 |
41 |
42 |
43 |
44 | Licence
45 | ===========================
46 | Copyright 2015 Akexorcist
47 |
48 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with the License. You may obtain a copy of the License in the LICENSE file, or at:
49 |
50 | http://www.apache.org/licenses/LICENSE-2.0
51 |
52 | Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
53 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 22
5 | buildToolsVersion "22.0.1"
6 |
7 | defaultConfig {
8 | applicationId "app.akexorcist.ioiocamerarobot"
9 | minSdkVersion 11
10 | targetSdkVersion 22
11 | }
12 |
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | compile 'com.android.support:support-v4:22.2.1'
23 | compile 'com.github.ytai.ioio:IOIOLibAndroid:5.05'
24 | compile 'com.github.ytai.ioio:IOIOLibAndroidBluetooth:5.05'
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
23 |
26 |
27 |
32 |
35 |
36 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
50 |
51 |
54 |
57 |
60 |
63 |
66 |
67 |
--------------------------------------------------------------------------------
/app/src/main/java/app/akexorcist/ioiocamerarobot/constant/Command.java:
--------------------------------------------------------------------------------
1 | package app.akexorcist.ioiocamerarobot.constant;
2 |
3 | /**
4 | * Created by Akexorcist on 9/5/15 AD.
5 | */
6 | public class Command {
7 | public static final String ACCEPT_CONNECTION = "ACCEPT";
8 | public static final String WRONG_PASSWORD = "WRONG";
9 | public static final String LED_ON = "LEDON";
10 | public static final String LED_OFF = "LEDOFF";
11 | public static final String FLASH_UNAVAILABLE = "NoFlash";
12 | public static final String SNAP = "SNAP";
13 | public static final String FOCUS = "FOCUS";
14 |
15 | // Unique command for IOIO Service
16 | public static final int MESSAGE_UPDATE = 0;
17 | public static final int MESSAGE_CLOSE = 1;
18 | public static final int MESSAGE_TOAST = 2;
19 | public static final int MESSAGE_PASS = 3;
20 | public static final int MESSAGE_WRONG = 4;
21 | public static final int MESSAGE_DISCONNECTED = 5;
22 | public static final int MESSAGE_FLASH = 6;
23 | public static final int MESSAGE_SNAP = 7;
24 | public static final int MESSAGE_FOCUS = 8;
25 | public static final int MESSAGE_STOP = 10;
26 | public static final int MESSAGE_UP = 11;
27 | public static final int MESSAGE_UPRIGHT = 12;
28 | public static final int MESSAGE_RIGHT = 13;
29 | public static final int MESSAGE_DOWNRIGHT = 14;
30 | public static final int MESSAGE_DOWN = 15;
31 | public static final int MESSAGE_DOWNLEFT = 16;
32 | public static final int MESSAGE_LEFT = 17;
33 | public static final int MESSAGE_UPLEFT = 18;
34 |
35 | public static final String FORWARD = "UU";
36 | public static final String FORWARD_RIGHT = "UR";
37 | public static final String FORWARD_LEFT = "UL";
38 | public static final String BACKWARD = "DD";
39 | public static final String BACKWARD_RIGHT = "DR";
40 | public static final String BACKWARD_LEFT = "DL";
41 | public static final String RIGHT = "RR";
42 | public static final String LEFT = "LL";
43 | public static final String STOP = "SS";
44 |
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/app/src/main/java/app/akexorcist/ioiocamerarobot/constant/DirectionState.java:
--------------------------------------------------------------------------------
1 | package app.akexorcist.ioiocamerarobot.constant;
2 |
3 | /**
4 | * Created by Akexorcist on 9/5/15 AD.
5 | */
6 | public class DirectionState {
7 | public static final int STOP = 10;
8 | public static final int UP = 11;
9 | public static final int UPRIGHT = 12;
10 | public static final int RIGHT = 13;
11 | public static final int DOWNRIGHT = 14;
12 | public static final int DOWN = 15;
13 | public static final int DOWNLEFT = 16;
14 | public static final int LEFT = 17;
15 | public static final int UPLEFT = 18;
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/app/akexorcist/ioiocamerarobot/constant/ExtraKey.java:
--------------------------------------------------------------------------------
1 | package app.akexorcist.ioiocamerarobot.constant;
2 |
3 | /**
4 | * Created by Akexorcist on 9/5/15 AD.
5 | */
6 | public class ExtraKey {
7 | public static final String SETUP_PREFERENCE = "setup_preference";
8 | public static final String QUALITY = "quality";
9 | public static final String PREVIEW_SIZE = "preview_size";
10 | public static final String OWN_PASSWORD = "own_password";
11 | public static final String TARGET_PASSWORD = "target_password";
12 | public static final String IP_ADDRESS = "ip_address";
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/app/akexorcist/ioiocamerarobot/controller/ConnectionManager.java:
--------------------------------------------------------------------------------
1 | package app.akexorcist.ioiocamerarobot.controller;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 |
7 | import java.io.DataInputStream;
8 | import java.io.DataOutputStream;
9 | import java.io.EOFException;
10 | import java.io.IOException;
11 | import java.io.InputStream;
12 | import java.io.OutputStream;
13 | import java.net.DatagramPacket;
14 | import java.net.DatagramSocket;
15 | import java.net.InetAddress;
16 | import java.net.InetSocketAddress;
17 | import java.net.Socket;
18 | import java.net.UnknownHostException;
19 |
20 | import app.akexorcist.ioiocamerarobot.constant.Command;
21 |
22 | /**
23 | * Created by Akexorcist on 9/5/15 AD.
24 | */
25 | public class ConnectionManager {
26 | public static final int PORT = 21111;
27 | public static final int TIMEOUT = 5000;
28 | private Activity activity;
29 | private ConnectionListener connectionListener;
30 | private IOIOResponseListener responseListener;
31 |
32 | private OutputStream outputStream;
33 | private DataOutputStream dataOutputStream;
34 | private InputStream inputStream;
35 | private DataInputStream dataInputStream;
36 |
37 | private Socket socket;
38 | private boolean isTaskRunning = false;
39 |
40 | private String ipAddress;
41 | private String password;
42 |
43 | public ConnectionManager(Activity activity, String ipAddress, String password) {
44 | this.activity = activity;
45 | this.ipAddress = ipAddress;
46 | this.password = password;
47 | }
48 |
49 | public void setConnectionListener(ConnectionListener listener) {
50 | this.connectionListener = listener;
51 | }
52 |
53 | public void setResponseListener(IOIOResponseListener listener) {
54 | this.responseListener = listener;
55 | }
56 |
57 | public void start() {
58 | if (!isTaskRunning) {
59 | new Thread(readThread).start();
60 | isTaskRunning = true;
61 | }
62 | }
63 |
64 | Runnable readThread = new Runnable() {
65 | public void run() {
66 | try {
67 | socket = new Socket();
68 | socket.connect((new InetSocketAddress(InetAddress.getByName(ipAddress), PORT)), TIMEOUT);
69 |
70 | outputStream = socket.getOutputStream();
71 | dataOutputStream = new DataOutputStream(outputStream);
72 |
73 | inputStream = socket.getInputStream();
74 | dataInputStream = new DataInputStream(inputStream);
75 | sendCommand(password);
76 |
77 | while (isTaskRunning) {
78 | try {
79 | int size = dataInputStream.readInt();
80 | final byte[] buffer = new byte[size];
81 | dataInputStream.readFully(buffer);
82 |
83 | activity.runOnUiThread(new Runnable() {
84 | @Override
85 | public void run() {
86 | if (buffer.length > 0 && buffer.length < 20) {
87 | if (new String(buffer).equalsIgnoreCase(Command.SNAP)) {
88 | if (responseListener != null)
89 | responseListener.onPictureTaken();
90 | } else if (new String(buffer).equalsIgnoreCase(Command.WRONG_PASSWORD)) {
91 | if (connectionListener != null)
92 | connectionListener.onWrongPassword();
93 | } else if (new String(buffer).equalsIgnoreCase(Command.ACCEPT_CONNECTION)) {
94 | if (connectionListener != null)
95 | connectionListener.onIOIOConnected();
96 | } else if (new String(buffer).equalsIgnoreCase(Command.FLASH_UNAVAILABLE)) {
97 | if (responseListener != null)
98 | responseListener.onFlashUnavailable();
99 | }
100 | } else if (buffer.length > 20) {
101 | if (responseListener != null) {
102 | Bitmap bitmap = BitmapFactory.decodeByteArray(buffer, 0, buffer.length);
103 | responseListener.onCameraImageIncoming(bitmap);
104 | }
105 | }
106 | }
107 | });
108 | } catch (EOFException e) {
109 | e.printStackTrace();
110 | activity.runOnUiThread(new Runnable() {
111 | @Override
112 | public void run() {
113 | if (connectionListener != null)
114 | connectionListener.onConnectionDown();
115 | }
116 | });
117 | isTaskRunning = false;
118 | } catch (NumberFormatException | IOException e) {
119 | e.printStackTrace();
120 | }
121 | }
122 | } catch (NumberFormatException | UnknownHostException e) {
123 | e.printStackTrace();
124 | } catch (IOException e) {
125 | e.printStackTrace();
126 | activity.runOnUiThread(new Runnable() {
127 | @Override
128 | public void run() {
129 | if (connectionListener != null)
130 | connectionListener.onConnectionFailed();
131 | }
132 | });
133 | }
134 | }
135 | };
136 |
137 | public interface ConnectionListener {
138 | public void onConnectionDown();
139 |
140 | public void onConnectionFailed();
141 |
142 | public void onWrongPassword();
143 |
144 | public void onIOIOConnected();
145 | }
146 |
147 | public interface IOIOResponseListener {
148 | public void onPictureTaken();
149 |
150 | public void onFlashUnavailable();
151 |
152 | public void onCameraImageIncoming(Bitmap bitmap);
153 | }
154 |
155 | public void stop() {
156 | isTaskRunning = false;
157 | try {
158 | socket.close();
159 | outputStream.close();
160 | dataOutputStream.close();
161 | } catch (IOException | NullPointerException e) {
162 | e.printStackTrace();
163 | }
164 | }
165 |
166 | public boolean sendCommand(String str) {
167 | try {
168 | dataOutputStream.writeInt(str.length());
169 | dataOutputStream.write(str.getBytes());
170 | outputStream.flush();
171 | return true;
172 | } catch (IOException | NullPointerException e) {
173 | e.printStackTrace();
174 | }
175 | return false;
176 | }
177 |
178 | public void sendMovement(final String str) {
179 | new Thread(new Runnable() {
180 | public void run() {
181 | try {
182 | byte[] data = str.getBytes();
183 | DatagramSocket datagramSocket = new DatagramSocket();
184 | InetAddress inetAddress = InetAddress.getByName(ipAddress);
185 | DatagramPacket datagramPacket = new DatagramPacket(data, data.length, inetAddress, PORT);
186 | datagramSocket.send(datagramPacket);
187 | datagramSocket.close();
188 | } catch (IOException e) {
189 | e.printStackTrace();
190 | }
191 | }
192 | }).start();
193 | }
194 |
195 | }
196 |
--------------------------------------------------------------------------------
/app/src/main/java/app/akexorcist/ioiocamerarobot/controller/ControllerActivity.java:
--------------------------------------------------------------------------------
1 | package app.akexorcist.ioiocamerarobot.controller;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Bitmap;
5 | import android.os.Bundle;
6 | import android.view.View;
7 | import android.view.View.OnClickListener;
8 | import android.view.WindowManager;
9 | import android.widget.Button;
10 | import android.widget.CheckBox;
11 | import android.widget.CompoundButton;
12 | import android.widget.CompoundButton.OnCheckedChangeListener;
13 | import android.widget.ImageView;
14 | import android.widget.RelativeLayout;
15 | import android.widget.Toast;
16 |
17 | import app.akexorcist.ioiocamerarobot.R;
18 | import app.akexorcist.ioiocamerarobot.constant.Command;
19 | import app.akexorcist.ioiocamerarobot.constant.ExtraKey;
20 |
21 | public class ControllerActivity extends Activity implements ConnectionManager.IOIOResponseListener, ConnectionManager.ConnectionListener, OnClickListener, OnCheckedChangeListener, JoyStickManager.JoyStickEventListener {
22 | private ImageView ivCameraImage;
23 | private CheckBox cbFlash;
24 |
25 | private ConnectionManager connectionManager;
26 | private JoyStickManager joyStickManager;
27 |
28 | private Button btnTakePhoto;
29 | private Button btnAutoFocus;
30 | private RelativeLayout layoutJoyStick;
31 |
32 | protected void onCreate(Bundle savedInstanceState) {
33 | super.onCreate(savedInstanceState);
34 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
35 | | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
36 | setContentView(R.layout.activity_controller);
37 |
38 | int screenHeight = getWindowManager().getDefaultDisplay().getHeight();
39 |
40 | String ipAddress = getIntent().getExtras().getString(ExtraKey.IP_ADDRESS);
41 | String password = getIntent().getExtras().getString(ExtraKey.TARGET_PASSWORD);
42 |
43 | ivCameraImage = (ImageView) findViewById(R.id.iv_camera_image);
44 |
45 | layoutJoyStick = (RelativeLayout) findViewById(R.id.layout_joystick);
46 | joyStickManager = new JoyStickManager(this, layoutJoyStick, screenHeight);
47 | joyStickManager.setJoyStickEventListener(this);
48 |
49 | btnTakePhoto = (Button) findViewById(R.id.btn_take_photo);
50 | btnTakePhoto.setOnClickListener(this);
51 |
52 | btnAutoFocus = (Button) findViewById(R.id.btn_auto_focus);
53 | btnAutoFocus.setOnClickListener(this);
54 |
55 | cbFlash = (CheckBox) findViewById(R.id.cbFlash);
56 | cbFlash.setOnCheckedChangeListener(this);
57 |
58 | connectionManager = new ConnectionManager(this, ipAddress, password);
59 | connectionManager.start();
60 | connectionManager.setConnectionListener(this);
61 | connectionManager.setResponseListener(this);
62 | }
63 |
64 | @Override
65 | public void onStop() {
66 | super.onStop();
67 | connectionManager.stop();
68 | finish();
69 | }
70 |
71 | @Override
72 | public void onClick(View v) {
73 | int id = v.getId();
74 | if (id == R.id.btn_auto_focus) {
75 | requestAutoFocus();
76 | } else if (id == R.id.btn_take_photo) {
77 | requestTakePhoto();
78 | }
79 | }
80 |
81 | public void requestAutoFocus() {
82 | connectionManager.sendCommand(Command.FOCUS);
83 | }
84 |
85 | public void requestTakePhoto() {
86 | connectionManager.sendCommand(Command.SNAP);
87 | }
88 |
89 | @Override
90 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
91 | if (isChecked) {
92 | connectionManager.sendCommand(Command.LED_ON);
93 | } else {
94 | connectionManager.sendCommand(Command.LED_OFF);
95 | }
96 | }
97 |
98 | @Override
99 | public void onPictureTaken() {
100 | showToast(getString(R.string.photo_taken));
101 | }
102 |
103 | @Override
104 | public void onFlashUnavailable() {
105 | showToast(getString(R.string.unsupport_flash));
106 | }
107 |
108 | @Override
109 | public void onCameraImageIncoming(Bitmap bitmap) {
110 | ivCameraImage.setImageBitmap(bitmap);
111 | }
112 |
113 | @Override
114 | public void onConnectionDown() {
115 | showToast(getString(R.string.connection_down));
116 | finish();
117 | }
118 |
119 | @Override
120 | public void onConnectionFailed() {
121 | showToast(getString(R.string.connection_failed));
122 | finish();
123 | }
124 |
125 | @Override
126 | public void onWrongPassword() {
127 | showToast(getString(R.string.wrong_password));
128 | finish();
129 | }
130 |
131 | @Override
132 | public void onIOIOConnected() {
133 | showToast(getString(R.string.connection_accepted));
134 | }
135 |
136 | public void showToast(String message) {
137 | Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
138 | }
139 |
140 | @Override
141 | public void onJoyStickUp(int speed) {
142 | connectionManager.sendMovement(Command.FORWARD + speed);
143 | }
144 |
145 | @Override
146 | public void onJoyStickUpRight(int speed) {
147 | connectionManager.sendMovement(Command.FORWARD_RIGHT + speed);
148 | }
149 |
150 | @Override
151 | public void onJoyStickUpLeft(int speed) {
152 | connectionManager.sendMovement(Command.FORWARD_LEFT + speed);
153 | }
154 |
155 | @Override
156 | public void onJoyStickDown(int speed) {
157 | connectionManager.sendMovement(Command.BACKWARD + speed);
158 | }
159 |
160 | @Override
161 | public void onJoyStickDownRight(int speed) {
162 | connectionManager.sendMovement(Command.BACKWARD_RIGHT + speed);
163 | }
164 |
165 | @Override
166 | public void onJoyStickDownLeft(int speed) {
167 | connectionManager.sendMovement(Command.BACKWARD_LEFT + speed);
168 | }
169 |
170 | @Override
171 | public void onJoyStickRight(int speed) {
172 | connectionManager.sendMovement(Command.RIGHT + speed);
173 | }
174 |
175 | @Override
176 | public void onJoyStickLeft(int speed) {
177 | connectionManager.sendMovement(Command.LEFT + speed);
178 | }
179 |
180 | @Override
181 | public void onJoyStickNone() {
182 | connectionManager.sendMovement(Command.STOP);
183 | connectionManager.sendMovement(Command.STOP);
184 | }
185 | }
186 |
--------------------------------------------------------------------------------
/app/src/main/java/app/akexorcist/ioiocamerarobot/controller/ControllerSetupActivity.java:
--------------------------------------------------------------------------------
1 | package app.akexorcist.ioiocamerarobot.controller;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.content.SharedPreferences;
6 | import android.os.Bundle;
7 | import android.os.Handler;
8 | import android.view.View;
9 | import android.view.View.OnClickListener;
10 | import android.view.WindowManager;
11 | import android.widget.Button;
12 | import android.widget.EditText;
13 |
14 | import app.akexorcist.ioiocamerarobot.R;
15 | import app.akexorcist.ioiocamerarobot.constant.ExtraKey;
16 |
17 | public class ControllerSetupActivity extends Activity implements OnClickListener {
18 | private static final String DEFAULT_IP_ADDRESS = "192.168.1.1";
19 | private EditText etIpAddress;
20 | private EditText etPassword;
21 | private Button btnConnect;
22 |
23 | protected void onCreate(Bundle savedInstanceState) {
24 | super.onCreate(savedInstanceState);
25 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
26 | setContentView(R.layout.activity_controller_connection);
27 | SharedPreferences settings = getSharedPreferences(ExtraKey.SETUP_PREFERENCE, 0);
28 |
29 | etIpAddress = (EditText) findViewById(R.id.et_ip_address);
30 | etIpAddress.setText(settings.getString(ExtraKey.IP_ADDRESS, DEFAULT_IP_ADDRESS));
31 |
32 | etPassword = (EditText) findViewById(R.id.et_password);
33 | etPassword.setText(settings.getString(ExtraKey.TARGET_PASSWORD, ""));
34 |
35 | btnConnect = (Button) findViewById(R.id.btn_connect);
36 | btnConnect.setOnClickListener(this);
37 | }
38 |
39 | public void onPause() {
40 | super.onPause();
41 | saveConnectionConfiguration();
42 | }
43 |
44 | public void saveConnectionConfiguration() {
45 | SharedPreferences settings = getSharedPreferences(ExtraKey.SETUP_PREFERENCE, 0);
46 | SharedPreferences.Editor editor = settings.edit();
47 | editor.putString(ExtraKey.IP_ADDRESS, etIpAddress.getText().toString());
48 | editor.putString(ExtraKey.TARGET_PASSWORD, etPassword.getText().toString());
49 | editor.apply();
50 | }
51 |
52 | public void goToController() {
53 | Intent intent = new Intent(ControllerSetupActivity.this, ControllerActivity.class);
54 | intent.putExtra(ExtraKey.IP_ADDRESS, etIpAddress.getText().toString());
55 | intent.putExtra(ExtraKey.TARGET_PASSWORD, etPassword.getText().toString());
56 | startActivity(intent);
57 | }
58 |
59 | public void onResume() {
60 | super.onResume();
61 | delayedEnableButton();
62 | }
63 |
64 | public void delayedEnableButton() {
65 | btnConnect.setEnabled(false);
66 | new Handler().postDelayed(new Runnable() {
67 | @Override
68 | public void run() {
69 | btnConnect.setEnabled(true);
70 | }
71 | }, 1000);
72 | }
73 |
74 | @Override
75 | public void onClick(View v) {
76 | int id = v.getId();
77 | if (id == R.id.btn_connect) {
78 | goToController();
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/app/src/main/java/app/akexorcist/ioiocamerarobot/controller/JoyStickManager.java:
--------------------------------------------------------------------------------
1 | package app.akexorcist.ioiocamerarobot.controller;
2 |
3 | import android.content.Context;
4 | import android.view.MotionEvent;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 |
8 | import app.akexorcist.ioiocamerarobot.R;
9 | import app.akexorcist.ioiocamerarobot.utils.JoyStickView;
10 |
11 | /**
12 | * Created by Akexorcist on 9/5/15 AD.
13 | */
14 | public class JoyStickManager implements View.OnTouchListener {
15 | private static final int JOYSTICK_COOLDOWN = 200;
16 | private JoyStickEventListener listener;
17 | private JoyStickView joystick;
18 |
19 | private long time = System.currentTimeMillis();
20 |
21 | @SuppressWarnings("deprecation")
22 | public JoyStickManager(Context context, ViewGroup layoutJoyStick, int screenHeight) {
23 | setupJoyStick(context, layoutJoyStick, screenHeight);
24 | layoutJoyStick.setOnTouchListener(this);
25 | }
26 |
27 | public void setJoyStickEventListener(JoyStickEventListener listener) {
28 | this.listener = listener;
29 | }
30 |
31 | private void setupJoyStick(Context context, ViewGroup layoutJoyStick, int screenHeight) {
32 | joystick = new JoyStickView(context, layoutJoyStick, R.drawable.image_button);
33 | joystick.setStickSize(screenHeight / 7, screenHeight / 7);
34 | joystick.setLayoutSize(screenHeight / 2, screenHeight / 2);
35 | joystick.setLayoutAlpha(100);
36 | joystick.setStickAlpha(255);
37 | joystick.setOffset((int) ((screenHeight / 9) * 0.6));
38 | joystick.setMinimumDistance((int) ((screenHeight / 9) * 0.6));
39 | }
40 |
41 | @Override
42 | public boolean onTouch(View view, MotionEvent event) {
43 | joystick.drawStick(event);
44 | if (event.getAction() == MotionEvent.ACTION_DOWN) {
45 | getJoyStickDirection();
46 | } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
47 | long currentTimeMillis = System.currentTimeMillis();
48 | if (currentTimeMillis - time > JOYSTICK_COOLDOWN) {
49 | getJoyStickDirection();
50 | time = currentTimeMillis;
51 | }
52 | } else if (event.getAction() == MotionEvent.ACTION_UP) {
53 | if (listener != null)
54 | listener.onJoyStickNone();
55 | }
56 | return true;
57 | }
58 |
59 | public void getJoyStickDirection() {
60 | int direction = joystick.get8Direction();
61 | int speed = (int) (joystick.getDistance() / 1.875) + 20;
62 | speed = (speed > 100) ? 100 : speed;
63 | speed = (speed < 0) ? 0 : speed;
64 |
65 | if (listener != null) {
66 | if (direction == JoyStickView.STICK_UP) {
67 | listener.onJoyStickUp(speed);
68 | } else if (direction == JoyStickView.STICK_UPRIGHT) {
69 | listener.onJoyStickUpRight(speed);
70 | } else if (direction == JoyStickView.STICK_RIGHT) {
71 | listener.onJoyStickRight(speed);
72 | } else if (direction == JoyStickView.STICK_DOWNRIGHT) {
73 | listener.onJoyStickDownRight(speed);
74 | } else if (direction == JoyStickView.STICK_DOWN) {
75 | listener.onJoyStickDown(speed);
76 | } else if (direction == JoyStickView.STICK_DOWNLEFT) {
77 | listener.onJoyStickDownLeft(speed);
78 | } else if (direction == JoyStickView.STICK_LEFT) {
79 | listener.onJoyStickLeft(speed);
80 | } else if (direction == JoyStickView.STICK_UPLEFT) {
81 | listener.onJoyStickUpLeft(speed);
82 | } else if (direction == JoyStickView.STICK_NONE) {
83 | listener.onJoyStickNone();
84 | }
85 | }
86 | }
87 |
88 | public interface JoyStickEventListener {
89 | public void onJoyStickUp(int speed);
90 | public void onJoyStickUpRight(int speed);
91 | public void onJoyStickUpLeft(int speed);
92 | public void onJoyStickDown(int speed);
93 | public void onJoyStickDownRight(int speed);
94 | public void onJoyStickDownLeft(int speed);
95 | public void onJoyStickRight(int speed);
96 | public void onJoyStickLeft(int speed);
97 | public void onJoyStickNone();
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/app/src/main/java/app/akexorcist/ioiocamerarobot/ioio/CameraManager.java:
--------------------------------------------------------------------------------
1 | package app.akexorcist.ioiocamerarobot.ioio;
2 |
3 | import android.graphics.Bitmap;
4 | import android.hardware.Camera;
5 | import android.os.Environment;
6 | import android.view.SurfaceHolder;
7 | import android.view.SurfaceView;
8 |
9 | import java.io.File;
10 | import java.io.FileOutputStream;
11 | import java.io.IOException;
12 | import java.text.SimpleDateFormat;
13 | import java.util.Date;
14 | import java.util.List;
15 |
16 | /**
17 | * Created by Akexorcist on 9/5/15 AD.
18 | */
19 | public class CameraManager implements Camera.PictureCallback, Camera.PreviewCallback {
20 |
21 | private CameraManagerListener listener;
22 | private Camera mCamera;
23 | private Camera.Parameters params;
24 | private Camera.Size pictureSize;
25 | private Camera.Size previewSize;
26 |
27 | private int selectedPreviewSize;
28 | int w, h;
29 | int[] rgbs;
30 | boolean initialed = false;
31 |
32 | public CameraManager(int selectedPreviewSize) {
33 | this.selectedPreviewSize = selectedPreviewSize;
34 | }
35 |
36 | public void setCameraManagerListener(CameraManagerListener listener) {
37 | this.listener = listener;
38 | }
39 |
40 | @Override
41 | public void onPictureTaken(byte[] data, Camera camera) {
42 | int imageNum = 0;
43 | File imagesFolder = new File(Environment.getExternalStorageDirectory(), "DCIM/IOIOCameraRobot");
44 | imagesFolder.mkdirs();
45 |
46 | SimpleDateFormat sd = new SimpleDateFormat("yyyyMMdd-hhmmss");
47 | String date = sd.format(new Date());
48 |
49 | String fileName = "IMG_" + date + ".jpg";
50 | File output = new File(imagesFolder, fileName);
51 | while (output.exists()) {
52 | imageNum++;
53 | fileName = "IMG_" + date + "_" + String.valueOf(imageNum) + ".jpg";
54 | output = new File(imagesFolder, fileName);
55 | }
56 |
57 | try {
58 | FileOutputStream fos = new FileOutputStream(output);
59 | fos.write(data);
60 | fos.close();
61 | } catch (IOException e) {
62 | e.printStackTrace();
63 | }
64 |
65 | mCamera.stopPreview();
66 | mCamera.setPreviewCallback(this);
67 | mCamera.startPreview();
68 | if (listener != null)
69 | listener.onPictureTaken(fileName, imagesFolder.getAbsolutePath());
70 | }
71 |
72 | public void setCameraOrientation(int orientation) {
73 | switch (orientation) {
74 | case OrientationManager.LANDSCAPE_NORMAL:
75 | mCamera.setDisplayOrientation(0);
76 | break;
77 | case OrientationManager.PORTRAIT_NORMAL:
78 | mCamera.setDisplayOrientation(90);
79 | break;
80 | case OrientationManager.LANDSCAPE_REVERSE:
81 | mCamera.setDisplayOrientation(180);
82 | break;
83 | case OrientationManager.PORTRAIT_REVERSE:
84 | mCamera.setDisplayOrientation(270);
85 | break;
86 | }
87 | }
88 |
89 | @Override
90 | public void onPreviewFrame(byte[] data, Camera camera) {
91 | if (!initialed) {
92 | w = mCamera.getParameters().getPreviewSize().width;
93 | h = mCamera.getParameters().getPreviewSize().height;
94 | rgbs = new int[w * h];
95 | initialed = true;
96 | }
97 |
98 | if (data != null && listener != null) {
99 | try {
100 | decodeYUV420(rgbs, data, w, h);
101 | listener.onPreviewTaken(Bitmap.createBitmap(rgbs, w, h, Bitmap.Config.ARGB_8888));
102 | } catch (OutOfMemoryError e) {
103 | listener.onPreviewOutOfMemory(e);
104 | }
105 | }
106 | }
107 |
108 | public void startCameraPreview(SurfaceView surfaceView) {
109 | try {
110 | mCamera.setPreviewDisplay(surfaceView.getHolder());
111 | mCamera.startPreview();
112 | } catch (Exception e) {
113 | e.printStackTrace();
114 | }
115 | }
116 |
117 | public void stopCameraPreview() {
118 | try {
119 | mCamera.stopPreview();
120 | } catch (Exception e) {
121 | e.printStackTrace();
122 | }
123 | }
124 |
125 | public void initCameraParameter() {
126 | params = mCamera.getParameters();
127 | pictureSize = getMaxPictureSize(params);
128 | previewSize = params.getSupportedPreviewSizes().get(selectedPreviewSize);
129 |
130 | params.setPictureSize(pictureSize.width, pictureSize.height);
131 | params.setPreviewSize(previewSize.width, previewSize.height);
132 | params.setPreviewFrameRate(getMaxPreviewFps(params));
133 |
134 | params.setJpegQuality(100);
135 | mCamera.setParameters(params);
136 | mCamera.setPreviewCallback(this);
137 | }
138 |
139 | public Camera.Size getPreviewSize() {
140 | return previewSize;
141 | }
142 |
143 | public Camera.Size getPictureSize() {
144 | return pictureSize;
145 | }
146 |
147 | public Camera.Size getMaxPictureSize(Camera.Parameters params) {
148 | List pictureSize = params.getSupportedPictureSizes();
149 | int firstPictureWidth, lastPictureWidth;
150 | try {
151 | firstPictureWidth = pictureSize.get(0).width;
152 | lastPictureWidth = pictureSize.get(pictureSize.size() - 1).width;
153 | if (firstPictureWidth > lastPictureWidth)
154 | return pictureSize.get(0);
155 | else
156 | return pictureSize.get(pictureSize.size() - 1);
157 | } catch (ArrayIndexOutOfBoundsException e) {
158 | e.printStackTrace();
159 | return pictureSize.get(0);
160 | }
161 | }
162 |
163 | public int getMaxPreviewFps(Camera.Parameters params) {
164 | List previewFps = params.getSupportedPreviewFrameRates();
165 | int fps = 0;
166 | for (int i = 0; i < previewFps.size(); i++) {
167 | if (previewFps.get(i) > fps)
168 | fps = previewFps.get(i);
169 | }
170 | return fps;
171 | }
172 |
173 | public void createCameraInstance(SurfaceHolder holder) {
174 | try {
175 | mCamera = Camera.open(0);
176 | mCamera.setPreviewDisplay(holder);
177 | mCamera.startPreview();
178 | } catch (IOException e) {
179 | e.printStackTrace();
180 | }
181 | }
182 |
183 | public void destroyCameraInstance() {
184 | mCamera.setPreviewCallback(null);
185 | mCamera.stopPreview();
186 | mCamera.release();
187 | mCamera = null;
188 | }
189 |
190 | public interface CameraManagerListener {
191 | public void onPictureTaken(String filename, String path);
192 | public void onPreviewTaken(Bitmap bitmap);
193 | public void onPreviewOutOfMemory(OutOfMemoryError e);
194 | }
195 |
196 | public void requestAutoFocus() {
197 | if (mCamera != null)
198 | mCamera.autoFocus(null);
199 | }
200 |
201 | public boolean requestTakePicture() {
202 | if (mCamera != null) {
203 | mCamera.takePicture(null, null, null, this);
204 | return true;
205 | }
206 | return false;
207 | }
208 |
209 | public boolean isFlashAvailable() {
210 | return params.getSupportedFlashModes() != null;
211 | }
212 |
213 | public boolean requestFlashOn() {
214 | if (params.getSupportedFlashModes() != null) {
215 | params.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
216 | mCamera.setParameters(params);
217 | return true;
218 | }
219 | return false;
220 | }
221 |
222 | public boolean requestFlashOff() {
223 | if (params.getSupportedFlashModes() != null) {
224 | params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
225 | mCamera.setParameters(params);
226 | return true;
227 | }
228 | return false;
229 | }
230 |
231 | private void decodeYUV420(int[] rgb, byte[] yuv420, int width, int height) {
232 | final int frameSize = width * height;
233 |
234 | for (int j = 0, yp = 0; j < height; j++) {
235 | int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
236 | for (int i = 0; i < width; i++, yp++) {
237 | int y = (0xff & ((int) yuv420[yp])) - 16;
238 | if (y < 0) y = 0;
239 | if ((i & 1) == 0) {
240 | v = (0xff & yuv420[uvp++]) - 128;
241 | u = (0xff & yuv420[uvp++]) - 128;
242 | }
243 |
244 | int y1192 = 1192 * y;
245 | int r = (y1192 + 1634 * v);
246 | int g = (y1192 - 833 * v - 400 * u);
247 | int b = (y1192 + 2066 * u);
248 |
249 | if (r < 0) r = 0;
250 | else if (r > 262143) r = 262143;
251 | if (g < 0) g = 0;
252 | else if (g > 262143) g = 262143;
253 | if (b < 0) b = 0;
254 | else if (b > 262143) b = 262143;
255 |
256 | rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
257 | }
258 | }
259 | }
260 | }
261 |
--------------------------------------------------------------------------------
/app/src/main/java/app/akexorcist/ioiocamerarobot/ioio/ConnectionManager.java:
--------------------------------------------------------------------------------
1 | package app.akexorcist.ioiocamerarobot.ioio;
2 |
3 | import android.os.Handler;
4 | import android.os.Message;
5 |
6 | import java.io.DataOutputStream;
7 | import java.io.IOException;
8 | import java.io.OutputStream;
9 | import java.net.Socket;
10 |
11 | import app.akexorcist.ioiocamerarobot.constant.Command;
12 |
13 | /**
14 | * Created by Akexorcist on 9/5/15 AD.
15 | */
16 | public class ConnectionManager {
17 | private ConnectionListener connectionListener;
18 | private ControllerCommandListener commandListener;
19 | private SendCommandListener sendListener;
20 | private OutputStream out;
21 | private DataOutputStream dos;
22 | private IOIOService ioio;
23 | private String password;
24 |
25 |
26 | public ConnectionManager(String password) {
27 | this.password = password;
28 | }
29 |
30 | public void setConnectionListener(ConnectionListener listener) {
31 | connectionListener = listener;
32 | }
33 |
34 | public void setCommandListener(ControllerCommandListener listener) {
35 | commandListener = listener;
36 | }
37 |
38 | public void setSendCommandListener(SendCommandListener sendListener) {
39 | this.sendListener = sendListener;
40 | }
41 |
42 | public void start() {
43 | ioio = new IOIOService(mHandler, password);
44 | ioio.execute();
45 | }
46 |
47 | Handler mHandler = new Handler() {
48 | public void handleMessage(Message msg) {
49 | onDataIncoming();
50 | int messageType = msg.what;
51 | if (messageType == Command.MESSAGE_PASS) {
52 | onControllerConnected((Socket) msg.obj);
53 | } else if (messageType == Command.MESSAGE_WRONG) {
54 | onControllerPasswordWrong((Socket) msg.obj);
55 | } else if (messageType == Command.MESSAGE_DISCONNECTED) {
56 | onControllerDisconnected();
57 | } else if (messageType == Command.MESSAGE_CLOSE) {
58 | onControllerClosed();
59 | } else if (messageType == Command.MESSAGE_FLASH) {
60 | onFlashCommand(msg.obj.toString());
61 | } else if (messageType == Command.MESSAGE_SNAP) {
62 | onRequestTakePicture();
63 | } else if (messageType == Command.MESSAGE_FOCUS) {
64 | onRequestAutoFocus();
65 | } else if (messageType == Command.MESSAGE_UP) {
66 | onMoveForwardCommand((Integer) msg.obj);
67 | } else if (messageType == Command.MESSAGE_UPRIGHT) {
68 | onMoveForwardRightCommand((Integer) msg.obj);
69 | } else if (messageType == Command.MESSAGE_UPLEFT) {
70 | onMoveForwardLeftCommand((Integer) msg.obj);
71 | } else if (messageType == Command.MESSAGE_DOWN) {
72 | onMoveBackwardCommand((Integer) msg.obj);
73 | } else if (messageType == Command.MESSAGE_DOWNRIGHT) {
74 | onMoveBackwardRightCommand((Integer) msg.obj);
75 | } else if (messageType == Command.MESSAGE_DOWNLEFT) {
76 | onMoveBackwardLeftCommand((Integer) msg.obj);
77 | } else if (messageType == Command.MESSAGE_RIGHT) {
78 | onMoveRightCommand((Integer) msg.obj);
79 | } else if (messageType == Command.MESSAGE_LEFT) {
80 | onMoveLeftCommand((Integer) msg.obj);
81 | } else if (messageType == Command.MESSAGE_STOP) {
82 | onMoveStopCommand();
83 | }
84 | }
85 | };
86 |
87 | public void onDataIncoming() {
88 | if(connectionListener != null)
89 | connectionListener.onDataIncoming();
90 | }
91 |
92 | public void onControllerConnected(Socket socket) {
93 | try {
94 | out = socket.getOutputStream();
95 | dos = new DataOutputStream(out);
96 | if(connectionListener != null)
97 | connectionListener.onControllerConnected();
98 | } catch (IOException e) {
99 | e.printStackTrace();
100 | }
101 | }
102 |
103 | public void onControllerPasswordWrong(Socket socket) {
104 | try {
105 | out = socket.getOutputStream();
106 | dos = new DataOutputStream(out);
107 | restart();
108 | if(connectionListener != null)
109 | connectionListener.onWrongPassword();
110 | } catch (IOException e) {
111 | e.printStackTrace();
112 | }
113 | }
114 |
115 | public void onControllerDisconnected() {
116 | restart();
117 | if(connectionListener != null)
118 | connectionListener.onControllerDisconnected();
119 | }
120 |
121 | public void onControllerClosed() {
122 | restart();
123 | if(connectionListener != null)
124 | connectionListener.onControllerClosed();
125 | }
126 |
127 | public void onFlashCommand(String command) {
128 | if(commandListener != null)
129 | commandListener.onFlashCommand(command);
130 | }
131 |
132 | public void onRequestTakePicture() {
133 | if(commandListener != null)
134 | commandListener.onRequestTakePicture();
135 | }
136 |
137 | public void onRequestAutoFocus() {
138 | if(commandListener != null)
139 | commandListener.onRequestAutoFocus();
140 | }
141 |
142 | public void onMoveForwardCommand(int speed) {
143 | if(commandListener != null)
144 | commandListener.onMoveForwardCommand(speed);
145 | }
146 |
147 | public void onMoveForwardRightCommand(int speed) {
148 | if(commandListener != null)
149 | commandListener.onMoveForwardRightCommand(speed);
150 | }
151 |
152 | public void onMoveForwardLeftCommand(int speed) {
153 | if(commandListener != null)
154 | commandListener.onMoveForwardLeftCommand(speed);
155 | }
156 |
157 | public void onMoveBackwardCommand(int speed) {
158 | if(commandListener != null)
159 | commandListener.onMoveBackwardCommand(speed);
160 | }
161 |
162 | public void onMoveBackwardRightCommand(int speed) {
163 | if(commandListener != null)
164 | commandListener.onMoveBackwardRightCommand(speed);
165 | }
166 |
167 | public void onMoveBackwardLeftCommand(int speed) {
168 | if(commandListener != null)
169 | commandListener.onMoveBackwardLeftCommand(speed);
170 | }
171 |
172 | public void onMoveRightCommand(int speed) {
173 | if(commandListener != null)
174 | commandListener.onMoveRightCommand(speed);
175 | }
176 |
177 | public void onMoveLeftCommand(int speed) {
178 | if(commandListener != null)
179 | commandListener.onMoveLeftCommand(speed);
180 | }
181 |
182 | public void onMoveStopCommand() {
183 | if(commandListener != null)
184 | commandListener.onMoveStopCommand();
185 | }
186 |
187 | public void stop() {
188 | if (ioio != null)
189 | ioio.killTask();
190 | }
191 |
192 | public void restart() {
193 | stop();
194 | new Handler().postDelayed(new Runnable() {
195 | public void run() {
196 | start();
197 | }
198 | }, 1000);
199 | }
200 |
201 | public void sendImageData(byte[] data) {
202 | try {
203 | dos.writeInt(data.length);
204 | dos.write(data);
205 | out.flush();
206 | if(sendListener != null)
207 | sendListener.onSendCommandSuccess();
208 | } catch (IOException e) {
209 | e.printStackTrace();
210 | if(sendListener != null)
211 | sendListener.onSendCommandFailure();
212 | } catch (NullPointerException e) {
213 | e.printStackTrace();
214 | }
215 | }
216 |
217 | public void sendCommand(String str) {
218 | try {
219 | dos.writeInt(str.length());
220 | dos.write(str.getBytes());
221 | out.flush();
222 | if(sendListener != null)
223 | sendListener.onSendCommandSuccess();
224 | } catch (IOException e) {
225 | e.printStackTrace();
226 | if(sendListener != null)
227 | sendListener.onSendCommandFailure();
228 | } catch (NullPointerException e) {
229 | e.printStackTrace();
230 | }
231 | }
232 |
233 | public interface ConnectionListener {
234 | public void onControllerConnected();
235 | public void onWrongPassword();
236 | public void onControllerDisconnected();
237 | public void onControllerClosed();
238 | public void onDataIncoming();
239 | }
240 |
241 | public interface ControllerCommandListener {
242 | public void onFlashCommand(String command);
243 | public void onRequestTakePicture();
244 | public void onRequestAutoFocus();
245 | public void onMoveForwardCommand(int speed);
246 | public void onMoveForwardRightCommand(int speed);
247 | public void onMoveForwardLeftCommand(int speed);
248 | public void onMoveBackwardCommand(int speed);
249 | public void onMoveBackwardRightCommand(int speed);
250 | public void onMoveBackwardLeftCommand(int speed);
251 | public void onMoveLeftCommand(int speed);
252 | public void onMoveRightCommand(int speed);
253 | public void onMoveStopCommand();
254 | }
255 |
256 | public interface SendCommandListener {
257 | public void onSendCommandSuccess();
258 | public void onSendCommandFailure();
259 | }
260 | }
261 |
--------------------------------------------------------------------------------
/app/src/main/java/app/akexorcist/ioiocamerarobot/ioio/IOIOControllerActivity.java:
--------------------------------------------------------------------------------
1 | package app.akexorcist.ioiocamerarobot.ioio;
2 |
3 | import app.akexorcist.ioiocamerarobot.utils.Utilities;
4 | import app.akexorcist.ioiocamerarobot.constant.Command;
5 | import app.akexorcist.ioiocamerarobot.constant.DirectionState;
6 | import app.akexorcist.ioiocamerarobot.constant.ExtraKey;
7 | import app.akexorcist.ioiocamerarobot.R;
8 | import ioio.lib.api.DigitalOutput;
9 | import ioio.lib.api.PwmOutput;
10 | import ioio.lib.api.exception.ConnectionLostException;
11 | import ioio.lib.util.BaseIOIOLooper;
12 | import ioio.lib.util.IOIOLooper;
13 | import ioio.lib.util.android.IOIOActivity;
14 |
15 | import java.io.ByteArrayOutputStream;
16 |
17 | import android.graphics.Bitmap;
18 | import android.os.Bundle;
19 | import android.view.SurfaceHolder;
20 | import android.view.SurfaceHolder.Callback;
21 | import android.view.View.OnClickListener;
22 | import android.view.ViewGroup.LayoutParams;
23 | import android.view.Display;
24 | import android.view.SurfaceView;
25 | import android.view.View;
26 | import android.view.WindowManager;
27 | import android.widget.Button;
28 | import android.widget.RelativeLayout;
29 | import android.widget.TextView;
30 | import android.widget.Toast;
31 |
32 |
33 | public class IOIOControllerActivity extends IOIOActivity implements CameraManager.CameraManagerListener, Callback, ConnectionManager.ConnectionListener, ConnectionManager.ControllerCommandListener, ConnectionManager.SendCommandListener {
34 | private static final int TAKE_PICTURE_COOLDOWN = 1000;
35 | private RelativeLayout layoutParent;
36 | private TextView tvMovementSpeed;
37 | private TextView tvIpAddress;
38 | private Button btnMoveForward;
39 | private Button btnMoveForwardLeft;
40 | private Button btnMoveForwardRight;
41 | private Button btnMoveDown;
42 | private Button btnMoveDownLeft;
43 | private Button btnMoveDownRight;
44 | private Button btnMoveRight;
45 | private Button btnMoveLeft;
46 | private SurfaceView surfacePreview;
47 |
48 | private int movementSpeed = 0;
49 | private int lastPictureTakenTime = 0;
50 | private int directionState = DirectionState.STOP;
51 |
52 | private ConnectionManager connectionManager;
53 | private CameraManager cameraManager;
54 | private OrientationManager orientationManager;
55 |
56 | private int imageQuality;
57 | private boolean isConnected = false;
58 |
59 | @SuppressWarnings("deprecation")
60 | protected void onCreate(Bundle savedInstanceState) {
61 | super.onCreate(savedInstanceState);
62 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
63 | setContentView(R.layout.activity_ioio);
64 |
65 | String password = getIntent().getExtras().getString(ExtraKey.OWN_PASSWORD);
66 | int selectedPreviewSize = getIntent().getExtras().getInt(ExtraKey.PREVIEW_SIZE);
67 | imageQuality = getIntent().getExtras().getInt(ExtraKey.QUALITY);
68 |
69 | btnMoveForward = (Button) findViewById(R.id.btn_move_forward);
70 | btnMoveForwardLeft = (Button) findViewById(R.id.btn_move_forward_left);
71 | btnMoveForwardRight = (Button) findViewById(R.id.btn_move_forward_right);
72 | btnMoveDown = (Button) findViewById(R.id.btn_move_backward);
73 | btnMoveDownLeft = (Button) findViewById(R.id.btn_move_backward_left);
74 | btnMoveDownRight = (Button) findViewById(R.id.btn_move_backward_right);
75 | btnMoveRight = (Button) findViewById(R.id.btn_move_right);
76 | btnMoveLeft = (Button) findViewById(R.id.btn_move_left);
77 |
78 | tvMovementSpeed = (TextView) findViewById(R.id.tv_movement_speed);
79 |
80 | tvIpAddress = (TextView) findViewById(R.id.tv_ip_address);
81 | tvIpAddress.setText(Utilities.getCurrentIP(this));
82 |
83 | surfacePreview = (SurfaceView) findViewById(R.id.surface_preview);
84 | surfacePreview.getHolder().addCallback(this);
85 | surfacePreview.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
86 |
87 |
88 | layoutParent = (RelativeLayout) findViewById(R.id.layout_parent);
89 | layoutParent.setOnClickListener(new OnClickListener() {
90 | public void onClick(View v) {
91 | cameraManager.requestAutoFocus();
92 | }
93 | });
94 | connectionManager = new ConnectionManager(password);
95 | connectionManager.start();
96 | connectionManager.setConnectionListener(this);
97 | connectionManager.setCommandListener(this);
98 | connectionManager.setSendCommandListener(this);
99 |
100 | orientationManager = new OrientationManager(this);
101 | cameraManager = new CameraManager(selectedPreviewSize);
102 | cameraManager.setCameraManagerListener(this);
103 | }
104 |
105 | public void onStop() {
106 | super.onStop();
107 | connectionManager.stop();
108 | finish();
109 | }
110 |
111 | public void clearCheckBox() {
112 | btnMoveForward.setPressed(false);
113 | btnMoveForwardLeft.setPressed(false);
114 | btnMoveForwardRight.setPressed(false);
115 | btnMoveDown.setPressed(false);
116 | btnMoveDownLeft.setPressed(false);
117 | btnMoveDownRight.setPressed(false);
118 | btnMoveRight.setPressed(false);
119 | btnMoveLeft.setPressed(false);
120 | }
121 |
122 | public void updateMovementSpeed(int speed) {
123 | movementSpeed = speed;
124 | tvMovementSpeed.setText(getString(R.string.movement_speed, speed));
125 | }
126 |
127 | @Override
128 | public void onDataIncoming() {
129 | clearCheckBox();
130 | }
131 |
132 | @Override
133 | public void onControllerConnected() {
134 | isConnected = true;
135 | connectionManager.sendCommand(Command.ACCEPT_CONNECTION);
136 | }
137 |
138 | @Override
139 | public void onWrongPassword() {
140 | connectionManager.sendCommand(Command.WRONG_PASSWORD);
141 | connectionManager.restart();
142 | }
143 |
144 | @Override
145 | public void onControllerDisconnected() {
146 | showToast(getString(R.string.connection_down));
147 | }
148 |
149 | @Override
150 | public void onControllerClosed() {
151 | isConnected = false;
152 | }
153 |
154 | @Override
155 | public void onFlashCommand(String command) {
156 | if (cameraManager.isFlashAvailable()) {
157 | if (command.equals(Command.LED_ON)) {
158 | cameraManager.requestFlashOn();
159 | } else if (command.equals(Command.LED_OFF)) {
160 | cameraManager.requestFlashOff();
161 | }
162 | } else {
163 | connectionManager.sendCommand(Command.FLASH_UNAVAILABLE);
164 | }
165 | }
166 |
167 | @Override
168 | public void onRequestTakePicture() {
169 | double currentTimeSeconds = System.currentTimeMillis();
170 | if (currentTimeSeconds - lastPictureTakenTime > TAKE_PICTURE_COOLDOWN) {
171 | lastPictureTakenTime = (int) currentTimeSeconds;
172 | cameraManager.requestTakePicture();
173 | }
174 | }
175 |
176 | @Override
177 | public void onRequestAutoFocus() {
178 | cameraManager.requestAutoFocus();
179 | }
180 |
181 | @Override
182 | public void onMoveForwardCommand(int movementSpeed) {
183 | btnMoveForward.setPressed(true);
184 | directionState = DirectionState.UP;
185 | updateMovementSpeed(movementSpeed);
186 | }
187 |
188 | @Override
189 | public void onMoveForwardRightCommand(int movementSpeed) {
190 | btnMoveForwardRight.setPressed(true);
191 | directionState = DirectionState.UPRIGHT;
192 | updateMovementSpeed(movementSpeed);
193 | }
194 |
195 | @Override
196 | public void onMoveForwardLeftCommand(int movementSpeed) {
197 | btnMoveForwardLeft.setPressed(true);
198 | directionState = DirectionState.UPLEFT;
199 | updateMovementSpeed(movementSpeed);
200 | }
201 |
202 | @Override
203 | public void onMoveBackwardCommand(int movementSpeed) {
204 | btnMoveDown.setPressed(true);
205 | directionState = DirectionState.DOWN;
206 | updateMovementSpeed(movementSpeed);
207 | }
208 |
209 | @Override
210 | public void onMoveBackwardRightCommand(int movementSpeed) {
211 | btnMoveDownRight.setPressed(true);
212 | directionState = DirectionState.DOWNRIGHT;
213 | updateMovementSpeed(movementSpeed);
214 | }
215 |
216 | @Override
217 | public void onMoveBackwardLeftCommand(int movementSpeed) {
218 | btnMoveDownLeft.setPressed(true);
219 | directionState = DirectionState.DOWNLEFT;
220 | updateMovementSpeed(movementSpeed);
221 | }
222 |
223 | @Override
224 | public void onMoveLeftCommand(int movementSpeed) {
225 | btnMoveLeft.setPressed(true);
226 | directionState = DirectionState.LEFT;
227 | updateMovementSpeed(movementSpeed);
228 | }
229 |
230 | @Override
231 | public void onMoveRightCommand(int movementSpeed) {
232 | btnMoveRight.setPressed(true);
233 | directionState = DirectionState.RIGHT;
234 | updateMovementSpeed(movementSpeed);
235 | }
236 |
237 | @Override
238 | public void onMoveStopCommand() {
239 | directionState = DirectionState.STOP;
240 | updateMovementSpeed(0);
241 | }
242 |
243 | @Override
244 | public void onSendCommandSuccess() {
245 | }
246 |
247 | @Override
248 | public void onSendCommandFailure() {
249 | isConnected = false;
250 | }
251 |
252 | @SuppressWarnings("deprecation")
253 | public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
254 | if (surfacePreview == null)
255 | return;
256 |
257 | cameraManager.stopCameraPreview();
258 | cameraManager.initCameraParameter();
259 |
260 | setupPreviewLayout();
261 |
262 | cameraManager.setCameraOrientation(orientationManager.getOrientation());
263 | cameraManager.startCameraPreview(surfacePreview);
264 | }
265 |
266 | @SuppressWarnings("deprecation")
267 | public void setupPreviewLayout() {
268 | Display display = getWindowManager().getDefaultDisplay();
269 | LayoutParams lp = layoutParent.getLayoutParams();
270 |
271 | float previewWidth = cameraManager.getPreviewSize().width;
272 | float previewHeight = cameraManager.getPreviewSize().height;
273 |
274 | int orientation = orientationManager.getOrientation();
275 | float ratio = 0;
276 | if (orientation == OrientationManager.LANDSCAPE_NORMAL
277 | || orientation == OrientationManager.LANDSCAPE_REVERSE) {
278 | ratio = previewWidth / previewHeight;
279 | } else if (orientation == OrientationManager.PORTRAIT_NORMAL
280 | || orientation == OrientationManager.PORTRAIT_REVERSE) {
281 | ratio = previewHeight / previewWidth;
282 | }
283 | if ((int) ((float) surfacePreview.getWidth() / ratio) >= display.getHeight()) {
284 | lp.height = (int) ((float) surfacePreview.getWidth() / ratio);
285 | lp.width = surfacePreview.getWidth();
286 | } else {
287 | lp.height = surfacePreview.getHeight();
288 | lp.width = (int) ((float) surfacePreview.getHeight() * ratio);
289 | }
290 |
291 | layoutParent.setLayoutParams(lp);
292 | int locationX = (int) (lp.width / 2.0 - surfacePreview.getWidth() / 2.0);
293 | layoutParent.animate().translationX(-locationX);
294 | }
295 |
296 | public void surfaceCreated(SurfaceHolder holder) {
297 | cameraManager.createCameraInstance(holder);
298 | }
299 |
300 | public void surfaceDestroyed(SurfaceHolder holder) {
301 | cameraManager.destroyCameraInstance();
302 | }
303 |
304 | @Override
305 | public void onPictureTaken(String filename, String path) {
306 | connectionManager.sendCommand(Command.SNAP);
307 | }
308 |
309 | @Override
310 | public void onPreviewTaken(Bitmap bitmap) {
311 | if (isConnected) {
312 | ByteArrayOutputStream bos = new ByteArrayOutputStream();
313 | bitmap.compress(Bitmap.CompressFormat.JPEG, imageQuality, bos);
314 | connectionManager.sendImageData(bos.toByteArray());
315 | }
316 | }
317 |
318 | @Override
319 | public void onPreviewOutOfMemory(OutOfMemoryError e) {
320 | e.printStackTrace();
321 | showToast(getString(R.string.out_of_memory));
322 | finish();
323 | }
324 |
325 | public void showToast(String message) {
326 | Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
327 | }
328 |
329 | class Looper extends BaseIOIOLooper {
330 | DigitalOutput D1A, D1B, D2A, D2B, D3A, D3B, D4A, D4B;
331 | PwmOutput PWM1, PWM2, PWM3, PWM4;
332 |
333 | protected void setup() throws ConnectionLostException {
334 | ioio_.openDigitalOutput(0, false);
335 | D1A = ioio_.openDigitalOutput(1, false);
336 | D1B = ioio_.openDigitalOutput(2, false);
337 | D2A = ioio_.openDigitalOutput(4, false);
338 | D2B = ioio_.openDigitalOutput(5, false);
339 | D3A = ioio_.openDigitalOutput(16, false);
340 | D3B = ioio_.openDigitalOutput(17, false);
341 | D4A = ioio_.openDigitalOutput(18, false);
342 | D4B = ioio_.openDigitalOutput(19, false);
343 | PWM1 = ioio_.openPwmOutput(3, 100);
344 | PWM1.setDutyCycle(0);
345 | PWM2 = ioio_.openPwmOutput(6, 100);
346 | PWM2.setDutyCycle(0);
347 | PWM3 = ioio_.openPwmOutput(13, 100);
348 | PWM3.setDutyCycle(0);
349 | PWM4 = ioio_.openPwmOutput(14, 100);
350 | PWM4.setDutyCycle(0);
351 |
352 | showToastFromIOIO(getString(R.string.connected));
353 | }
354 |
355 | public void loop() throws ConnectionLostException, InterruptedException {
356 | if (directionState == DirectionState.UP) {
357 | PWM1.setDutyCycle((float) movementSpeed / 100);
358 | PWM2.setDutyCycle((float) movementSpeed / 100);
359 | PWM3.setDutyCycle((float) movementSpeed / 100);
360 | PWM4.setDutyCycle((float) movementSpeed / 100);
361 | D1A.write(true);
362 | D1B.write(false);
363 | D2A.write(true);
364 | D2B.write(false);
365 | D3A.write(true);
366 | D3B.write(false);
367 | D4A.write(true);
368 | D4B.write(false);
369 | } else if (directionState == DirectionState.DOWN) {
370 | PWM1.setDutyCycle((float) movementSpeed / 100);
371 | PWM2.setDutyCycle((float) movementSpeed / 100);
372 | PWM3.setDutyCycle((float) movementSpeed / 100);
373 | PWM4.setDutyCycle((float) movementSpeed / 100);
374 | D1A.write(false);
375 | D1B.write(true);
376 | D2A.write(false);
377 | D2B.write(true);
378 | D3A.write(false);
379 | D3B.write(true);
380 | D4A.write(false);
381 | D4B.write(true);
382 | } else if (directionState == DirectionState.LEFT) {
383 | PWM1.setDutyCycle((float) movementSpeed / 100);
384 | PWM2.setDutyCycle((float) movementSpeed / 100);
385 | PWM3.setDutyCycle((float) movementSpeed / 100);
386 | PWM4.setDutyCycle((float) movementSpeed / 100);
387 | D1A.write(false);
388 | D1B.write(true);
389 | D2A.write(false);
390 | D2B.write(true);
391 | D3A.write(true);
392 | D3B.write(false);
393 | D4A.write(true);
394 | D4B.write(false);
395 | } else if (directionState == DirectionState.RIGHT) {
396 | PWM1.setDutyCycle((float) movementSpeed / 100);
397 | PWM2.setDutyCycle((float) movementSpeed / 100);
398 | PWM3.setDutyCycle((float) movementSpeed / 100);
399 | PWM4.setDutyCycle((float) movementSpeed / 100);
400 | D1A.write(true);
401 | D1B.write(false);
402 | D2A.write(true);
403 | D2B.write(false);
404 | D3A.write(false);
405 | D3B.write(true);
406 | D4A.write(false);
407 | D4B.write(true);
408 | } else if (directionState == DirectionState.UPRIGHT) {
409 | PWM1.setDutyCycle((((float) movementSpeed / (float) 1.5) + 20) / 100);
410 | PWM2.setDutyCycle((((float) movementSpeed / (float) 1.5) + 20) / 100);
411 | PWM3.setDutyCycle((((float) movementSpeed / (float) 1.5) - 20) / 100);
412 | PWM4.setDutyCycle((((float) movementSpeed / (float) 1.5) - 20) / 100);
413 | D1A.write(true);
414 | D1B.write(false);
415 | D2A.write(true);
416 | D2B.write(false);
417 | D3A.write(true);
418 | D3B.write(false);
419 | D4A.write(true);
420 | D4B.write(false);
421 | } else if (directionState == DirectionState.UPLEFT) {
422 | PWM1.setDutyCycle((((float) movementSpeed / (float) 1.5) - 20) / 100);
423 | PWM2.setDutyCycle((((float) movementSpeed / (float) 1.5) - 20) / 100);
424 | PWM3.setDutyCycle((((float) movementSpeed / (float) 1.5) + 20) / 100);
425 | PWM4.setDutyCycle((((float) movementSpeed / (float) 1.5) + 20) / 100);
426 | D1A.write(true);
427 | D1B.write(false);
428 | D2A.write(true);
429 | D2B.write(false);
430 | D3A.write(true);
431 | D3B.write(false);
432 | D4A.write(true);
433 | D4B.write(false);
434 | } else if (directionState == DirectionState.DOWNRIGHT) {
435 | PWM1.setDutyCycle((((float) movementSpeed / (float) 1.5) + 20) / 100);
436 | PWM2.setDutyCycle((((float) movementSpeed / (float) 1.5) + 20) / 100);
437 | PWM3.setDutyCycle((((float) movementSpeed / (float) 1.5) - 20) / 100);
438 | PWM4.setDutyCycle((((float) movementSpeed / (float) 1.5) - 20) / 100);
439 | D1A.write(false);
440 | D1B.write(true);
441 | D2A.write(false);
442 | D2B.write(true);
443 | D3A.write(false);
444 | D3B.write(true);
445 | D4A.write(false);
446 | D4B.write(true);
447 | } else if (directionState == DirectionState.DOWNLEFT) {
448 | PWM1.setDutyCycle((((float) movementSpeed / (float) 1.5) - 20) / 100);
449 | PWM2.setDutyCycle((((float) movementSpeed / (float) 1.5) - 20) / 100);
450 | PWM3.setDutyCycle((((float) movementSpeed / (float) 1.5) + 20) / 100);
451 | PWM4.setDutyCycle((((float) movementSpeed / (float) 1.5) + 20) / 100);
452 | D1A.write(false);
453 | D1B.write(true);
454 | D2A.write(false);
455 | D2B.write(true);
456 | D3A.write(false);
457 | D3B.write(true);
458 | D4A.write(false);
459 | D4B.write(true);
460 | } else if (directionState == DirectionState.STOP) {
461 | PWM1.setDutyCycle(0);
462 | PWM2.setDutyCycle(0);
463 | PWM3.setDutyCycle(0);
464 | PWM4.setDutyCycle(0);
465 | D1A.write(false);
466 | D1B.write(false);
467 | D2A.write(false);
468 | D2B.write(false);
469 | D3A.write(false);
470 | D3B.write(false);
471 | D4A.write(false);
472 | D4B.write(false);
473 | }
474 |
475 | Thread.sleep(20);
476 | }
477 |
478 | public void disconnected() {
479 | showToastFromIOIO(getString(R.string.disconnected));
480 | }
481 |
482 | public void incompatible() {
483 | showToastFromIOIO(getString(R.string.incompatible_firmware));
484 | }
485 |
486 | public void showToastFromIOIO(final String mesage) {
487 | runOnUiThread(new Runnable() {
488 | public void run() {
489 | showToast(mesage);
490 | }
491 | });
492 | }
493 | }
494 |
495 | protected IOIOLooper createIOIOLooper() {
496 | return new Looper();
497 | }
498 | }
499 |
--------------------------------------------------------------------------------
/app/src/main/java/app/akexorcist/ioiocamerarobot/ioio/IOIOService.java:
--------------------------------------------------------------------------------
1 | package app.akexorcist.ioiocamerarobot.ioio;
2 |
3 | import android.content.Context;
4 | import android.os.AsyncTask;
5 | import android.os.Handler;
6 | import android.util.Log;
7 |
8 | import java.io.DataInputStream;
9 | import java.io.EOFException;
10 | import java.io.IOException;
11 | import java.io.InputStream;
12 | import java.io.InterruptedIOException;
13 | import java.net.DatagramPacket;
14 | import java.net.DatagramSocket;
15 | import java.net.InetSocketAddress;
16 | import java.net.ServerSocket;
17 | import java.net.Socket;
18 | import java.net.SocketException;
19 | import java.net.SocketTimeoutException;
20 |
21 | import app.akexorcist.ioiocamerarobot.constant.Command;
22 |
23 | public class IOIOService extends AsyncTask {
24 | private static final String TAG = "IOIOService";
25 | private static final int PORT = 21111;
26 |
27 | private boolean isTaskRunning = true;
28 | private ServerSocket serverSocket;
29 | private Socket socket;
30 | private String password;
31 |
32 | private DataInputStream dataInputStream;
33 | private InputStream inputStream;
34 | private Handler handler;
35 |
36 | public IOIOService(Handler handler, String password) {
37 | this.handler = handler;
38 | this.password = password;
39 | }
40 |
41 | protected Void doInBackground(Void... params) {
42 | Runnable run = new Runnable() {
43 | public void run() {
44 |
45 | try {
46 | byte[] message = new byte[10];
47 | DatagramPacket datagramPacket = new DatagramPacket(message, message.length);
48 | DatagramSocket datagramSocket = new DatagramSocket(null);
49 | datagramSocket.setReuseAddress(true);
50 | datagramSocket.setBroadcast(true);
51 | datagramSocket.bind(new InetSocketAddress(PORT));
52 |
53 | while (isTaskRunning) {
54 | try {
55 | datagramSocket.setSoTimeout(3000);
56 | datagramSocket.receive(datagramPacket);
57 | String text = new String(message, 0, datagramPacket.getLength());
58 | String command = text.substring(0, 2);
59 | if (command.equalsIgnoreCase(Command.FORWARD)) {
60 | int speed = Integer.parseInt(text.substring(2, text.length()));
61 | handler.obtainMessage(Command.MESSAGE_UP, speed - 50).sendToTarget();
62 | } else if (command.equalsIgnoreCase(Command.FORWARD_RIGHT)) {
63 | int speed = Integer.parseInt(text.substring(2, text.length()));
64 | handler.obtainMessage(Command.MESSAGE_UPRIGHT, speed - 50).sendToTarget();
65 | } else if (command.equalsIgnoreCase(Command.FORWARD_LEFT)) {
66 | int speed = Integer.parseInt(text.substring(2, text.length()));
67 | handler.obtainMessage(Command.MESSAGE_UPLEFT, speed - 50).sendToTarget();
68 | } else if (command.equalsIgnoreCase(Command.BACKWARD)) {
69 | int speed = Integer.parseInt(text.substring(2, text.length()));
70 | handler.obtainMessage(Command.MESSAGE_DOWN, speed - 50).sendToTarget();
71 | } else if (command.equalsIgnoreCase(Command.BACKWARD_RIGHT)) {
72 | int speed = Integer.parseInt(text.substring(2, text.length()));
73 | handler.obtainMessage(Command.MESSAGE_DOWNRIGHT, speed - 50).sendToTarget();
74 | } else if (command.equalsIgnoreCase(Command.BACKWARD_LEFT)) {
75 | int speed = Integer.parseInt(text.substring(2, text.length()));
76 | handler.obtainMessage(Command.MESSAGE_DOWNLEFT, speed - 50).sendToTarget();
77 | } else if (command.equalsIgnoreCase(Command.RIGHT)) {
78 | int speed = Integer.parseInt(text.substring(2, text.length()));
79 | handler.obtainMessage(Command.MESSAGE_RIGHT, speed - 50).sendToTarget();
80 | } else if (command.equalsIgnoreCase(Command.LEFT)) {
81 | int speed = Integer.parseInt(text.substring(2, text.length()));
82 | handler.obtainMessage(Command.MESSAGE_LEFT, speed - 50).sendToTarget();
83 | } else if (command.equalsIgnoreCase(Command.STOP)) {
84 | handler.obtainMessage(Command.MESSAGE_STOP).sendToTarget();
85 | }
86 | } catch (SocketTimeoutException e) {
87 | } catch (IOException e) {
88 | e.printStackTrace();
89 | }
90 | }
91 | datagramSocket.close();
92 | Log.e(TAG, "Kill Task");
93 | } catch (SocketException e) {
94 | e.printStackTrace();
95 | }
96 | }
97 | };
98 | new Thread(run).start();
99 |
100 | try {
101 | serverSocket = new ServerSocket(21111);
102 | serverSocket.setSoTimeout(2000);
103 | Log.i(TAG, "Waiting for connect");
104 | while (socket == null && isTaskRunning) {
105 | try {
106 | socket = serverSocket.accept();
107 | socket.setSoTimeout(2000);
108 | } catch (InterruptedIOException e) {
109 | Log.i(TAG, "Waiting for connect");
110 | } catch (SocketException e) {
111 | e.printStackTrace();
112 | }
113 | }
114 |
115 | if (isTaskRunning) {
116 | inputStream = socket.getInputStream();
117 | dataInputStream = new DataInputStream(inputStream);
118 | int size = dataInputStream.readInt();
119 | byte[] buffer = new byte[size];
120 | dataInputStream.readFully(buffer);
121 | if ((new String(buffer)).equalsIgnoreCase(password)) {
122 | handler.obtainMessage(Command.MESSAGE_PASS, socket).sendToTarget();
123 | } else {
124 | handler.obtainMessage(Command.MESSAGE_WRONG, socket).sendToTarget();
125 | }
126 | }
127 |
128 | } catch (IOException e) {
129 | e.printStackTrace();
130 | }
131 |
132 | while (isTaskRunning) {
133 | try {
134 | int size = dataInputStream.readInt();
135 | byte[] buffer = new byte[size];
136 | dataInputStream.readFully(buffer);
137 | String data = new String(buffer);
138 |
139 | if (data.equalsIgnoreCase(Command.SNAP)) {
140 | handler.obtainMessage(Command.MESSAGE_SNAP).sendToTarget();
141 | } else if (data.equalsIgnoreCase(Command.LED_ON) || data.equalsIgnoreCase(Command.LED_OFF)) {
142 | handler.obtainMessage(Command.MESSAGE_FLASH, data).sendToTarget();
143 | } else if (data.equalsIgnoreCase(Command.FOCUS)) {
144 | handler.obtainMessage(Command.MESSAGE_FOCUS).sendToTarget();
145 | }
146 | } catch (EOFException e) {
147 | e.printStackTrace();
148 | handler.obtainMessage(Command.MESSAGE_CLOSE).sendToTarget();
149 | break;
150 | } catch (IOException e) {
151 | }
152 |
153 | if (!socket.isConnected()) {
154 | handler.obtainMessage(Command.MESSAGE_DISCONNECTED).sendToTarget();
155 | }
156 | }
157 | try {
158 | serverSocket.close();
159 | socket.close();
160 | inputStream.close();
161 | dataInputStream.close();
162 | } catch (IOException | NullPointerException e) {
163 | e.printStackTrace();
164 | }
165 | Log.e(TAG, "Service was killed");
166 | return null;
167 | }
168 |
169 | public void killTask() {
170 | isTaskRunning = false;
171 | }
172 | }
173 |
--------------------------------------------------------------------------------
/app/src/main/java/app/akexorcist/ioiocamerarobot/ioio/IOIOSetupActivity.java:
--------------------------------------------------------------------------------
1 | package app.akexorcist.ioiocamerarobot.ioio;
2 |
3 | import android.app.Activity;
4 | import android.app.Dialog;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.content.SharedPreferences;
8 | import android.hardware.Camera;
9 | import android.hardware.Camera.Size;
10 | import android.os.Build;
11 | import android.os.Bundle;
12 | import android.view.View;
13 | import android.view.View.OnClickListener;
14 | import android.view.Window;
15 | import android.widget.AdapterView;
16 | import android.widget.AdapterView.OnItemClickListener;
17 | import android.widget.ArrayAdapter;
18 | import android.widget.Button;
19 | import android.widget.EditText;
20 | import android.widget.ListView;
21 | import android.widget.SeekBar;
22 | import android.widget.SeekBar.OnSeekBarChangeListener;
23 | import android.widget.TextView;
24 | import android.widget.Toast;
25 |
26 | import java.util.ArrayList;
27 | import java.util.List;
28 |
29 | import app.akexorcist.ioiocamerarobot.R;
30 | import app.akexorcist.ioiocamerarobot.constant.ExtraKey;
31 |
32 | public class IOIOSetupActivity extends Activity implements OnClickListener, OnSeekBarChangeListener {
33 | private TextView tvImageQuality;
34 | private EditText etPassword;
35 | private SeekBar sbImageQuality;
36 | private Button btnOk;
37 | private Button btnPreviewSizeChooser;
38 | private ArrayList previewSizeList;
39 |
40 | private int selectedSizePosition;
41 |
42 | protected void onCreate(Bundle savedInstanceState) {
43 | super.onCreate(savedInstanceState);
44 | overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
45 | setContentView(R.layout.activity_ioio_setup);
46 |
47 | SharedPreferences settings = getSharedPreferences(ExtraKey.SETUP_PREFERENCE, Context.MODE_PRIVATE);
48 | selectedSizePosition = settings.getInt(ExtraKey.PREVIEW_SIZE, 0);
49 | String password = settings.getString(ExtraKey.OWN_PASSWORD, "");
50 | int quality = settings.getInt(ExtraKey.QUALITY, 100);
51 |
52 | initCameraPreviewSize();
53 |
54 | etPassword = (EditText) findViewById(R.id.et_password);
55 | etPassword.setText(password);
56 |
57 | btnPreviewSizeChooser = (Button) findViewById(R.id.btn_preview_size_chooser);
58 | updateSeletedPreviewSize();
59 | btnPreviewSizeChooser.setOnClickListener(this);
60 |
61 | tvImageQuality = (TextView) findViewById(R.id.tv_image_quality);
62 | updateTextViewQuality(quality);
63 |
64 | sbImageQuality = (SeekBar) findViewById(R.id.sb_image_quality);
65 | sbImageQuality.setProgress(quality);
66 | sbImageQuality.setOnSeekBarChangeListener(this);
67 |
68 | btnOk = (Button) findViewById(R.id.btn_ok);
69 | btnOk.setOnClickListener(this);
70 | }
71 |
72 | @Override
73 | public void onClick(View v) {
74 | int id = v.getId();
75 | if (id == R.id.btn_preview_size_chooser) {
76 | createPreviewSizeChooserDialog();
77 | } else if (id == R.id.btn_ok) {
78 | confirmSetup();
79 | }
80 | }
81 |
82 | @Override
83 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
84 | saveImageQuality(progress);
85 | updateTextViewQuality(progress);
86 | }
87 |
88 | @Override
89 | public void onStartTrackingTouch(SeekBar seekBar) {
90 | }
91 |
92 | @Override
93 | public void onStopTrackingTouch(SeekBar seekBar) {
94 | }
95 |
96 | public void updateSeletedPreviewSize() {
97 | String strSize = previewSizeList.get(selectedSizePosition);
98 | btnPreviewSizeChooser.setText(strSize);
99 | }
100 |
101 | public void updateTextViewQuality(int quality) {
102 | tvImageQuality.setText(getString(R.string.image_quality, quality));
103 | }
104 |
105 | public void savePassword(String password) {
106 | getPreferenceEditor().putString(ExtraKey.OWN_PASSWORD, password).apply();
107 | }
108 |
109 | public void saveImageQuality(int quality) {
110 | getPreferenceEditor().putInt(ExtraKey.QUALITY, quality).apply();
111 | }
112 |
113 | public void saveImagePreviewSize(int size) {
114 | getPreferenceEditor().putInt(ExtraKey.PREVIEW_SIZE, size).apply();
115 | }
116 |
117 | public SharedPreferences.Editor getPreferenceEditor() {
118 | SharedPreferences settings = getSharedPreferences(ExtraKey.SETUP_PREFERENCE, Context.MODE_PRIVATE);
119 | return settings.edit();
120 | }
121 |
122 | public void goToIOIOController() {
123 | Intent intent = new Intent(this, IOIOControllerActivity.class);
124 | intent.putExtra(ExtraKey.OWN_PASSWORD, etPassword.getText().toString());
125 | intent.putExtra(ExtraKey.PREVIEW_SIZE, selectedSizePosition);
126 | intent.putExtra(ExtraKey.QUALITY, sbImageQuality.getProgress());
127 | startActivity(intent);
128 | }
129 |
130 | @SuppressWarnings("deprecation")
131 | public void initCameraPreviewSize() {
132 | Camera mCamera;
133 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) {
134 | mCamera = Camera.open();
135 | } else {
136 | mCamera = Camera.open(0);
137 | }
138 | Camera.Parameters params = mCamera.getParameters();
139 | initPreviewSizeList(params.getSupportedPreviewSizes());
140 | mCamera.release();
141 | }
142 |
143 | @SuppressWarnings("deprecation")
144 | public void initPreviewSizeList(List previewSize) {
145 | previewSizeList = new ArrayList<>();
146 | for (int i = 0; i < previewSize.size(); i++) {
147 | String str = previewSize.get(i).width + " x " + previewSize.get(i).height;
148 | previewSizeList.add(str);
149 | }
150 | }
151 |
152 | public void createPreviewSizeChooserDialog() {
153 | final Dialog dialogSize = new Dialog(this);
154 | dialogSize.requestWindowFeature(Window.FEATURE_NO_TITLE);
155 | dialogSize.setContentView(R.layout.dialog_camera_size);
156 | dialogSize.setCancelable(true);
157 |
158 | ArrayAdapter adapter = new ArrayAdapter<>(this, R.layout.view_simple_textview, previewSizeList);
159 | ListView lvAvailablePreviewSize = (ListView) dialogSize.findViewById(R.id.lv_available_preview_size);
160 | lvAvailablePreviewSize.setAdapter(adapter);
161 | lvAvailablePreviewSize.setOnItemClickListener(new OnItemClickListener() {
162 | public void onItemClick(AdapterView> adapterView, View view, int position, long id) {
163 | selectedSizePosition = position;
164 | saveImagePreviewSize(position);
165 | updateSeletedPreviewSize();
166 | dialogSize.cancel();
167 | }
168 | });
169 | dialogSize.show();
170 | }
171 |
172 | public void showToast(String message) {
173 | Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
174 | }
175 |
176 | public void confirmSetup() {
177 | String strPassword = etPassword.getText().toString();
178 | if (strPassword.length() != 0) {
179 | savePassword(strPassword);
180 | goToIOIOController();
181 | } else {
182 | showToast(getString(R.string.password_is_required));
183 | }
184 | }
185 | }
186 |
--------------------------------------------------------------------------------
/app/src/main/java/app/akexorcist/ioiocamerarobot/ioio/OrientationManager.java:
--------------------------------------------------------------------------------
1 | package app.akexorcist.ioiocamerarobot.ioio;
2 |
3 | import java.lang.reflect.Method;
4 |
5 | import android.app.Activity;
6 | import android.content.Context;
7 | import android.hardware.SensorManager;
8 | import android.util.DisplayMetrics;
9 | import android.view.Display;
10 | import android.view.OrientationEventListener;
11 | import android.view.Surface;
12 | import android.view.WindowManager;
13 |
14 |
15 | public class OrientationManager {
16 | public final static int PORTRAIT_NORMAL = 0;
17 | public final static int PORTRAIT_REVERSE = 1;
18 | public final static int LANDSCAPE_NORMAL = 2;
19 | public final static int LANDSCAPE_REVERSE = 3;
20 |
21 | Context context;
22 | Activity activity;
23 |
24 | String device_orientation = "";
25 |
26 | public OrientationManager(Activity activity) {
27 | this.activity = activity;
28 | this.context = activity.getApplicationContext();
29 |
30 | int xres = 0, yres = 0;
31 | Method mGetRawH;
32 | Display display = activity.getWindowManager().getDefaultDisplay();
33 | DisplayMetrics dm = new DisplayMetrics();
34 | activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
35 |
36 | if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
37 | try {
38 | mGetRawH = Display.class.getMethod("getRawHeight");
39 | Method mGetRawW = Display.class.getMethod("getRawWidth");
40 | xres = (Integer) mGetRawW.invoke(display);
41 | yres = (Integer) mGetRawH.invoke(display);
42 | } catch (Exception e) {
43 | xres = display.getWidth();
44 | yres = display.getHeight();
45 | }
46 | } else if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
47 | DisplayMetrics outMetrics = new DisplayMetrics ();
48 | display.getRealMetrics(outMetrics);
49 | xres = outMetrics.widthPixels;
50 | yres = outMetrics.heightPixels;
51 | }
52 |
53 | int hdp = (int)(yres * (1f / dm.density));
54 | int wdp = (int)(xres * (1f / dm.density));
55 | int sw = (hdp < wdp) ? hdp : wdp;
56 | device_orientation = (sw >= 720) ? "landscape" : "portrait";
57 | }
58 |
59 | public int getOrientation() {
60 | WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
61 | int rotation = wm.getDefaultDisplay().getRotation();
62 |
63 | if(device_orientation.equals("portrait")) {
64 | if(rotation == Surface.ROTATION_0) {
65 | return PORTRAIT_NORMAL;
66 | } else if(rotation == Surface.ROTATION_90) {
67 | return LANDSCAPE_NORMAL;
68 | } else if(rotation == Surface.ROTATION_180) {
69 | return PORTRAIT_REVERSE;
70 | } else if(rotation == Surface.ROTATION_270) {
71 | return LANDSCAPE_REVERSE;
72 | }
73 | } else if(device_orientation.equals("landscape")) {
74 | if(rotation == Surface.ROTATION_0) {
75 | return LANDSCAPE_NORMAL;
76 | } else if(rotation == Surface.ROTATION_90) {
77 | return PORTRAIT_REVERSE;
78 | } else if(rotation == Surface.ROTATION_180) {
79 | return LANDSCAPE_REVERSE;
80 | } else if(rotation == Surface.ROTATION_270) {
81 | return PORTRAIT_NORMAL;
82 | }
83 | }
84 | return -1;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/app/src/main/java/app/akexorcist/ioiocamerarobot/menu/MenuActivity.java:
--------------------------------------------------------------------------------
1 | package app.akexorcist.ioiocamerarobot.menu;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.view.View;
7 | import android.view.View.OnClickListener;
8 | import android.widget.Button;
9 |
10 | import app.akexorcist.ioiocamerarobot.controller.ControllerSetupActivity;
11 | import app.akexorcist.ioiocamerarobot.ioio.IOIOSetupActivity;
12 | import app.akexorcist.ioiocamerarobot.R;
13 |
14 | public class MenuActivity extends Activity {
15 | private Button btnController;
16 | private Button btnIoio;
17 |
18 | public void onCreate(Bundle savedInstanceState) {
19 | super.onCreate(savedInstanceState);
20 | overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
21 | setContentView(R.layout.activity_main);
22 |
23 | btnController = (Button)findViewById(R.id.btn_controller);
24 | btnController.setOnClickListener(new OnClickListener() {
25 | public void onClick(View v) {
26 | Intent intent = new Intent(MenuActivity.this, ControllerSetupActivity.class);
27 | startActivity(intent);
28 | }
29 | });
30 |
31 | btnIoio = (Button)findViewById(R.id.btn_ioio);
32 | btnIoio.setOnClickListener(new OnClickListener() {
33 | public void onClick(View v) {
34 | Intent intent = new Intent(MenuActivity.this, IOIOSetupActivity.class);
35 | startActivity(intent);
36 | }
37 | });
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/java/app/akexorcist/ioiocamerarobot/splashscreen/SplashScreenActivity.java:
--------------------------------------------------------------------------------
1 | package app.akexorcist.ioiocamerarobot.splashscreen;
2 |
3 | import android.animation.Animator;
4 | import android.animation.AnimatorInflater;
5 | import android.animation.AnimatorSet;
6 | import android.app.Activity;
7 | import android.content.Intent;
8 | import android.os.Bundle;
9 | import android.widget.ImageView;
10 |
11 | import app.akexorcist.ioiocamerarobot.R;
12 | import app.akexorcist.ioiocamerarobot.menu.MenuActivity;
13 |
14 | public class SplashScreenActivity extends Activity implements Animator.AnimatorListener {
15 | private AnimatorSet animatorSet;
16 | private ImageView ivInexLogo;
17 |
18 | public void onCreate(Bundle savedInstanceState) {
19 | super.onCreate(savedInstanceState);
20 | setContentView(R.layout.activity_splashscreen);
21 |
22 | ivInexLogo = (ImageView) findViewById(R.id.iv_inex_logo);
23 | ivInexLogo.setAlpha(0f);
24 |
25 | goToMenuActivity();
26 | // startLogoAnimation();
27 | }
28 |
29 | public void startLogoAnimation() {
30 | animatorSet = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.set_splashscreen);
31 | animatorSet.setTarget(ivInexLogo);
32 | animatorSet.start();
33 | animatorSet.addListener(this);
34 | }
35 |
36 | public void goToMenuActivity() {
37 | Intent intent = new Intent(this, MenuActivity.class);
38 | startActivity(intent);
39 | finish();
40 | }
41 |
42 | @Override
43 | protected void onResume() {
44 | super.onResume();
45 | animatorSet.resume();
46 | }
47 |
48 | @Override
49 | protected void onPause() {
50 | super.onPause();
51 | animatorSet.pause();
52 | }
53 |
54 | @Override
55 | public void onAnimationStart(Animator animation) {
56 | }
57 |
58 | @Override
59 | public void onAnimationEnd(Animator animation) {
60 | goToMenuActivity();
61 | }
62 |
63 | @Override
64 | public void onAnimationCancel(Animator animation) {
65 | }
66 |
67 | @Override
68 | public void onAnimationRepeat(Animator animation) {
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/app/src/main/java/app/akexorcist/ioiocamerarobot/utils/JoyStickView.java:
--------------------------------------------------------------------------------
1 | package app.akexorcist.ioiocamerarobot.utils;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.graphics.Canvas;
7 | import android.graphics.Paint;
8 | import android.view.MotionEvent;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.view.ViewGroup.LayoutParams;
12 |
13 | public class JoyStickView {
14 | public static final int STICK_NONE = 0;
15 | public static final int STICK_UP = 1;
16 | public static final int STICK_UPRIGHT = 2;
17 | public static final int STICK_RIGHT = 3;
18 | public static final int STICK_DOWNRIGHT = 4;
19 | public static final int STICK_DOWN = 5;
20 | public static final int STICK_DOWNLEFT = 6;
21 | public static final int STICK_LEFT = 7;
22 | public static final int STICK_UPLEFT = 8;
23 |
24 | private int STICK_ALPHA = 200;
25 | private int LAYOUT_ALPHA = 200;
26 | private int OFFSET = 0;
27 |
28 | private ViewGroup mLayout;
29 | private LayoutParams params;
30 | private int stick_width, stick_height;
31 |
32 | private int position_x = 0, position_y = 0, min_distance = 0;
33 | private float distance = 0, angle = 0;
34 |
35 | private DrawCanvas draw;
36 | private Paint paint;
37 | private Bitmap stick;
38 |
39 | private boolean touch_state = false;
40 |
41 | public JoyStickView(Context context, ViewGroup layout, int stick_res_id) {
42 |
43 | stick = BitmapFactory.decodeResource(context.getResources(), stick_res_id);
44 |
45 | stick_width = stick.getWidth();
46 | stick_height = stick.getHeight();
47 |
48 | draw = new DrawCanvas(context);
49 | paint = new Paint();
50 | mLayout = layout;
51 | params = mLayout.getLayoutParams();
52 | }
53 |
54 | public void drawStick(MotionEvent arg1) {
55 | position_x = (int) (arg1.getX() - (params.width / 2));
56 | position_y = (int) (arg1.getY() - (params.height / 2));
57 | distance = (float) Math.sqrt(Math.pow(position_x, 2) + Math.pow(position_y, 2));
58 | angle = (float) cal_angle(position_x, position_y);
59 |
60 |
61 | if (arg1.getAction() == MotionEvent.ACTION_DOWN) {
62 | if (distance <= (params.width / 2) - OFFSET) {
63 | draw.position(arg1.getX(), arg1.getY());
64 | draw();
65 | touch_state = true;
66 | }
67 | } else if (arg1.getAction() == MotionEvent.ACTION_MOVE && touch_state) {
68 | if (distance <= (params.width / 2) - OFFSET) {
69 | draw.position(arg1.getX(), arg1.getY());
70 | draw();
71 | } else if (distance > (params.width / 2) - OFFSET) {
72 | float x = (float) (Math.cos(Math.toRadians(cal_angle(position_x, position_y))) * ((params.width / 2) - OFFSET));
73 | float y = (float) (Math.sin(Math.toRadians(cal_angle(position_x, position_y))) * ((params.height / 2) - OFFSET));
74 | x += (params.width / 2);
75 | y += (params.height / 2);
76 | draw.position(x, y);
77 | draw();
78 | } else {
79 | mLayout.removeView(draw);
80 | }
81 | } else if (arg1.getAction() == MotionEvent.ACTION_UP) {
82 | mLayout.removeView(draw);
83 | touch_state = false;
84 | }
85 | }
86 |
87 | public int[] getPosition() {
88 | if (distance > min_distance && touch_state) {
89 | return new int[]{position_x, position_y};
90 | }
91 | return new int[]{0, 0};
92 | }
93 |
94 | public int getX() {
95 | if (distance > min_distance && touch_state) {
96 | return position_x;
97 | }
98 | return 0;
99 | }
100 |
101 | public int getY() {
102 | if (distance > min_distance && touch_state) {
103 | return position_y;
104 | }
105 | return 0;
106 | }
107 |
108 | public float getAngle() {
109 | if (distance > min_distance && touch_state) {
110 | return angle;
111 | }
112 | return 0;
113 | }
114 |
115 | public float getDistance() {
116 | if (distance > min_distance && touch_state) {
117 | return distance;
118 | }
119 | return 0;
120 | }
121 |
122 | public void setMinimumDistance(int minDistance) {
123 | min_distance = minDistance;
124 | }
125 |
126 | public int getMinimumDistance() {
127 | return min_distance;
128 | }
129 |
130 | public int get8Direction() {
131 | if (distance > min_distance && touch_state) {
132 | if (angle >= 247.5 && angle < 292.5) {
133 | return STICK_UP;
134 | } else if (angle >= 292.5 && angle < 337.5) {
135 | return STICK_UPRIGHT;
136 | } else if (angle >= 337.5 || angle < 22.5) {
137 | return STICK_RIGHT;
138 | } else if (angle >= 22.5 && angle < 67.5) {
139 | return STICK_DOWNRIGHT;
140 | } else if (angle >= 67.5 && angle < 112.5) {
141 | return STICK_DOWN;
142 | } else if (angle >= 112.5 && angle < 157.5) {
143 | return STICK_DOWNLEFT;
144 | } else if (angle >= 157.5 && angle < 202.5) {
145 | return STICK_LEFT;
146 | } else if (angle >= 202.5 && angle < 247.5) {
147 | return STICK_UPLEFT;
148 | }
149 | } else if (distance <= min_distance && touch_state) {
150 | return STICK_NONE;
151 | }
152 | return 0;
153 | }
154 |
155 | public int get4Direction() {
156 | if (distance > min_distance && touch_state) {
157 | if (angle >= 225 && angle < 315) {
158 | return STICK_UP;
159 | } else if (angle >= 315 || angle < 45) {
160 | return STICK_RIGHT;
161 | } else if (angle >= 45 && angle < 135) {
162 | return STICK_DOWN;
163 | } else if (angle >= 135 && angle < 225) {
164 | return STICK_LEFT;
165 | }
166 | } else if (distance <= min_distance && touch_state) {
167 | return STICK_NONE;
168 | }
169 | return 0;
170 | }
171 |
172 | public void setOffset(int offset) {
173 | OFFSET = offset;
174 | }
175 |
176 | public int getOffset() {
177 | return OFFSET;
178 | }
179 |
180 | public void setStickAlpha(int alpha) {
181 | STICK_ALPHA = alpha;
182 | paint.setAlpha(alpha);
183 | }
184 |
185 | public int getStickAlpha() {
186 | return STICK_ALPHA;
187 | }
188 |
189 | public void setLayoutAlpha(int alpha) {
190 | LAYOUT_ALPHA = alpha;
191 | mLayout.getBackground().setAlpha(alpha);
192 | }
193 |
194 | public int getLayoutAlpha() {
195 | return LAYOUT_ALPHA;
196 | }
197 |
198 | public void setStickSize(int width, int height) {
199 | stick = Bitmap.createScaledBitmap(stick, width, height, false);
200 | stick_width = stick.getWidth();
201 | stick_height = stick.getHeight();
202 | }
203 |
204 | public void setStickWidth(int width) {
205 | stick = Bitmap.createScaledBitmap(stick, width, stick_height, false);
206 | stick_width = stick.getWidth();
207 | }
208 |
209 | public void setStickHeight(int height) {
210 | stick = Bitmap.createScaledBitmap(stick, stick_width, height, false);
211 | stick_height = stick.getHeight();
212 | }
213 |
214 | public int getStickWidth() {
215 | return stick_width;
216 | }
217 |
218 | public int getStickHeight() {
219 | return stick_height;
220 | }
221 |
222 | public void setLayoutSize(int width, int height) {
223 | params.width = width;
224 | params.height = height;
225 | }
226 |
227 | public int getLayoutWidth() {
228 | return params.width;
229 | }
230 |
231 | public int getLayoutHeight() {
232 | return params.height;
233 | }
234 |
235 | private double cal_angle(float x, float y) {
236 | if (x >= 0 && y >= 0)
237 | return Math.toDegrees(Math.atan(y / x));
238 | else if (x < 0 && y >= 0)
239 | return Math.toDegrees(Math.atan(y / x)) + 180;
240 | else if (x < 0 && y < 0)
241 | return Math.toDegrees(Math.atan(y / x)) + 180;
242 | else if (x >= 0 && y < 0)
243 | return Math.toDegrees(Math.atan(y / x)) + 360;
244 | return 0;
245 | }
246 |
247 | private void draw() {
248 | try {
249 | mLayout.removeView(draw);
250 | } catch (Exception e) {
251 | }
252 | mLayout.addView(draw);
253 | }
254 |
255 | private class DrawCanvas extends View {
256 | float x, y;
257 |
258 | private DrawCanvas(Context mContext) {
259 | super(mContext);
260 | }
261 |
262 | public void onDraw(Canvas canvas) {
263 | canvas.drawBitmap(stick, x, y, paint);
264 | }
265 |
266 | private void position(float pos_x, float pos_y) {
267 | x = pos_x - (stick_width / 2);
268 | y = pos_y - (stick_height / 2);
269 | }
270 | }
271 | }
272 |
--------------------------------------------------------------------------------
/app/src/main/java/app/akexorcist/ioiocamerarobot/utils/Utilities.java:
--------------------------------------------------------------------------------
1 | package app.akexorcist.ioiocamerarobot.utils;
2 |
3 | import android.content.Context;
4 | import android.net.wifi.WifiInfo;
5 | import android.net.wifi.WifiManager;
6 |
7 | import java.lang.reflect.InvocationTargetException;
8 | import java.lang.reflect.Method;
9 |
10 | /**
11 | * Created by Akexorcist on 9/5/15 AD.
12 | */
13 | public class Utilities {
14 | public static String getCurrentIP(Context context) {
15 | WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
16 | Method[] wmMethods = wifi.getClass().getDeclaredMethods();
17 | for (Method method : wmMethods) {
18 | if (method.getName().equals("isWifiApEnabled")) {
19 |
20 | try {
21 | if (method.invoke(wifi).toString().equals("false")) {
22 | WifiInfo wifiInfo = wifi.getConnectionInfo();
23 | int ipAddress = wifiInfo.getIpAddress();
24 | return (ipAddress & 0xFF) + "." +
25 | ((ipAddress >> 8) & 0xFF) + "." +
26 | ((ipAddress >> 16) & 0xFF) + "." +
27 | ((ipAddress >> 24) & 0xFF);
28 | } else if (method.invoke(wifi).toString().equals("true")) {
29 | return "192.168.43.1";
30 | }
31 | } catch (IllegalArgumentException | InvocationTargetException | IllegalAccessException e) {
32 | e.printStackTrace();
33 | }
34 | }
35 | }
36 | return "Unknown";
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/fade_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/fade_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/animator/fade_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/animator/fade_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/animator/set_menu_slide_down.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/animator/set_menu_slide_up.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/animator/set_splashscreen.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
14 |
15 |
21 |
22 |
28 |
29 |
30 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-ldpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-ldpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_cancel_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_cancel_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_cancel_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_cancel_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_center.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_center.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_down_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_down_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_down_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_down_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_downleft_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_downleft_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_downleft_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_downleft_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_downright_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_downright_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_downright_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_downright_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_flash_off_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_flash_off_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_flash_off_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_flash_off_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_flash_on_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_flash_on_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_flash_on_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_flash_on_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_focus_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_focus_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_focus_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_focus_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_left_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_left_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_left_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_left_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_login_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_login_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_login_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_login_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_mode_control_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_mode_control_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_mode_control_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_mode_control_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_mode_ioio_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_mode_ioio_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_mode_ioio_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_mode_ioio_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_right_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_right_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_right_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_right_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_snap_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_snap_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_snap_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_snap_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_start_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_start_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_start_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_start_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_up_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_up_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_up_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_up_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_upleft_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_upleft_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_upleft_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_upleft_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_upright_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_upright_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/button_upright_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/button_upright_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/center.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/center.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/dialog_header_control.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/dialog_header_control.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/dialog_header_ioio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/dialog_header_ioio.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/edittext_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/edittext_bg.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/image_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/image_button.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/image_button_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/image_button_bg.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/image_divider.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/image_divider.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/logo_inex.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/logo_inex.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/seekbar_bg.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/seekbar_bg.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/seekbar_stripe_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/seekbar_stripe_bg.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/spinner_bg_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/spinner_bg_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/spinner_bg_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/spinner_bg_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/spinner_dropdownlist_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/spinner_dropdownlist_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/spinner_dropdownlist_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-mdpi/spinner_dropdownlist_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_cancel_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_cancel_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_cancel_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_cancel_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_center.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_center.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_down_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_down_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_down_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_down_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_downleft_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_downleft_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_downleft_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_downleft_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_downright_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_downright_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_downright_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_downright_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_flash_off_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_flash_off_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_flash_off_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_flash_off_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_flash_on_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_flash_on_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_flash_on_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_flash_on_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_focus_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_focus_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_focus_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_focus_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_left_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_left_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_left_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_left_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_login_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_login_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_login_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_login_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_mode_control_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_mode_control_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_mode_control_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_mode_control_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_mode_ioio_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_mode_ioio_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_mode_ioio_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_mode_ioio_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_right_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_right_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_right_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_right_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_snap_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_snap_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_snap_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_snap_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_start_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_start_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_start_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_start_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_up_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_up_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_up_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_up_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_upleft_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_upleft_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_upleft_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_upleft_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_upright_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_upright_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/button_upright_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/button_upright_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/center.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/center.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/dialog_header_control.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/dialog_header_control.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/dialog_header_ioio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/dialog_header_ioio.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/edittext_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/edittext_bg.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/image_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/image_button.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/image_button_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/image_button_bg.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/image_divider.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/image_divider.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/logo_inex.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/logo_inex.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/seekbar_bg.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/seekbar_bg.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/seekbar_stripe_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/seekbar_stripe_bg.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/spinner_bg_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/spinner_bg_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/spinner_bg_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/spinner_bg_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/spinner_dropdownlist_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/spinner_dropdownlist_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/spinner_dropdownlist_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xhdpi/spinner_dropdownlist_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/app/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_cancel.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_down.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_downleft.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_downright.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_flash.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
7 |
9 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_focus.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_login.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_mode_control.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_mode_ioio.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_snap.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_start.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_up.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_upleft.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_upright.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/seekbar_progress.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 | -
7 |
8 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/spinner_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/spinner_dropdownlist.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_controller.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
22 |
23 |
29 |
30 |
36 |
37 |
44 |
45 |
46 |
47 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_controller_connection.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
19 |
20 |
26 |
27 |
34 |
35 |
41 |
42 |
55 |
56 |
63 |
64 |
75 |
76 |
77 |
78 |
83 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_ioio.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
18 |
19 |
26 |
27 |
34 |
35 |
36 |
43 |
44 |
48 |
49 |
55 |
56 |
62 |
63 |
69 |
70 |
71 |
75 |
76 |
82 |
83 |
89 |
90 |
96 |
97 |
98 |
99 |
103 |
104 |
110 |
111 |
117 |
118 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_ioio_setup.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
17 |
18 |
19 |
24 |
25 |
33 |
34 |
41 |
42 |
49 |
50 |
51 |
57 |
64 |
65 |
74 |
75 |
82 |
83 |
94 |
95 |
96 |
97 |
102 |
103 |
104 |
105 |
113 |
114 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
14 |
15 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_splashscreen.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_camera_size.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_simple_text.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_simple_textview.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/values-large/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 30sp
5 | 150dp
6 | 150dp
7 | 60dp
8 | 317dp
9 | 50dp
10 |
11 | 240dp
12 | 90dp
13 | 300dp
14 | 15dp
15 | 60dp
16 |
17 |
18 | 220dp
19 | 30dp
20 | 90dp
21 | 10dp
22 | 20dp
23 |
24 |
25 | 40dp
26 |
27 |
28 | 35sp
29 | 72sp
30 | 38sp
31 |
32 |
33 | 30sp
34 | 15dp
35 |
36 |
37 | 222dp
38 | 400dp
39 |
40 |
--------------------------------------------------------------------------------
/app/src/main/res/values-normal/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 17sp
5 | 100dp
6 | 100dp
7 | 35dp
8 | 185dp
9 | 20dp
10 |
11 | 150dp
12 | 50dp
13 | 200dp
14 | 10dp
15 | 30dp
16 |
17 |
18 | 120dp
19 | 30dp
20 | 60dp
21 | 5dp
22 | 15dp
23 |
24 |
25 | 20dp
26 |
27 |
28 | 25sp
29 | 72sp
30 | 38sp
31 |
32 |
33 | 20sp
34 | 10dp
35 |
36 |
37 | 130dp
38 | 234dp
39 |
40 |
--------------------------------------------------------------------------------
/app/src/main/res/values-small/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 17sp
5 | 100dp
6 | 100dp
7 | 35dp
8 | 185dp
9 | 20dp
10 |
11 | 150dp
12 | 50dp
13 | 160dp
14 | 10dp
15 | 30dp
16 |
17 |
18 | 120dp
19 | 15dp
20 | 50dp
21 | 5dp
22 | 5dp
23 |
24 |
25 | 20dp
26 |
27 |
28 | 20sp
29 | 48sp
30 | 25sp
31 |
32 |
33 | 20sp
34 | 10dp
35 |
36 |
37 | 130dp
38 | 234dp
39 |
40 |
--------------------------------------------------------------------------------
/app/src/main/res/values-xlarge/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 45sp
5 | 250dp
6 | 250dp
7 | 90dp
8 | 475dp
9 | 50dp
10 |
11 | 350dp
12 | 140dp
13 | 400dp
14 | 20dp
15 | 70dp
16 |
17 |
18 | 300dp
19 | 50dp
20 | 120dp
21 | 15dp
22 | 10dp
23 |
24 |
25 | 40dp
26 |
27 |
28 | 50sp
29 | 108sp
30 | 57sp
31 |
32 |
33 | 30sp
34 | 15dp
35 |
36 |
37 | 334dp
38 | 600dp
39 |
40 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | #ca2559
5 | #fe3e7a
6 | #136755
7 | #3fa992
8 |
9 | @color/pink
10 | #fffbd5
11 | #ffffff
12 | #000000
13 | #20000000
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Camera Robot
5 | Hello world!
6 | Settings
7 | Password
8 | Image Resolution
9 | Image Quality %1$s %%
10 | Speed %1$s
11 | Password is required.
12 | Unavailable Flash Mode.
13 | Device not support flash
14 | Out of memory. Please decrease image quality and preview size.
15 | Connection down, will be restart service in 1 seconds
16 | 0.0.0.0
17 | Incompatible firmware version
18 | Disconnected
19 | Connected
20 | IP Address
21 | Connection Failed
22 | Wrong Password
23 | Photo Taken.
24 | Connection accepted
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/accessory_filter.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/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 | }
6 | dependencies {
7 | classpath 'com.android.tools.build:gradle:1.2.3'
8 | }
9 | }
10 |
11 | allprojects {
12 | repositories {
13 | jcenter()
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/doc/Screenshot_2015-09-06-00-15-35_framed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/doc/Screenshot_2015-09-06-00-15-35_framed.png
--------------------------------------------------------------------------------
/doc/Screenshot_2015-09-06-00-16-05_framed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/doc/Screenshot_2015-09-06-00-16-05_framed.png
--------------------------------------------------------------------------------
/doc/Screenshot_20150906-001533_framed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/doc/Screenshot_20150906-001533_framed.png
--------------------------------------------------------------------------------
/doc/Screenshot_20150910-151759_framed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/doc/Screenshot_20150910-151759_framed.png
--------------------------------------------------------------------------------
/doc/circuit-thumbnail.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/doc/circuit-thumbnail.jpg
--------------------------------------------------------------------------------
/doc/circuit.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/doc/circuit.ai
--------------------------------------------------------------------------------
/doc/circuit.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/doc/circuit.jpg
--------------------------------------------------------------------------------
/doc/connection-01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/doc/connection-01.jpg
--------------------------------------------------------------------------------
/doc/connection-02.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/doc/connection-02.jpg
--------------------------------------------------------------------------------
/doc/header.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/doc/header.jpg
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akexorcist/IOIO-CameraRobot/61110789c198d0db9324bfd66880d9079a0fb0cb/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Apr 10 15:27:10 PDT 2013
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-2.2.1-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 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------