BLE通信を行うためのアプリ。
Révision | 38d36c1a2911b2e0f6cd708b3dd0f428066cda81 (tree) |
---|---|
l'heure | 2020-04-07 23:30:28 |
Auteur | MRSa <mrsa@myad...> |
Commiter | MRSa |
サマリーデータについて、ロギング(ファイル出力)できるようにした。
@@ -8,10 +8,10 @@ import android.util.Log; | ||
8 | 8 | import androidx.annotation.NonNull; |
9 | 9 | import androidx.fragment.app.FragmentActivity; |
10 | 10 | |
11 | -import net.osdn.gokigen.blecontrol.lib.SimpleLogDumper; | |
12 | 11 | import net.osdn.gokigen.blecontrol.lib.ble.R; |
13 | 12 | import net.osdn.gokigen.blecontrol.lib.ble.connect.BleDeviceFinder; |
14 | 13 | import net.osdn.gokigen.blecontrol.lib.ble.connect.ITextDataUpdater; |
14 | +import net.osdn.gokigen.blecontrol.lib.data.brainwave.BrainwaveFileLogger; | |
15 | 15 | import net.osdn.gokigen.blecontrol.lib.data.brainwave.IBrainwaveDataReceiver; |
16 | 16 | |
17 | 17 | import java.io.ByteArrayOutputStream; |
@@ -27,7 +27,9 @@ public class MindWaveCommunication implements BleDeviceFinder.BleScanResult | ||
27 | 27 | private final ITextDataUpdater dataUpdater; |
28 | 28 | private final IBrainwaveDataReceiver dataReceiver; |
29 | 29 | private BleDeviceFinder deviceFinder = null; |
30 | + private BrainwaveFileLogger fileLogger = null; | |
30 | 31 | private boolean foundDevice = false; |
32 | + private boolean loggingFlag = false; | |
31 | 33 | |
32 | 34 | public MindWaveCommunication(@NonNull FragmentActivity context, @NonNull ITextDataUpdater dataUpdater, @NonNull IBrainwaveDataReceiver dataReceiver) |
33 | 35 | { |
@@ -40,12 +42,13 @@ public class MindWaveCommunication implements BleDeviceFinder.BleScanResult | ||
40 | 42 | } |
41 | 43 | } |
42 | 44 | |
43 | - public void connect(@NonNull String deviceName) | |
45 | + public void connect(@NonNull String deviceName, boolean loggingFlag) | |
44 | 46 | { |
45 | - Log.v(TAG, " BrainWaveMobileCommunicator::connect() : " + deviceName); | |
46 | - setText(context.getString(R.string.start_query) + " '" + deviceName + "' "); | |
47 | + Log.v(TAG, " BrainWaveMobileCommunicator::connect() : " + deviceName + " Logging : " + loggingFlag); | |
48 | + setText(context.getString(R.string.start_query) + " '" + deviceName + "'"); | |
47 | 49 | try |
48 | 50 | { |
51 | + this.loggingFlag = loggingFlag; | |
49 | 52 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) |
50 | 53 | { |
51 | 54 | // BLE のサービスを取得 |
@@ -79,8 +82,6 @@ public class MindWaveCommunication implements BleDeviceFinder.BleScanResult | ||
79 | 82 | dataUpdater.addText(message); |
80 | 83 | } |
81 | 84 | |
82 | - | |
83 | - | |
84 | 85 | private void parseReceivedData(byte[] data) |
85 | 86 | { |
86 | 87 | // 受信データブロック1つ分 |
@@ -109,7 +110,11 @@ public class MindWaveCommunication implements BleDeviceFinder.BleScanResult | ||
109 | 110 | return; |
110 | 111 | } |
111 | 112 | dataReceiver.receivedSummaryData(data); |
112 | - //SimpleLogDumper.dump_bytes("RECV SPP [" + data.length + "] ", data); | |
113 | + if (fileLogger != null) | |
114 | + { | |
115 | + // ファイルにサマリーデータを出力する | |
116 | + fileLogger.outputSummaryData(data); | |
117 | + } | |
113 | 118 | } |
114 | 119 | catch (Exception e) |
115 | 120 | { |
@@ -136,6 +141,19 @@ public class MindWaveCommunication implements BleDeviceFinder.BleScanResult | ||
136 | 141 | return; |
137 | 142 | } |
138 | 143 | |
144 | + if (loggingFlag) | |
145 | + { | |
146 | + try | |
147 | + { | |
148 | + // ログ出力を指示されていた場合...ファイル出力クラスを作成しておく | |
149 | + fileLogger = new BrainwaveFileLogger(context); | |
150 | + } | |
151 | + catch (Exception e) | |
152 | + { | |
153 | + e.printStackTrace(); | |
154 | + } | |
155 | + } | |
156 | + | |
139 | 157 | // シリアルデータの受信メイン部分 |
140 | 158 | byte previousData = (byte) 0xff; |
141 | 159 | ByteArrayOutputStream outputStream = null; |
@@ -81,6 +81,11 @@ public class BrainwaveDataHolder implements IBrainwaveDataReceiver | ||
81 | 81 | { |
82 | 82 | return (Arrays.copyOfRange(valueBuffer, 0, endPosition)); |
83 | 83 | } |
84 | + if (currentPosition == 0) | |
85 | + { | |
86 | + endPosition = (maxBufferSize - 1); | |
87 | + return (Arrays.copyOfRange(valueBuffer, (endPosition - size), endPosition)); | |
88 | + } | |
84 | 89 | |
85 | 90 | int remainSize = size - (currentPosition - 1); |
86 | 91 | int [] size0 = Arrays.copyOfRange(valueBuffer, 0, (currentPosition - 1)); |
@@ -88,8 +93,8 @@ public class BrainwaveDataHolder implements IBrainwaveDataReceiver | ||
88 | 93 | |
89 | 94 | replyData = new int[size]; |
90 | 95 | |
91 | - System.arraycopy(size0, 0, replyData, 0, size0.length); | |
92 | - System.arraycopy(size1, 0, replyData, size0.length, size1.length); | |
96 | + System.arraycopy(size1, 0, replyData, 0, size1.length); | |
97 | + System.arraycopy(size0, 0, replyData, size1.length, size0.length); | |
93 | 98 | } |
94 | 99 | catch (Exception e) |
95 | 100 | { |
@@ -0,0 +1,56 @@ | ||
1 | +package net.osdn.gokigen.blecontrol.lib.data.brainwave; | |
2 | + | |
3 | +import android.os.Environment; | |
4 | + | |
5 | +import androidx.annotation.NonNull; | |
6 | +import androidx.fragment.app.FragmentActivity; | |
7 | + | |
8 | +import net.osdn.gokigen.blecontrol.lib.SimpleLogDumper; | |
9 | +import net.osdn.gokigen.blecontrol.lib.ble.R; | |
10 | + | |
11 | +import java.io.File; | |
12 | +import java.io.FileOutputStream; | |
13 | +import java.text.SimpleDateFormat; | |
14 | +import java.util.Calendar; | |
15 | +import java.util.Locale; | |
16 | + | |
17 | +public class BrainwaveFileLogger | |
18 | +{ | |
19 | + private FileOutputStream outputStream; | |
20 | + | |
21 | + public BrainwaveFileLogger(@NonNull FragmentActivity context) | |
22 | + { | |
23 | + try | |
24 | + { | |
25 | + String fileNamePrefix = context.getString(R.string.app_name2) + "_EEG"; | |
26 | + Calendar calendar = Calendar.getInstance(); | |
27 | + String extendName = new SimpleDateFormat("yyyyMMdd-HHmmss", Locale.getDefault()).format(calendar.getTime()); | |
28 | + final String directoryPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath() + "/"; | |
29 | + String outputFileName = fileNamePrefix + "_" + extendName + ".bin"; | |
30 | + String filepath = new File(directoryPath.toLowerCase(), outputFileName.toLowerCase()).getPath(); | |
31 | + outputStream = new FileOutputStream(filepath); | |
32 | + } | |
33 | + catch (Exception e) | |
34 | + { | |
35 | + e.printStackTrace(); | |
36 | + outputStream = null; | |
37 | + } | |
38 | + } | |
39 | + | |
40 | + public void outputSummaryData(byte[] data) | |
41 | + { | |
42 | + try | |
43 | + { | |
44 | + SimpleLogDumper.dump_bytes("RECV [" + data.length + "] ", data); | |
45 | + if ((outputStream != null)&&(data.length >= 36)) | |
46 | + { | |
47 | + outputStream.write(data, 0, 36); | |
48 | + outputStream.flush(); | |
49 | + } | |
50 | + } | |
51 | + catch (Exception e) | |
52 | + { | |
53 | + e.printStackTrace(); | |
54 | + } | |
55 | + } | |
56 | +} |
@@ -3,6 +3,7 @@ package net.osdn.gokigen.blecontrol.lib.ui.brainwave; | ||
3 | 3 | import android.util.Log; |
4 | 4 | import android.view.View; |
5 | 5 | import android.widget.ImageButton; |
6 | +import android.widget.Switch; | |
6 | 7 | |
7 | 8 | import androidx.annotation.NonNull; |
8 | 9 | import androidx.annotation.Nullable; |
@@ -22,14 +23,16 @@ public class BrainwaveConnection implements View.OnClickListener, ITextDataUpdat | ||
22 | 23 | private final BrainwaveMobileViewModel viewModel; |
23 | 24 | private final MindWaveCommunication communicator; |
24 | 25 | private final SnackBarMessage messageToShow; |
26 | + private final Switch loggingSwitch; | |
25 | 27 | |
26 | - BrainwaveConnection(@NonNull FragmentActivity context, @NonNull SelectDevice deviceSelection, @NonNull BrainwaveMobileViewModel viewModel, @NonNull IBrainwaveDataReceiver dataReceiver) | |
28 | + BrainwaveConnection(@NonNull FragmentActivity context, @NonNull SelectDevice deviceSelection, @NonNull BrainwaveMobileViewModel viewModel, @NonNull IBrainwaveDataReceiver dataReceiver, @Nullable Switch loggingSwitch) | |
27 | 29 | { |
28 | 30 | this.context = context; |
29 | 31 | this.deviceSelection = deviceSelection; |
30 | 32 | this.viewModel = viewModel; |
31 | 33 | this.communicator = new MindWaveCommunication(context, this, dataReceiver); |
32 | 34 | this.messageToShow = new SnackBarMessage(context, false); |
35 | + this.loggingSwitch = loggingSwitch; | |
33 | 36 | } |
34 | 37 | |
35 | 38 | @Override |
@@ -50,18 +53,24 @@ public class BrainwaveConnection implements View.OnClickListener, ITextDataUpdat | ||
50 | 53 | |
51 | 54 | private void connectToEEG(@Nullable final String selectedDevice) |
52 | 55 | { |
56 | + boolean logging = false; | |
53 | 57 | if (selectedDevice == null) |
54 | 58 | { |
55 | 59 | Log.v(TAG, " DEVICE is NULL."); |
56 | 60 | return; |
57 | 61 | } |
62 | + if (loggingSwitch != null) | |
63 | + { | |
64 | + logging = loggingSwitch.isChecked(); | |
65 | + } | |
58 | 66 | try |
59 | 67 | { |
68 | + final boolean loggingFlag = logging; | |
60 | 69 | Log.v(TAG, " CONNECT TO EEG. : " + selectedDevice); |
61 | 70 | Thread thread = new Thread(new Runnable() { |
62 | 71 | @Override |
63 | 72 | public void run() { |
64 | - communicator.connect(selectedDevice); | |
73 | + communicator.connect(selectedDevice, loggingFlag); | |
65 | 74 | } |
66 | 75 | }); |
67 | 76 | thread.start(); |
@@ -10,6 +10,7 @@ import android.widget.AdapterView; | ||
10 | 10 | import android.widget.ArrayAdapter; |
11 | 11 | import android.widget.Button; |
12 | 12 | import android.widget.Spinner; |
13 | +import android.widget.Switch; | |
13 | 14 | import android.widget.TextView; |
14 | 15 | |
15 | 16 | import androidx.annotation.Nullable; |
@@ -55,7 +56,8 @@ public class BrainwaveMobileFragment extends Fragment implements BrainwaveConnec | ||
55 | 56 | prepareDeviceSelection(context, root); |
56 | 57 | |
57 | 58 | // Connect Button |
58 | - final BrainwaveConnection eegConnection = new BrainwaveConnection(context, this, brainwaveViewModel, dataHolder); | |
59 | + final Switch loggingSwitch = root.findViewById(R.id.switch_logging); | |
60 | + final BrainwaveConnection eegConnection = new BrainwaveConnection(context, this, brainwaveViewModel, dataHolder, loggingSwitch); | |
59 | 61 | final Button queryButton = root.findViewById(R.id.connect_to_eeg); |
60 | 62 | if (queryButton != null) |
61 | 63 | { |
@@ -75,6 +75,26 @@ | ||
75 | 75 | app:srcCompat="@drawable/ic_texture_black_24dp" |
76 | 76 | android:visibility="invisible" /> |
77 | 77 | |
78 | + <TextView | |
79 | + android:id="@+id/label_logging" | |
80 | + android:layout_width="wrap_content" | |
81 | + android:layout_height="wrap_content" | |
82 | + android:layout_gravity="center_horizontal" | |
83 | + android:textAlignment="center" | |
84 | + android:layout_marginRight="4sp" | |
85 | + android:layout_marginEnd="4sp" | |
86 | + android:text="@string/label_logging" | |
87 | + android:textSize="8pt" /> | |
88 | + | |
89 | + <Switch | |
90 | + android:id="@+id/switch_logging" | |
91 | + android:layout_width="wrap_content" | |
92 | + android:layout_height="wrap_content" | |
93 | + android:layout_gravity="center_horizontal" | |
94 | + android:textAlignment="center" | |
95 | + android:layout_marginRight="4sp" | |
96 | + android:layout_marginEnd="4sp" | |
97 | + /> | |
78 | 98 | </LinearLayout> |
79 | 99 | |
80 | 100 | <View |
@@ -72,4 +72,5 @@ | ||
72 | 72 | <string name="value_title_midGamma">mid Gamma(41–49.75Hz): </string> |
73 | 73 | <string name="value_title_attention">Attention: </string> |
74 | 74 | <string name="value_title_mediation">Mediation: </string> |
75 | + <string name="label_logging"> Logging</string> | |
75 | 76 | </resources> |
@@ -71,4 +71,5 @@ | ||
71 | 71 | <string name="value_title_midGamma">mid Gamma(41–49.75Hz): </string> |
72 | 72 | <string name="value_title_attention">Attention: </string> |
73 | 73 | <string name="value_title_mediation">Mediation: </string> |
74 | + <string name="label_logging"> Logging</string> | |
74 | 75 | </resources> |