OPC(Olympus Air)用撮影アプリ。
Revisão | f20bdfdf408863985be14a9a428b1c4af6726464 (tree) |
---|---|
Hora | 2021-01-10 00:34:11 |
Autor | MRSa <mrsa@myad...> |
Commiter | MRSa |
ConnectionMethodの違いで背景画像を変更した。
@@ -821,7 +821,6 @@ public class MainActivity extends AppCompatActivity implements IChangeScene, IS | ||
821 | 821 | { |
822 | 822 | liveView.hideDialog(); |
823 | 823 | listener.setEnableOperation(operation.ENABLE); |
824 | - | |
825 | 824 | } |
826 | 825 | } |
827 | 826 | catch (Exception e) |
@@ -830,6 +829,20 @@ public class MainActivity extends AppCompatActivity implements IChangeScene, IS | ||
830 | 829 | } |
831 | 830 | } |
832 | 831 | |
832 | + private void updateConnectionMethodMessage() | |
833 | + { | |
834 | + try | |
835 | + { | |
836 | + String connectionMethod = preferences.getString(IPreferenceCameraPropertyAccessor.CONNECTION_METHOD, IPreferenceCameraPropertyAccessor.CONNECTION_METHOD_DEFAULT_VALUE); | |
837 | + int methodId = (connectionMethod.contains(IPreferenceCameraPropertyAccessor.CONNECTION_METHOD_THETA)) ? R.string.connection_method_theta : R.string.connection_method_opc; | |
838 | + setMessage(IShowInformation.AREA_5, Color.MAGENTA, getString(methodId)); | |
839 | + } | |
840 | + catch (Exception e) | |
841 | + { | |
842 | + e.printStackTrace(); | |
843 | + } | |
844 | + } | |
845 | + | |
833 | 846 | private void updateConnectionMethod(String parameter, ICameraController method) |
834 | 847 | { |
835 | 848 | try |
@@ -845,7 +858,7 @@ public class MainActivity extends AppCompatActivity implements IChangeScene, IS | ||
845 | 858 | } |
846 | 859 | |
847 | 860 | /** |
848 | - * 接続方式を変更するか確認する | |
861 | + * 接続方式を変更するか確認する (OPC ⇔ THETA) | |
849 | 862 | * |
850 | 863 | */ |
851 | 864 | private void changeConnectionMethod() |
@@ -882,6 +895,7 @@ public class MainActivity extends AppCompatActivity implements IChangeScene, IS | ||
882 | 895 | // 接続方式を Theta に切り替える |
883 | 896 | updateConnectionMethod(IPreferenceCameraPropertyAccessor.CONNECTION_METHOD_THETA, olyAirCoordinator); // thetaCoordinator |
884 | 897 | } |
898 | + updateConnectionMethodMessage(); | |
885 | 899 | } |
886 | 900 | }); |
887 | 901 | } |
@@ -120,7 +120,20 @@ public class CameraLiveImageView extends View implements IImageDataReceiver, IAu | ||
120 | 120 | // ダミーのビットマップデータ読み込み...画面表示のテスト用ロジック |
121 | 121 | try |
122 | 122 | { |
123 | - imageBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.momonga); | |
123 | + int imageId = R.drawable.momonga; | |
124 | + try | |
125 | + { | |
126 | + String connectionMethod = preferences.getString(IPreferenceCameraPropertyAccessor.CONNECTION_METHOD, IPreferenceCameraPropertyAccessor.CONNECTION_METHOD_DEFAULT_VALUE); | |
127 | + if (connectionMethod != null) | |
128 | + { | |
129 | + imageId = (connectionMethod.contains(IPreferenceCameraPropertyAccessor.CONNECTION_METHOD_THETA)) ? R.drawable.kamakura : R.drawable.momonga; | |
130 | + } | |
131 | + } | |
132 | + catch (Throwable tt) | |
133 | + { | |
134 | + tt.printStackTrace(); | |
135 | + } | |
136 | + imageBitmap = BitmapFactory.decodeResource(context.getResources(), imageId); | |
124 | 137 | } |
125 | 138 | catch (Throwable t) |
126 | 139 | { |
@@ -0,0 +1,524 @@ | ||
1 | +package jp.sfjp.gokigen.a01c.utils | |
2 | + | |
3 | +import android.graphics.Bitmap | |
4 | +import android.graphics.BitmapFactory | |
5 | +import android.util.Log | |
6 | +import java.io.* | |
7 | +import java.net.HttpURLConnection | |
8 | +import java.net.URL | |
9 | + | |
10 | +class SimpleHttpClient() | |
11 | +{ | |
12 | + /** | |
13 | + * | |
14 | + * | |
15 | + * | |
16 | + */ | |
17 | + fun httpGet(url: String, timeoutMs: Int): String | |
18 | + { | |
19 | + var inputStream : InputStream? = null | |
20 | + var replyString = "" | |
21 | + var timeout = timeoutMs | |
22 | + if (timeoutMs < 0) | |
23 | + { | |
24 | + timeout = DEFAULT_TIMEOUT | |
25 | + } | |
26 | + | |
27 | + // HTTP GETメソッドで要求を投げる | |
28 | + try | |
29 | + { | |
30 | + val httpConn = URL(url).openConnection() as HttpURLConnection | |
31 | + try | |
32 | + { | |
33 | + httpConn.requestMethod = "GET" | |
34 | + httpConn.connectTimeout = timeout | |
35 | + httpConn.readTimeout = timeout | |
36 | + httpConn.connect() | |
37 | + val responseCode = httpConn.responseCode | |
38 | + if (responseCode == HttpURLConnection.HTTP_OK) | |
39 | + { | |
40 | + inputStream = httpConn.inputStream | |
41 | + } | |
42 | + if (inputStream == null) | |
43 | + { | |
44 | + Log.w(TAG, "httpGet: Response Code Error: $responseCode: $url") | |
45 | + return ("") | |
46 | + } | |
47 | + } | |
48 | + catch (ee : Exception) | |
49 | + { | |
50 | + Log.w(TAG, "httpGet: " + url + " " + ee.message) | |
51 | + ee.printStackTrace() | |
52 | + httpConn.disconnect() | |
53 | + return ("") | |
54 | + } | |
55 | + } | |
56 | + catch (e: Exception) | |
57 | + { | |
58 | + Log.w(TAG, "httpGet(2): " + url + " " + e.message) | |
59 | + e.printStackTrace() | |
60 | + return ("") | |
61 | + } | |
62 | + | |
63 | + // 応答を確認する | |
64 | + try | |
65 | + { | |
66 | + val responseBuf = StringBuilder() | |
67 | + val reader = BufferedReader(InputStreamReader(inputStream)) | |
68 | + var c: Int | |
69 | + while (reader.read().also { c = it } != -1) | |
70 | + { | |
71 | + responseBuf.append(c.toChar()) | |
72 | + } | |
73 | + replyString = responseBuf.toString() | |
74 | + reader.close() | |
75 | + } | |
76 | + catch (e: Exception) | |
77 | + { | |
78 | + Log.w(TAG, "httpGet: exception: " + e.message) | |
79 | + e.printStackTrace() | |
80 | + } | |
81 | + finally | |
82 | + { | |
83 | + try | |
84 | + { | |
85 | + inputStream.close() | |
86 | + } | |
87 | + catch (e: Exception) | |
88 | + { | |
89 | + e.printStackTrace() | |
90 | + } | |
91 | + } | |
92 | + return (replyString) | |
93 | + } | |
94 | + | |
95 | + /** | |
96 | + * | |
97 | + * | |
98 | + * | |
99 | + */ | |
100 | + fun httpGetBytes(url: String, setProperty: Map<String, String>?, timeoutMs: Int, callback: IReceivedMessageCallback) | |
101 | + { | |
102 | + httpCommandBytes(url, "GET", null, setProperty, null, timeoutMs, callback) | |
103 | + } | |
104 | + | |
105 | + /** | |
106 | + * | |
107 | + * | |
108 | + * | |
109 | + */ | |
110 | + fun httpPostBytes(url: String, postData: String?, setProperty: Map<String, String>?, timeoutMs: Int, callback: IReceivedMessageCallback) | |
111 | + { | |
112 | + httpCommandBytes(url, "POST", postData, setProperty, null, timeoutMs, callback) | |
113 | + } | |
114 | + | |
115 | + private fun httpCommandBytes(url: String, requestMethod: String, postData: String?, setProperty: Map<String, String>?, contentType: String?, timeoutMs: Int, callback: IReceivedMessageCallback) | |
116 | + { | |
117 | + var inputStream: InputStream? = null | |
118 | + var timeout = timeoutMs | |
119 | + if (timeoutMs < 0) | |
120 | + { | |
121 | + timeout = DEFAULT_TIMEOUT | |
122 | + } | |
123 | + | |
124 | + // HTTP メソッドで要求を送出 | |
125 | + try | |
126 | + { | |
127 | + val httpConn = URL(url).openConnection() as HttpURLConnection | |
128 | + httpConn.requestMethod = requestMethod | |
129 | + if (setProperty != null) | |
130 | + { | |
131 | + for (key in setProperty.keys) | |
132 | + { | |
133 | + val value = setProperty[key] | |
134 | + httpConn.setRequestProperty(key, value) | |
135 | + } | |
136 | + } | |
137 | + if (contentType != null) | |
138 | + { | |
139 | + httpConn.setRequestProperty("Content-Type", contentType) | |
140 | + } | |
141 | + httpConn.connectTimeout = timeout | |
142 | + httpConn.readTimeout = timeout | |
143 | + if (postData == null) | |
144 | + { | |
145 | + httpConn.connect() | |
146 | + } | |
147 | + else | |
148 | + { | |
149 | + httpConn.doInput = true | |
150 | + httpConn.doOutput = true | |
151 | + val outputStream = httpConn.outputStream | |
152 | + val writer = OutputStreamWriter(outputStream, "UTF-8") | |
153 | + writer.write(postData) | |
154 | + writer.flush() | |
155 | + writer.close() | |
156 | + outputStream.close() | |
157 | + } | |
158 | + val responseCode = httpConn.responseCode | |
159 | + if (responseCode == HttpURLConnection.HTTP_OK) | |
160 | + { | |
161 | + inputStream = httpConn.inputStream | |
162 | + } | |
163 | + if (inputStream == null) | |
164 | + { | |
165 | + Log.w(TAG, " http $requestMethod Response Code Error: $responseCode: $url") | |
166 | + callback.onErrorOccurred(NullPointerException()) | |
167 | + callback.onCompleted() | |
168 | + return | |
169 | + } | |
170 | + | |
171 | + // 応答を確認する | |
172 | + try | |
173 | + { | |
174 | + var contentLength = httpConn.contentLength | |
175 | + if (contentLength < 0) | |
176 | + { | |
177 | + // コンテンツ長が取れない場合の処理... | |
178 | + try | |
179 | + { | |
180 | + val headers = httpConn.headerFields | |
181 | + // コンテンツ長さが取れない場合は、HTTP応答ヘッダから取得する | |
182 | + val valueList = headers["X-FILE_SIZE"] | |
183 | + try | |
184 | + { | |
185 | + if (valueList != null) | |
186 | + { | |
187 | + contentLength = getValue(valueList).toInt() | |
188 | + } | |
189 | + } | |
190 | + catch (ee: Exception) | |
191 | + { | |
192 | + ee.printStackTrace() | |
193 | + } | |
194 | + } | |
195 | + catch (e: Exception) | |
196 | + { | |
197 | + e.printStackTrace() | |
198 | + } | |
199 | + } | |
200 | + val buffer = ByteArray(BUFFER_SIZE) | |
201 | + var readBytes = 0 | |
202 | + var readSize = inputStream.read(buffer, 0, BUFFER_SIZE) | |
203 | + while (readSize != -1) | |
204 | + { | |
205 | + callback.onReceive(readBytes, contentLength, readSize, buffer) | |
206 | + readBytes += readSize | |
207 | + readSize = inputStream.read(buffer, 0, BUFFER_SIZE) | |
208 | + } | |
209 | + Log.v(TAG, "RECEIVED $readBytes BYTES. (contentLength : $contentLength)") | |
210 | + inputStream.close() | |
211 | + } | |
212 | + catch (e: Exception) | |
213 | + { | |
214 | + Log.w(TAG, "httpGet: exception: " + e.message) | |
215 | + e.printStackTrace() | |
216 | + callback.onErrorOccurred(e) | |
217 | + } | |
218 | + finally | |
219 | + { | |
220 | + try | |
221 | + { | |
222 | + inputStream.close() | |
223 | + } | |
224 | + catch (e: Exception) | |
225 | + { | |
226 | + e.printStackTrace() | |
227 | + } | |
228 | + } | |
229 | + } | |
230 | + catch (e: Exception) | |
231 | + { | |
232 | + Log.w(TAG, "http " + requestMethod + " " + url + " " + e.message) | |
233 | + e.printStackTrace() | |
234 | + callback.onErrorOccurred(e) | |
235 | + callback.onCompleted() | |
236 | + return | |
237 | + } | |
238 | + callback.onCompleted() | |
239 | + } | |
240 | + | |
241 | + | |
242 | + private fun getValue(valueList: List<String>): String | |
243 | + { | |
244 | + // 応答ヘッダの値切り出し用... | |
245 | + var isFirst = true | |
246 | + val values = StringBuilder() | |
247 | + for (value in valueList) | |
248 | + { | |
249 | + values.append(value) | |
250 | + if (isFirst) | |
251 | + { | |
252 | + isFirst = false | |
253 | + } | |
254 | + else | |
255 | + { | |
256 | + values.append(" ") | |
257 | + } | |
258 | + } | |
259 | + return values.toString() | |
260 | + } | |
261 | + | |
262 | + fun httpGetBitmap(url: String, setProperty: Map<String, String>?, timeoutMs: Int): Bitmap? | |
263 | + { | |
264 | + return (httpCommandBitmap(url, "GET", null, setProperty, null, timeoutMs)) | |
265 | + } | |
266 | + | |
267 | + /** | |
268 | + * | |
269 | + * | |
270 | + * | |
271 | + */ | |
272 | + fun httpPostBitmap(url: String, postData: String?, timeoutMs: Int): Bitmap? | |
273 | + { | |
274 | + return (httpCommandBitmap(url, "POST", postData, null, null, timeoutMs)) | |
275 | + } | |
276 | + | |
277 | + /** | |
278 | + * | |
279 | + * | |
280 | + * | |
281 | + */ | |
282 | + private fun httpCommandBitmap(url: String, requestMethod: String, postData: String?, setProperty: Map<String, String>?, contentType: String?, timeoutMs: Int): Bitmap? | |
283 | + { | |
284 | + //var httpConn: HttpURLConnection? = null | |
285 | + var inputStream: InputStream? = null | |
286 | + //var outputStream: OutputStream? = null | |
287 | + //var writer: OutputStreamWriter? = null | |
288 | + var bmp: Bitmap? = null | |
289 | + var timeout = timeoutMs | |
290 | + if (timeoutMs < 0) | |
291 | + { | |
292 | + timeout = DEFAULT_TIMEOUT | |
293 | + } | |
294 | + | |
295 | + // HTTP メソッドで要求を送出 | |
296 | + try | |
297 | + { | |
298 | + val httpConn = URL(url).openConnection() as HttpURLConnection | |
299 | + httpConn.requestMethod = requestMethod | |
300 | + if (setProperty != null) | |
301 | + { | |
302 | + for (key in setProperty.keys) | |
303 | + { | |
304 | + val value = setProperty[key] | |
305 | + httpConn.setRequestProperty(key, value) | |
306 | + } | |
307 | + } | |
308 | + if (contentType != null) | |
309 | + { | |
310 | + httpConn.setRequestProperty("Content-Type", contentType) | |
311 | + } | |
312 | + httpConn.connectTimeout = timeout | |
313 | + httpConn.readTimeout = timeout | |
314 | + if (postData == null) | |
315 | + { | |
316 | + httpConn.connect() | |
317 | + } | |
318 | + else | |
319 | + { | |
320 | + httpConn.doInput = true | |
321 | + httpConn.doOutput = true | |
322 | + val outputStream = httpConn.outputStream | |
323 | + val writer = OutputStreamWriter(outputStream, "UTF-8") | |
324 | + writer.write(postData) | |
325 | + writer.flush() | |
326 | + writer.close() | |
327 | + outputStream.close() | |
328 | + } | |
329 | + val responseCode = httpConn.responseCode | |
330 | + if (responseCode == HttpURLConnection.HTTP_OK) | |
331 | + { | |
332 | + inputStream = httpConn.inputStream | |
333 | + if (inputStream != null) | |
334 | + { | |
335 | + bmp = BitmapFactory.decodeStream(inputStream) | |
336 | + } | |
337 | + } | |
338 | + if (inputStream == null) | |
339 | + { | |
340 | + Log.w(TAG, "http: ($requestMethod) Response Code Error: $responseCode: $url") | |
341 | + return (null) | |
342 | + } | |
343 | + inputStream.close() | |
344 | + } | |
345 | + catch (e: Exception) | |
346 | + { | |
347 | + Log.w(TAG, "http: (" + requestMethod + ") " + url + " " + e.message) | |
348 | + e.printStackTrace() | |
349 | + return (null) | |
350 | + } | |
351 | + return (bmp) | |
352 | + } | |
353 | + | |
354 | + /** | |
355 | + * | |
356 | + * | |
357 | + * | |
358 | + */ | |
359 | + fun httpPost(url: String, postData: String?, timeoutMs: Int): String? | |
360 | + { | |
361 | + return (httpCommand(url, "POST", postData, null, null, timeoutMs)) | |
362 | + } | |
363 | + | |
364 | + /** | |
365 | + * | |
366 | + * | |
367 | + * | |
368 | + */ | |
369 | + fun httpGetWithHeader(url: String, headerMap: Map<String, String>?, contentType: String?, timeoutMs: Int): String? | |
370 | + { | |
371 | + return (httpCommand(url, "GET", null, headerMap, contentType, timeoutMs)) | |
372 | + } | |
373 | + | |
374 | + /** | |
375 | + * | |
376 | + * | |
377 | + * | |
378 | + */ | |
379 | + fun httpPostWithHeader(url: String, postData: String?, headerMap: Map<String, String>?, contentType: String?, timeoutMs: Int): String? | |
380 | + { | |
381 | + return (httpCommand(url, "POST", postData, headerMap, contentType, timeoutMs)) | |
382 | + } | |
383 | + | |
384 | + /** | |
385 | + * | |
386 | + * | |
387 | + * | |
388 | + */ | |
389 | + fun httpPutWithHeader(url: String, putData: String?, headerMap: Map<String, String>?, contentType: String?, timeoutMs: Int): String? | |
390 | + { | |
391 | + return (httpCommand(url, "PUT", putData, headerMap, contentType, timeoutMs)) | |
392 | + } | |
393 | + | |
394 | + /** | |
395 | + * | |
396 | + * | |
397 | + * | |
398 | + */ | |
399 | + fun httpPut(url: String, postData: String?, timeoutMs: Int): String? | |
400 | + { | |
401 | + return (httpCommand(url, "PUT", postData, null, null, timeoutMs)) | |
402 | + } | |
403 | + | |
404 | + /** | |
405 | + * | |
406 | + * | |
407 | + * | |
408 | + */ | |
409 | + fun httpOptions(url: String, optionsData: String?, timeoutMs: Int): String? | |
410 | + { | |
411 | + return (httpCommand(url, "OPTIONS", optionsData, null, null, timeoutMs)) | |
412 | + } | |
413 | + | |
414 | + /** | |
415 | + * | |
416 | + * | |
417 | + * | |
418 | + */ | |
419 | + private fun httpCommand(url: String, requestMethod: String, postData: String?, setProperty: Map<String, String>?, contentType: String?, timeoutMs: Int): String? | |
420 | + { | |
421 | + var inputStream: InputStream? = null | |
422 | + var timeout = timeoutMs | |
423 | + if (timeoutMs < 0) | |
424 | + { | |
425 | + timeout = DEFAULT_TIMEOUT | |
426 | + } | |
427 | + | |
428 | + // HTTP メソッドで要求を送出 | |
429 | + try | |
430 | + { | |
431 | + val httpConn = URL(url).openConnection() as HttpURLConnection | |
432 | + httpConn.requestMethod = requestMethod | |
433 | + if (setProperty != null) | |
434 | + { | |
435 | + for (key in setProperty.keys) | |
436 | + { | |
437 | + val value = setProperty[key] | |
438 | + httpConn.setRequestProperty(key, value) | |
439 | + } | |
440 | + } | |
441 | + if (contentType != null) | |
442 | + { | |
443 | + httpConn.setRequestProperty("Content-Type", contentType) | |
444 | + } | |
445 | + httpConn.connectTimeout = timeout | |
446 | + httpConn.readTimeout = timeout | |
447 | + if (postData == null) | |
448 | + { | |
449 | + httpConn.connect() | |
450 | + } | |
451 | + else | |
452 | + { | |
453 | + httpConn.doInput = true | |
454 | + httpConn.doOutput = true | |
455 | + val outputStream = httpConn.outputStream | |
456 | + val writer = OutputStreamWriter(outputStream, "UTF-8") | |
457 | + writer.write(postData) | |
458 | + writer.flush() | |
459 | + writer.close() | |
460 | + outputStream.close() | |
461 | + } | |
462 | + val responseCode = httpConn.responseCode | |
463 | + if (responseCode == HttpURLConnection.HTTP_OK) | |
464 | + { | |
465 | + inputStream = httpConn.inputStream | |
466 | + } | |
467 | + if (inputStream == null) | |
468 | + { | |
469 | + Log.w(TAG, "http $requestMethod : Response Code Error: $responseCode: $url") | |
470 | + return "" | |
471 | + } | |
472 | + } | |
473 | + catch (e: Exception) | |
474 | + { | |
475 | + Log.w(TAG, "http " + requestMethod + " : IOException: " + e.message) | |
476 | + e.printStackTrace() | |
477 | + return ("") | |
478 | + } | |
479 | + | |
480 | + // 応答の読み出し | |
481 | + return readFromInputStream(inputStream) | |
482 | + } | |
483 | + | |
484 | + private fun readFromInputStream(inputStream: InputStream?): String | |
485 | + { | |
486 | + //var reader: BufferedReader? = null | |
487 | + var replyString = "" | |
488 | + if (inputStream == null) | |
489 | + { | |
490 | + return "" | |
491 | + } | |
492 | + try | |
493 | + { | |
494 | + val responseBuf = StringBuilder() | |
495 | + val reader = BufferedReader(InputStreamReader(inputStream)) | |
496 | + var c: Int | |
497 | + while (reader.read().also { c = it } != -1) | |
498 | + { | |
499 | + responseBuf.append(c.toChar()) | |
500 | + } | |
501 | + replyString = responseBuf.toString() | |
502 | + reader.close() | |
503 | + } | |
504 | + catch (e: Exception) | |
505 | + { | |
506 | + e.printStackTrace() | |
507 | + } | |
508 | + return replyString | |
509 | + } | |
510 | + | |
511 | + interface IReceivedMessageCallback | |
512 | + { | |
513 | + fun onCompleted() | |
514 | + fun onErrorOccurred(e: Exception?) | |
515 | + fun onReceive(readBytes: Int, length: Int, size: Int, data: ByteArray?) | |
516 | + } | |
517 | + | |
518 | + companion object | |
519 | + { | |
520 | + private val TAG = SimpleHttpClient::class.java.simpleName | |
521 | + private const val DEFAULT_TIMEOUT = 10 * 1000 // [ms] | |
522 | + private const val BUFFER_SIZE = 131072 * 2 // 256kB | |
523 | + } | |
524 | +} |
@@ -0,0 +1,404 @@ | ||
1 | +package jp.sfjp.gokigen.a01c.utils; | |
2 | + | |
3 | + | |
4 | +import android.util.Log; | |
5 | + | |
6 | +import androidx.annotation.NonNull; | |
7 | + | |
8 | +import java.io.ByteArrayOutputStream; | |
9 | +import java.io.EOFException; | |
10 | +import java.io.IOException; | |
11 | +import java.io.InputStream; | |
12 | +import java.io.OutputStream; | |
13 | +import java.io.OutputStreamWriter; | |
14 | +import java.net.HttpURLConnection; | |
15 | +import java.net.URL; | |
16 | + | |
17 | +public class SimpleLiveviewSlicer | |
18 | +{ | |
19 | + private static final String TAG = SimpleLiveviewSlicer.class.getSimpleName(); | |
20 | + public static final class Payload | |
21 | + { | |
22 | + // jpeg data container | |
23 | + final byte[] jpegData; | |
24 | + | |
25 | + // padding data container | |
26 | + final byte[] paddingData; | |
27 | + | |
28 | + /** | |
29 | + * Constructor | |
30 | + */ | |
31 | + private Payload(byte[] jpeg, byte[] padding) | |
32 | + { | |
33 | + this.jpegData = jpeg; | |
34 | + this.paddingData = padding; | |
35 | + } | |
36 | + public byte[] getJpegData() | |
37 | + { | |
38 | + return (jpegData); | |
39 | + } | |
40 | + } | |
41 | + | |
42 | + private static final int CONNECTION_TIMEOUT = 2000; // [msec] | |
43 | + private int[] mJpegStartMarker = { 0x0d, 0x0a, 0x0d, 0x0a, 0xff, 0xd8 }; | |
44 | + private HttpURLConnection mHttpConn; | |
45 | + private InputStream mInputStream; | |
46 | + | |
47 | + public void setMJpegStartMarker(@NonNull int[] startMarker) | |
48 | + { | |
49 | + mJpegStartMarker = startMarker; | |
50 | + } | |
51 | + | |
52 | +/* | |
53 | + public void open(InputStream inputStream) | |
54 | + { | |
55 | + mInputStream = inputStream; | |
56 | + } | |
57 | +*/ | |
58 | + | |
59 | + public void open(String liveviewUrl, String postData, String contentType) | |
60 | + { | |
61 | + OutputStream outputStream = null; | |
62 | + OutputStreamWriter writer = null; | |
63 | + try | |
64 | + { | |
65 | + if ((mInputStream != null)||(mHttpConn != null)) | |
66 | + { | |
67 | + Log.v(TAG, "Slicer is already open."); | |
68 | + return; | |
69 | + } | |
70 | + | |
71 | + final URL urlObj = new URL(liveviewUrl); | |
72 | + mHttpConn = (HttpURLConnection) urlObj.openConnection(); | |
73 | + mHttpConn.setRequestMethod("POST"); | |
74 | + mHttpConn.setConnectTimeout(CONNECTION_TIMEOUT); | |
75 | + if (contentType != null) | |
76 | + { | |
77 | + mHttpConn.setRequestProperty("Content-Type", contentType); | |
78 | + } | |
79 | + { | |
80 | + mHttpConn.setDoInput(true); | |
81 | + mHttpConn.setDoOutput(true); | |
82 | + outputStream = mHttpConn.getOutputStream(); | |
83 | + //noinspection CharsetObjectCanBeUsed | |
84 | + writer = new OutputStreamWriter(outputStream, "UTF-8"); | |
85 | + writer.write(postData); | |
86 | + writer.flush(); | |
87 | + writer.close(); | |
88 | + writer = null; | |
89 | + outputStream.close(); | |
90 | + outputStream = null; | |
91 | + } | |
92 | + if (mHttpConn.getResponseCode() == HttpURLConnection.HTTP_OK) | |
93 | + { | |
94 | + mInputStream = mHttpConn.getInputStream(); | |
95 | + } | |
96 | + } | |
97 | + catch (Exception e) | |
98 | + { | |
99 | + e.printStackTrace(); | |
100 | + } | |
101 | + finally | |
102 | + { | |
103 | + try | |
104 | + { | |
105 | + if (writer != null) | |
106 | + { | |
107 | + writer.close(); | |
108 | + } | |
109 | + } | |
110 | + catch (Exception e) | |
111 | + { | |
112 | + e.printStackTrace(); | |
113 | + } | |
114 | + try | |
115 | + { | |
116 | + if (outputStream != null) | |
117 | + { | |
118 | + outputStream.close(); | |
119 | + } | |
120 | + } | |
121 | + catch (IOException e) | |
122 | + { | |
123 | + e.printStackTrace(); | |
124 | + } | |
125 | + } | |
126 | + } | |
127 | + | |
128 | + public void open(String liveviewUrl) | |
129 | + { | |
130 | + try | |
131 | + { | |
132 | + if ((mInputStream != null)||(mHttpConn != null)) | |
133 | + { | |
134 | + Log.v(TAG, "Slicer is already open."); | |
135 | + return; | |
136 | + } | |
137 | + | |
138 | + final URL urlObj = new URL(liveviewUrl); | |
139 | + mHttpConn = (HttpURLConnection) urlObj.openConnection(); | |
140 | + mHttpConn.setRequestMethod("GET"); | |
141 | + mHttpConn.setConnectTimeout(CONNECTION_TIMEOUT); | |
142 | + mHttpConn.connect(); | |
143 | + if (mHttpConn.getResponseCode() == HttpURLConnection.HTTP_OK) | |
144 | + { | |
145 | + mInputStream = mHttpConn.getInputStream(); | |
146 | + } | |
147 | + } | |
148 | + catch (Exception e) | |
149 | + { | |
150 | + e.printStackTrace(); | |
151 | + } | |
152 | + } | |
153 | + | |
154 | + public void close() | |
155 | + { | |
156 | + try | |
157 | + { | |
158 | + if (mInputStream != null) | |
159 | + { | |
160 | + mInputStream.close(); | |
161 | + mInputStream = null; | |
162 | + } | |
163 | + } | |
164 | + catch (Exception e) | |
165 | + { | |
166 | + e.printStackTrace(); | |
167 | + } | |
168 | + try | |
169 | + { | |
170 | + if (mHttpConn != null) | |
171 | + { | |
172 | + mHttpConn.disconnect(); | |
173 | + mHttpConn = null; | |
174 | + } | |
175 | + } | |
176 | + catch (Exception e) | |
177 | + { | |
178 | + e.printStackTrace(); | |
179 | + } | |
180 | + } | |
181 | + | |
182 | + public Payload nextPayload() | |
183 | + { | |
184 | + Payload payload = null; | |
185 | + try | |
186 | + { | |
187 | + while ((mInputStream != null)&&(payload == null)) | |
188 | + { | |
189 | + // Common Header | |
190 | + int readLength = 1 + 1 + 2 + 4; | |
191 | + byte[] commonHeader = readBytes(mInputStream, readLength); | |
192 | + if ((commonHeader == null)||(commonHeader.length != readLength)) | |
193 | + { | |
194 | + Log.v(TAG, "Cannot read stream for common header."); | |
195 | + payload = null; | |
196 | + break; | |
197 | + } | |
198 | + if (commonHeader[0] != (byte) 0xFF) | |
199 | + { | |
200 | + Log.v(TAG, "Unexpected data format. (Start byte)"); | |
201 | + payload = null; | |
202 | + break; | |
203 | + } | |
204 | + switch (commonHeader[1]) | |
205 | + { | |
206 | + case (byte) 0x12: | |
207 | + // This is information header for streaming. skip this packet. | |
208 | + readLength = 4 + 3 + 1 + 2 + 118 + 4 + 4 + 24; | |
209 | + //commonHeader = null; | |
210 | + readBytes(mInputStream, readLength); | |
211 | + break; | |
212 | + | |
213 | + case (byte) 0x01: | |
214 | + case (byte) 0x11: | |
215 | + payload = readPayload(); | |
216 | + break; | |
217 | + | |
218 | + default: | |
219 | + break; | |
220 | + } | |
221 | + } | |
222 | + } | |
223 | + catch (Exception e) | |
224 | + { | |
225 | + e.printStackTrace(); | |
226 | + System.gc(); | |
227 | + } | |
228 | + return (payload); | |
229 | + } | |
230 | + | |
231 | + private Payload readPayload() | |
232 | + { | |
233 | + try | |
234 | + { | |
235 | + if (mInputStream != null) | |
236 | + { | |
237 | + // Payload Header | |
238 | + int readLength = 4 + 3 + 1 + 4 + 1 + 115; | |
239 | + byte[] payloadHeader = readBytes(mInputStream, readLength); | |
240 | + if ((payloadHeader == null)||(payloadHeader.length != readLength)) | |
241 | + { | |
242 | + throw new EOFException("Cannot read stream for payload header."); | |
243 | + } | |
244 | + if (payloadHeader[0] != (byte) 0x24 || payloadHeader[1] != (byte) 0x35 | |
245 | + || payloadHeader[2] != (byte) 0x68 | |
246 | + || payloadHeader[3] != (byte) 0x79) | |
247 | + { | |
248 | + throw new EOFException("Unexpected data format. (Start code)"); | |
249 | + } | |
250 | + int jpegSize = bytesToInt(payloadHeader, 4, 3); | |
251 | + int paddingSize = bytesToInt(payloadHeader, 7, 1); | |
252 | + | |
253 | + // Payload Data | |
254 | + byte[] jpegData = readBytes(mInputStream, jpegSize); | |
255 | + byte[] paddingData = readBytes(mInputStream, paddingSize); | |
256 | + | |
257 | + return (new Payload(jpegData, paddingData)); | |
258 | + } | |
259 | + } | |
260 | + catch (EOFException eo) | |
261 | + { | |
262 | + eo.printStackTrace(); | |
263 | + close(); | |
264 | + } | |
265 | + catch (Exception e) | |
266 | + { | |
267 | + e.printStackTrace(); | |
268 | + } | |
269 | + return (null); | |
270 | + } | |
271 | + | |
272 | + private static int bytesToInt(byte[] byteData, int startIndex, int count) | |
273 | + { | |
274 | + int ret = 0; | |
275 | + try | |
276 | + { | |
277 | + for (int i = startIndex; i < startIndex + count; i++) | |
278 | + { | |
279 | + ret = (ret << 8) | (byteData[i] & 0xff); | |
280 | + } | |
281 | + } | |
282 | + catch (Exception e) | |
283 | + { | |
284 | + e.printStackTrace(); | |
285 | + } | |
286 | + return (ret); | |
287 | + } | |
288 | + | |
289 | + private static byte[] readBytes(InputStream in, int length) | |
290 | + { | |
291 | + byte[] ret; | |
292 | + try | |
293 | + { | |
294 | + ByteArrayOutputStream tmpByteArray = new ByteArrayOutputStream(); | |
295 | + byte[] buffer = new byte[1024]; | |
296 | + while (true) | |
297 | + { | |
298 | + int trialReadlen = Math.min(buffer.length, length - tmpByteArray.size()); | |
299 | + int readlen = in.read(buffer, 0, trialReadlen); | |
300 | + if (readlen < 0) | |
301 | + { | |
302 | + break; | |
303 | + } | |
304 | + tmpByteArray.write(buffer, 0, readlen); | |
305 | + if (length <= tmpByteArray.size()) | |
306 | + { | |
307 | + break; | |
308 | + } | |
309 | + } | |
310 | + ret = tmpByteArray.toByteArray(); | |
311 | + tmpByteArray.close(); | |
312 | + } | |
313 | + catch (Exception e) | |
314 | + { | |
315 | + e.printStackTrace(); | |
316 | + ret = null; | |
317 | + } | |
318 | + return (ret); | |
319 | + } | |
320 | + | |
321 | + /** | |
322 | + * 先頭のjpegマーカーが出てくるまで読み飛ばす | |
323 | + * | |
324 | + */ | |
325 | + private void skipJpegMarkStart(InputStream stream) | |
326 | + { | |
327 | + int searchIndex = 0; | |
328 | + while (true) | |
329 | + { | |
330 | + try | |
331 | + { | |
332 | + int data = stream.read(); | |
333 | + if (data == mJpegStartMarker[searchIndex]) | |
334 | + { | |
335 | + searchIndex++; | |
336 | + if (searchIndex >= mJpegStartMarker.length) | |
337 | + { | |
338 | + break; | |
339 | + } | |
340 | + } | |
341 | + } | |
342 | + catch (Exception e) | |
343 | + { | |
344 | + e.printStackTrace(); | |
345 | + return; | |
346 | + } | |
347 | + } | |
348 | + } | |
349 | + | |
350 | + /** | |
351 | + * | |
352 | + * | |
353 | + */ | |
354 | + public Payload nextPayloadForMotionJpeg() | |
355 | + { | |
356 | + int searchIndex = 0; | |
357 | + int[] endmarker = { 0xff, 0xd9 }; | |
358 | + Payload payload = null; | |
359 | + try | |
360 | + { | |
361 | + while ((mInputStream != null)&&(payload == null)) | |
362 | + { | |
363 | + skipJpegMarkStart(mInputStream); | |
364 | + ByteArrayOutputStream tmpByteArray = new ByteArrayOutputStream(); | |
365 | + // 先頭にJPEGのマークを詰める | |
366 | + tmpByteArray.write(0xff); | |
367 | + tmpByteArray.write(0xd8); | |
368 | + while (true) | |
369 | + { | |
370 | + try | |
371 | + { | |
372 | + // 1byteづつの読み込み... 本当は複数バイト読み出しで処理したい | |
373 | + int data = mInputStream.read(); | |
374 | + tmpByteArray.write(data); | |
375 | + if (data == endmarker[searchIndex]) | |
376 | + { | |
377 | + searchIndex++; | |
378 | + if (searchIndex >= endmarker.length) | |
379 | + { | |
380 | + break; | |
381 | + } | |
382 | + } | |
383 | + else | |
384 | + { | |
385 | + searchIndex = 0; | |
386 | + } | |
387 | + } | |
388 | + catch (Throwable e) | |
389 | + { | |
390 | + Log.v(TAG, "INPUT STREAM EXCEPTION : " + e.getLocalizedMessage()); | |
391 | + // e.printStackTrace(); | |
392 | + return (null); | |
393 | + } | |
394 | + } | |
395 | + payload = new Payload(tmpByteArray.toByteArray(), null); | |
396 | + } | |
397 | + } | |
398 | + catch (Exception e) | |
399 | + { | |
400 | + e.printStackTrace(); | |
401 | + } | |
402 | + return (payload); | |
403 | + } | |
404 | +} |
@@ -0,0 +1,78 @@ | ||
1 | +package jp.sfjp.gokigen.a01c.utils; | |
2 | + | |
3 | +import android.app.Activity; | |
4 | +import android.os.Environment; | |
5 | +import android.util.Log; | |
6 | + | |
7 | +import androidx.annotation.NonNull; | |
8 | + | |
9 | +import java.io.File; | |
10 | +import java.io.FileOutputStream; | |
11 | +import java.text.SimpleDateFormat; | |
12 | +import java.util.Calendar; | |
13 | +import java.util.Locale; | |
14 | + | |
15 | +import jp.sfjp.gokigen.a01c.R; | |
16 | + | |
17 | +public class SimpleLogDumper | |
18 | +{ | |
19 | + private static final String TAG = SimpleLogDumper.class.getSimpleName(); | |
20 | + | |
21 | + /** | |
22 | + * デバッグ用:ログにバイト列を出力する | |
23 | + * | |
24 | + */ | |
25 | + public static void dump_bytes(String header, byte[] data) | |
26 | + { | |
27 | + if (data == null) | |
28 | + { | |
29 | + Log.v(TAG, "DATA IS NULL"); | |
30 | + return; | |
31 | + } | |
32 | + if (data.length > 8192) | |
33 | + { | |
34 | + Log.v(TAG, " --- DUMP DATA IS TOO LONG... " + data.length + " bytes."); | |
35 | + return; | |
36 | + } | |
37 | + | |
38 | + int index = 0; | |
39 | + StringBuffer message; | |
40 | + message = new StringBuffer(); | |
41 | + for (byte item : data) | |
42 | + { | |
43 | + index++; | |
44 | + message.append(String.format("%02x ", item)); | |
45 | + if (index >= 16) | |
46 | + { | |
47 | + Log.v(TAG, header + " " + message); | |
48 | + index = 0; | |
49 | + message = new StringBuffer(); | |
50 | + } | |
51 | + } | |
52 | + if (index != 0) | |
53 | + { | |
54 | + Log.v(TAG, header + " " + message); | |
55 | + } | |
56 | + System.gc(); | |
57 | + } | |
58 | + | |
59 | + public static void binaryOutputToFile(@NonNull Activity activity, String fileNamePrefix, byte[] rx_body) | |
60 | + { | |
61 | + try | |
62 | + { | |
63 | + Calendar calendar = Calendar.getInstance(); | |
64 | + String extendName = new SimpleDateFormat("yyyyMMdd-HHmmss", Locale.getDefault()).format(calendar.getTime()); | |
65 | + final String directoryPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getPath() + "/" + activity.getString(R.string.app_name2) + "/"; | |
66 | + String outputFileName = fileNamePrefix + "_" + extendName + ".bin"; | |
67 | + String filepath = new File(directoryPath.toLowerCase(), outputFileName.toLowerCase()).getPath(); | |
68 | + FileOutputStream outputStream = new FileOutputStream(filepath); | |
69 | + outputStream.write(rx_body, 0, rx_body.length); | |
70 | + outputStream.flush(); | |
71 | + outputStream.close(); | |
72 | + } | |
73 | + catch (Exception e) | |
74 | + { | |
75 | + e.printStackTrace(); | |
76 | + } | |
77 | + } | |
78 | +} |
@@ -0,0 +1,183 @@ | ||
1 | +package jp.sfjp.gokigen.a01c.utils; | |
2 | + | |
3 | +import android.util.Log; | |
4 | +import android.util.Xml; | |
5 | + | |
6 | +import org.xmlpull.v1.XmlPullParser; | |
7 | +import java.io.StringReader; | |
8 | +import java.util.ArrayList; | |
9 | +import java.util.HashMap; | |
10 | +import java.util.LinkedList; | |
11 | +import java.util.List; | |
12 | +import java.util.Map; | |
13 | + | |
14 | +import androidx.annotation.NonNull; | |
15 | + | |
16 | +public class XmlElement | |
17 | +{ | |
18 | + private static final String TAG = XmlElement.class.getSimpleName(); | |
19 | + private static final XmlElement NULL_ELEMENT = new XmlElement(); | |
20 | + | |
21 | + private String tagName = ""; | |
22 | + private String tagValue; | |
23 | + | |
24 | + private final LinkedList<XmlElement> childElements; | |
25 | + private final Map<String, String> attributes; | |
26 | + private XmlElement parentElement; | |
27 | + | |
28 | + private XmlElement() | |
29 | + { | |
30 | + //Log.v(TAG, "XmlElement()"); | |
31 | + parentElement = null; | |
32 | + childElements = new LinkedList<>(); | |
33 | + attributes = new HashMap<>(); | |
34 | + tagValue = ""; | |
35 | + } | |
36 | + | |
37 | + public XmlElement getParent() | |
38 | + { | |
39 | + return (parentElement); | |
40 | + } | |
41 | + public String getTagName() | |
42 | + { | |
43 | + //Log.v(TAG, "XmlElement Tag [" + tagName + "]"); | |
44 | + return (tagName); | |
45 | + } | |
46 | + | |
47 | + private void setTagName(String name) | |
48 | + { | |
49 | + tagName = name; | |
50 | + } | |
51 | + | |
52 | + public String getValue() | |
53 | + { | |
54 | + //Log.v(TAG, "XmlElement Value [" + tagValue + "]"); | |
55 | + return (tagValue); | |
56 | + } | |
57 | + private void setValue(String value) | |
58 | + { | |
59 | + tagValue = value; | |
60 | + } | |
61 | + | |
62 | + private void putChild(XmlElement childItem) | |
63 | + { | |
64 | + childElements.add(childItem); | |
65 | + childItem.setParent(this); | |
66 | + } | |
67 | + | |
68 | + public XmlElement findChild(String name) | |
69 | + { | |
70 | + for (final XmlElement child : childElements) | |
71 | + { | |
72 | + if (child.getTagName().equals(name)) | |
73 | + { | |
74 | + return (child); | |
75 | + } | |
76 | + } | |
77 | + return (new XmlElement()); | |
78 | + } | |
79 | + | |
80 | + public List<XmlElement> findChildren(String name) | |
81 | + { | |
82 | + final List<XmlElement> tagItemList = new ArrayList<>(); | |
83 | + for (final XmlElement child : childElements) | |
84 | + { | |
85 | + if (child.getTagName().equals(name)) | |
86 | + { | |
87 | + tagItemList.add(child); | |
88 | + } | |
89 | + } | |
90 | + return (tagItemList); | |
91 | + } | |
92 | + | |
93 | + private void setParent(XmlElement parent) | |
94 | + { | |
95 | + parentElement = parent; | |
96 | + } | |
97 | + | |
98 | + private void putAttribute(String name, String value) | |
99 | + { | |
100 | + attributes.put(name, value); | |
101 | + } | |
102 | + | |
103 | + public String getAttribute(String name, String defaultValue) | |
104 | + { | |
105 | + String ret = attributes.get(name); | |
106 | + if (ret == null) | |
107 | + { | |
108 | + ret = defaultValue; | |
109 | + } | |
110 | + return (ret); | |
111 | + } | |
112 | + | |
113 | + private static XmlElement parse(XmlPullParser xmlPullParser) | |
114 | + { | |
115 | + XmlElement rootElement = XmlElement.NULL_ELEMENT; | |
116 | + try | |
117 | + { | |
118 | + XmlElement parsingElement = XmlElement.NULL_ELEMENT; | |
119 | + MAINLOOP: | |
120 | + while (true) | |
121 | + { | |
122 | + switch (xmlPullParser.next()) | |
123 | + { | |
124 | + case XmlPullParser.START_DOCUMENT: | |
125 | + Log.v(TAG, "------- START DOCUMENT -----"); | |
126 | + break; | |
127 | + case XmlPullParser.START_TAG: | |
128 | + final XmlElement childItem = new XmlElement(); | |
129 | + childItem.setTagName(xmlPullParser.getName()); | |
130 | + if (parsingElement == XmlElement.NULL_ELEMENT) { | |
131 | + rootElement = childItem; | |
132 | + } else { | |
133 | + parsingElement.putChild(childItem); | |
134 | + } | |
135 | + parsingElement = childItem; | |
136 | + | |
137 | + // Set Attribute | |
138 | + for (int i = 0; i < xmlPullParser.getAttributeCount(); i++) | |
139 | + { | |
140 | + parsingElement.putAttribute(xmlPullParser.getAttributeName(i), xmlPullParser.getAttributeValue(i)); | |
141 | + } | |
142 | + break; | |
143 | + | |
144 | + case XmlPullParser.TEXT: | |
145 | + parsingElement.setValue(xmlPullParser.getText()); | |
146 | + break; | |
147 | + | |
148 | + case XmlPullParser.END_TAG: | |
149 | + parsingElement = parsingElement.getParent(); | |
150 | + break; | |
151 | + | |
152 | + case XmlPullParser.END_DOCUMENT: | |
153 | + Log.v(TAG, "------- END DOCUMENT -------"); | |
154 | + break MAINLOOP; | |
155 | + | |
156 | + default: | |
157 | + break MAINLOOP; | |
158 | + } | |
159 | + } | |
160 | + } | |
161 | + catch (Exception e) | |
162 | + { | |
163 | + e.printStackTrace(); | |
164 | + rootElement = XmlElement.NULL_ELEMENT; | |
165 | + } | |
166 | + return (rootElement); | |
167 | + } | |
168 | + | |
169 | + public static XmlElement parse(@NonNull String xmlStr) | |
170 | + { | |
171 | + try | |
172 | + { | |
173 | + XmlPullParser xmlPullParser = Xml.newPullParser(); | |
174 | + xmlPullParser.setInput(new StringReader(xmlStr)); | |
175 | + return parse(xmlPullParser); | |
176 | + } | |
177 | + catch (Exception e) | |
178 | + { | |
179 | + e.printStackTrace(); | |
180 | + } | |
181 | + return (new XmlElement()); | |
182 | + } | |
183 | +} |
@@ -1,6 +1,7 @@ | ||
1 | 1 | <?xml version="1.0" encoding="utf-8"?> |
2 | 2 | <resources> |
3 | 3 | <string name="app_name">A01c</string> |
4 | + <string name="app_name2">A01c</string> | |
4 | 5 | <string name="hello_round">Hello Round World!</string> |
5 | 6 | <string name="hello_square">Hello Square World</string> |
6 | 7 |
@@ -70,4 +71,7 @@ | ||
70 | 71 | <string name="change_title_from_theta_to_opc">OPCに接続</string> |
71 | 72 | <string name="change_message_from_theta_to_opc">接続方式をOPCにしますか?</string> |
72 | 73 | |
74 | + <string name="connection_method_opc">OPC</string> | |
75 | + <string name="connection_method_theta">THETA</string> | |
76 | + | |
73 | 77 | </resources> |
@@ -1,5 +1,6 @@ | ||
1 | 1 | <resources> |
2 | 2 | <string name="app_name">A01c</string> |
3 | + <string name="app_name2">A01c</string> | |
3 | 4 | <string name="hello_round">Hello Round World!</string> |
4 | 5 | <string name="hello_square">Hello Square World!</string> |
5 | 6 |
@@ -68,4 +69,7 @@ | ||
68 | 69 | <string name="change_title_from_theta_to_opc">Change To OPC</string> |
69 | 70 | <string name="change_message_from_theta_to_opc">Change To OPC, OK?</string> |
70 | 71 | |
72 | + <string name="connection_method_opc">OPC</string> | |
73 | + <string name="connection_method_theta">THETA</string> | |
74 | + | |
71 | 75 | </resources> |