• R/O
  • HTTP
  • SSH
  • HTTPS

A01c: Commit

OPC(Olympus Air)用撮影アプリ。


Commit MetaInfo

Revisãof20bdfdf408863985be14a9a428b1c4af6726464 (tree)
Hora2021-01-10 00:34:11
AutorMRSa <mrsa@myad...>
CommiterMRSa

Mensagem de Log

ConnectionMethodの違いで背景画像を変更した。

Mudança Sumário

Diff

--- a/wear/src/main/java/jp/sfjp/gokigen/a01c/MainActivity.java
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/MainActivity.java
@@ -821,7 +821,6 @@ public class MainActivity extends AppCompatActivity implements IChangeScene, IS
821821 {
822822 liveView.hideDialog();
823823 listener.setEnableOperation(operation.ENABLE);
824-
825824 }
826825 }
827826 catch (Exception e)
@@ -830,6 +829,20 @@ public class MainActivity extends AppCompatActivity implements IChangeScene, IS
830829 }
831830 }
832831
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+
833846 private void updateConnectionMethod(String parameter, ICameraController method)
834847 {
835848 try
@@ -845,7 +858,7 @@ public class MainActivity extends AppCompatActivity implements IChangeScene, IS
845858 }
846859
847860 /**
848- * 接続方式を変更するか確認する
861+ * 接続方式を変更するか確認する (OPC ⇔ THETA)
849862 *
850863 */
851864 private void changeConnectionMethod()
@@ -882,6 +895,7 @@ public class MainActivity extends AppCompatActivity implements IChangeScene, IS
882895 // 接続方式を Theta に切り替える
883896 updateConnectionMethod(IPreferenceCameraPropertyAccessor.CONNECTION_METHOD_THETA, olyAirCoordinator); // thetaCoordinator
884897 }
898+ updateConnectionMethodMessage();
885899 }
886900 });
887901 }
--- a/wear/src/main/java/jp/sfjp/gokigen/a01c/liveview/CameraLiveImageView.java
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/liveview/CameraLiveImageView.java
@@ -120,7 +120,20 @@ public class CameraLiveImageView extends View implements IImageDataReceiver, IAu
120120 // ダミーのビットマップデータ読み込み...画面表示のテスト用ロジック
121121 try
122122 {
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);
124137 }
125138 catch (Throwable t)
126139 {
--- /dev/null
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/utils/SimpleHttpClient.kt
@@ -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+}
--- /dev/null
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/utils/SimpleLiveviewSlicer.java
@@ -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+}
--- /dev/null
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/utils/SimpleLogDumper.java
@@ -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+}
--- /dev/null
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/utils/XmlElement.java
@@ -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+}
--- a/wear/src/main/res/values-ja/strings.xml
+++ b/wear/src/main/res/values-ja/strings.xml
@@ -1,6 +1,7 @@
11 <?xml version="1.0" encoding="utf-8"?>
22 <resources>
33 <string name="app_name">A01c</string>
4+ <string name="app_name2">A01c</string>
45 <string name="hello_round">Hello Round World!</string>
56 <string name="hello_square">Hello Square World</string>
67
@@ -70,4 +71,7 @@
7071 <string name="change_title_from_theta_to_opc">OPCに接続</string>
7172 <string name="change_message_from_theta_to_opc">接続方式をOPCにしますか?</string>
7273
74+ <string name="connection_method_opc">OPC</string>
75+ <string name="connection_method_theta">THETA</string>
76+
7377 </resources>
--- a/wear/src/main/res/values/strings.xml
+++ b/wear/src/main/res/values/strings.xml
@@ -1,5 +1,6 @@
11 <resources>
22 <string name="app_name">A01c</string>
3+ <string name="app_name2">A01c</string>
34 <string name="hello_round">Hello Round World!</string>
45 <string name="hello_square">Hello Square World!</string>
56
@@ -68,4 +69,7 @@
6869 <string name="change_title_from_theta_to_opc">Change To OPC</string>
6970 <string name="change_message_from_theta_to_opc">Change To OPC, OK?</string>
7071
72+ <string name="connection_method_opc">OPC</string>
73+ <string name="connection_method_theta">THETA</string>
74+
7175 </resources>
Show on old repository browser