diff --git a/Application/Application.iml b/Application/Application.iml index f1f0492..462e25c 100644 --- a/Application/Application.iml +++ b/Application/Application.iml @@ -106,6 +106,8 @@ + + diff --git a/Application/build.gradle b/Application/build.gradle index 64f61ee..b921280 100644 --- a/Application/build.gradle +++ b/Application/build.gradle @@ -20,6 +20,7 @@ dependencies { compile "com.android.support:cardview-v7:25.3.1" compile "com.android.support:appcompat-v7:25.3.1" compile 'com.android.support:support-v13:25.3.1' + compile 'com.android.support.constraint:constraint-layout:1.0.2' } // The sample build uses multiple directories to @@ -35,7 +36,7 @@ android { buildToolsVersion "25.0.2" defaultConfig { - minSdkVersion 13 + minSdkVersion 14 targetSdkVersion 25 } diff --git a/Application/src/main/java/org/surfsite/iconsole/BluetoothChatFragment.java b/Application/src/main/java/org/surfsite/iconsole/BluetoothChatFragment.java index 6c1f78f..e594ca1 100644 --- a/Application/src/main/java/org/surfsite/iconsole/BluetoothChatFragment.java +++ b/Application/src/main/java/org/surfsite/iconsole/BluetoothChatFragment.java @@ -39,6 +39,7 @@ import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; +import android.widget.NumberPicker; import android.widget.TextView; import android.widget.Toast; @@ -60,11 +61,11 @@ public class BluetoothChatFragment extends Fragment { private static final int REQUEST_ENABLE_BT = 3; // Layout Views - private ListView mConversationView; + //private ListView mConversationView; private Button mStartButton; private Button mStopButton; private Button mDisconnectButton; - + private NumberPicker mLevel; /** * Name of the connected device */ @@ -72,8 +73,8 @@ public class BluetoothChatFragment extends Fragment { /** * Array adapter for the conversation thread - */ private ArrayAdapter mConversationArrayAdapter; + */ /** * Local Bluetooth adapter @@ -147,10 +148,16 @@ public class BluetoothChatFragment extends Fragment { @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { - mConversationView = (ListView) view.findViewById(R.id.in); + //mConversationView = (ListView) view.findViewById(R.id.in); mStartButton = (Button) view.findViewById(R.id.button_start); mStopButton = (Button) view.findViewById(R.id.button_stop); mDisconnectButton = (Button) view.findViewById(R.id.button_disconnect); + mLevel = (NumberPicker) view.findViewById(R.id.Level); + mLevel.setMaxValue(16); + mLevel.setMinValue(1); + mLevel.setValue(5); + mLevel.setWrapSelectorWheel(false); + mLevel.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS); } /** @@ -158,11 +165,12 @@ public class BluetoothChatFragment extends Fragment { */ private void setupChat() { Log.d(TAG, "setupChat()"); - +/* // Initialize the array adapter for the conversation thread mConversationArrayAdapter = new ArrayAdapter<>(getActivity(), R.layout.message); mConversationView.setAdapter(mConversationArrayAdapter); +*/ // Initialize the BluetoothChatService to perform bluetooth connections mChatService = new BluetoothChatService(getActivity(), mHandler); @@ -263,7 +271,7 @@ public class BluetoothChatFragment extends Fragment { switch (msg.arg1) { case BluetoothChatService.STATE_CONNECTED: setStatus(getString(R.string.title_connected_to, mConnectedDeviceName)); - mConversationArrayAdapter.clear(); + //mConversationArrayAdapter.clear(); mStartButton.setEnabled(true); mStopButton.setEnabled(true); mDisconnectButton.setEnabled(true); @@ -285,22 +293,26 @@ public class BluetoothChatFragment extends Fragment { break; case Constants.MESSAGE_DATA: IConsole.Data data = (IConsole.Data) msg.obj; - String dataMessage = String.format(Locale.US, "Time: %s Speed: %f Power: %f RPM: %d LVL: %d Dist: %f Cal: %d HF: %d", + // FIXME + // insert text here + /* + String dataMessage = String.format(Locale.US, "Time: %d Speed: %3.1f Power: %3.1f RPM: %d LVL: %d Dist: %4.1f Cal: %d HF: %d", data.mTime, data.mSpeed10 / 10.0, data.mPower10 / 10.0, data.mRPM, data.mLevel, data.mDistance10 / 10.0, data.mCalories, data.mHF); - mConversationArrayAdapter.add(mConnectedDeviceName + ": " + dataMessage); + */ + //mConversationArrayAdapter.add(mConnectedDeviceName + ": " + dataMessage); break; case Constants.MESSAGE_WRITE: - byte[] writeBuf = (byte[]) msg.obj; + //byte[] writeBuf = (byte[]) msg.obj; // construct a string from the buffer - String writeMessage = new String(writeBuf); - mConversationArrayAdapter.add("Me: " + writeMessage); + //String writeMessage = new String(writeBuf); + //mConversationArrayAdapter.add("Me: " + writeMessage); break; case Constants.MESSAGE_READ: - byte[] readBuf = (byte[]) msg.obj; + //byte[] readBuf = (byte[]) msg.obj; // construct a string from the valid bytes in the buffer - String readMessage = new String(readBuf, 0, msg.arg1); - mConversationArrayAdapter.add(mConnectedDeviceName + ": " + readMessage); + //String readMessage = new String(readBuf, 0, msg.arg1); + //mConversationArrayAdapter.add(mConnectedDeviceName + ": " + readMessage); break; case Constants.MESSAGE_DEVICE_NAME: // save the connected device's name diff --git a/Application/src/main/java/org/surfsite/iconsole/BluetoothChatService.java b/Application/src/main/java/org/surfsite/iconsole/BluetoothChatService.java index 73f038f..c04b84c 100644 --- a/Application/src/main/java/org/surfsite/iconsole/BluetoothChatService.java +++ b/Application/src/main/java/org/surfsite/iconsole/BluetoothChatService.java @@ -208,7 +208,7 @@ public class BluetoothChatService { } public synchronized boolean stopIConsole() { - return mConnectedThread.startIConsole(); + return mConnectedThread.stopIConsole(); } /** @@ -345,7 +345,7 @@ public class BluetoothChatService { mmIConsole = new IConsole(mmInStream, mmOutStream, new IConsole.DataListener() { @Override public void onData(IConsole.Data data) { - Log.i(TAG, "mConnectedThread: onData"); + //Log.i(TAG, "mConnectedThread: onData"); // Share the sent message back to the UI Activity mHandler.obtainMessage(Constants.MESSAGE_DATA, -1, -1, data) .sendToTarget(); @@ -358,11 +358,11 @@ public class BluetoothChatService { if (e instanceof IOException) connectionLost(); } - }, new IConsole.DebugListener() { + }, /* new IConsole.DebugListener() { @Override public void onRead(byte[] buffer) { if (buffer.length > 0) { - String hexbuf = IConsole.byteArrayToHex(Arrays.copyOfRange(buffer, 0, buffer.length)); + String hexbuf = IConsole.byteArrayToHex(buffer); // Send the obtained bytes to the UI Activity mHandler.obtainMessage(Constants.MESSAGE_READ, hexbuf.length(), -1, hexbuf.getBytes()) @@ -378,23 +378,24 @@ public class BluetoothChatService { mHandler.obtainMessage(Constants.MESSAGE_WRITE, -1, -1, hexbuf.getBytes()) .sendToTarget(); } - }); + }*/ null); } public void run() { Log.i(TAG, "BEGIN mConnectedThread"); - mmIConsole.start(); - while (mState == STATE_CONNECTED) { - if (!mmIConsole.processIO()) + if (!mmIConsole.processIO()) { + Log.i(TAG, "processIO = false"); break; + } try { Thread.sleep(100); } catch (InterruptedException e) { ; // ignore } } + Log.i(TAG, "END mConnectedThread"); } diff --git a/Application/src/main/java/org/surfsite/iconsole/IConsole.java b/Application/src/main/java/org/surfsite/iconsole/IConsole.java index 9a853e2..fe3b1a2 100644 --- a/Application/src/main/java/org/surfsite/iconsole/IConsole.java +++ b/Application/src/main/java/org/surfsite/iconsole/IConsole.java @@ -4,13 +4,17 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Arrays; +import java.util.Locale; import java.util.concurrent.TimeoutException; +import org.surfsite.iconsole.common.logger.Log; /** * Created by harald on 25.04.17. */ class IConsole { + private static final String TAG = "IConsole"; + private static final byte[] PING = {(byte) 0xf0, (byte) 0xa0, (byte) 0x01, (byte) 0x01, (byte) 0x92 }; private static final byte[] INIT_A0 = {(byte) 0xf0, (byte) 0xa0, 0x02, 0x02, (byte) 0x94}; //private static final byte[] PONG = {(byte) 0xf0, (byte) 0xb0, 0x01, 0x01, (byte) 0xa2}; @@ -126,7 +130,7 @@ class IConsole { boolean send(byte[] packet, byte expect, int plen) throws IOException { long now = System.currentTimeMillis(); - if ((now - mTimesent) < 200) { + if ((now - mTimesent) < ((mCurrentState == State.READ) ? 500 : 200)) { return false; } @@ -140,11 +144,12 @@ class IConsole { // Send packet mOutputStream.write(packet); - if (null != mDataListener) + if (null != mDebugListener) mDebugListener.onWrite(packet); + //Log.d(TAG, "sent: " + byteArrayToHex(packet)); mTimesent = System.currentTimeMillis(); - mExpectPacket = packet; + mExpectPacket = packet.clone(); mExpectPacket[1] = expect; mExpectLen = plen; mWaitAck = true; @@ -172,18 +177,24 @@ class IConsole { long now = System.currentTimeMillis(); - if ((now - mTimesent) > 1000000) { + if ((now - mTimesent) > 10000) { mWaitAck = false; return null; } - if (mInputStream.available() < mExpectLen) + if (mInputStream.available() < mExpectLen) { + //Log.d(TAG, String.format(Locale.US, "Avail: %d Expected: %d", mInputStream.available(), mExpectLen)); return null; + } bytes = mInputStream.read(buffer); - if (null != mDebugListener) + if (null != mDebugListener) { mDebugListener.onRead(Arrays.copyOfRange(buffer, 0, bytes)); + //Log.d(TAG, "wait ack got: " + byteArrayToHex(Arrays.copyOfRange(buffer, 0, bytes))); + } + + //Log.d(TAG, "wait ack checking"); if (bytes != mExpectLen) { throw new IOException("Wrong number of bytes read. Expected " + mExpectLen + ", got " + bytes); @@ -197,13 +208,16 @@ class IConsole { throw new IOException("Byte 1 wrong. Expected " + String.format("%02x", mExpectPacket[1]) + ", got " + String.format("%02x", buffer[1])); } + //Log.d(TAG, "wait ack success"); + mWaitAck = false; + return buffer; } private boolean processIOSend() throws IOException { switch (mCurrentState) { case BEGIN: - mCurrentState = mNextState; + send(PING); break; case PING: send(PING); @@ -230,7 +244,7 @@ class IConsole { send(STOP); break; case READ: - send(READ); + send(READ, 21); break; case SETLEVEL: send_level(mSetLevel); @@ -242,8 +256,11 @@ class IConsole { private boolean processIOAck() throws IOException, TimeoutException { byte[] got = null; got = wait_ack(); - if (null == got) + if (null == got) { return true; + } + + //Log.d(TAG, "processIOAck next state"); if(mCurrentState == State.READ) mDataListener.onData(new Data(got)); @@ -288,14 +305,19 @@ class IConsole { } boolean processIO() { + //Log.i(TAG, "Begin processIO"); + synchronized (this) { try { - if (! mWaitAck) { + if (!mWaitAck) { + //Log.i(TAG, "processIOSend"); return processIOSend(); } else { + //Log.i(TAG, "processIOAck"); return processIOAck(); } } catch (Exception e) { + Log.e(TAG, "processIO", e); mDataListener.onError(e); return false; } diff --git a/Application/src/main/java/org/surfsite/iconsole/MainActivity.java b/Application/src/main/java/org/surfsite/iconsole/MainActivity.java index 1b15d65..d817740 100644 --- a/Application/src/main/java/org/surfsite/iconsole/MainActivity.java +++ b/Application/src/main/java/org/surfsite/iconsole/MainActivity.java @@ -74,6 +74,7 @@ public class MainActivity extends SampleActivityBase { @Override public boolean onOptionsItemSelected(MenuItem item) { + /* switch(item.getItemId()) { case R.id.menu_toggle_log: mLogShown = !mLogShown; @@ -86,6 +87,7 @@ public class MainActivity extends SampleActivityBase { supportInvalidateOptionsMenu(); return true; } + */ return super.onOptionsItemSelected(item); } diff --git a/Application/src/main/res/layout/activity_main.xml b/Application/src/main/res/layout/activity_main.xml index a61c44d..9d1bf13 100755 --- a/Application/src/main/res/layout/activity_main.xml +++ b/Application/src/main/res/layout/activity_main.xml @@ -20,35 +20,19 @@ android:layout_height="match_parent" android:id="@+id/sample_main_layout"> - - - - - - - + - + - - - + android:layout_marginBottom="16dp" + android:layout_marginLeft="16dp" + android:layout_marginTop="16dp" + android:gravity="center" + android:text="@string/time_n00_00_00" + android:textAlignment="center" + app:layout_constraintBottom_toTopOf="@+id/guideline5" + app:layout_constraintLeft_toLeftOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintVertical_bias="0.513" + android:layout_marginRight="16dp" + app:layout_constraintRight_toRightOf="parent" /> -