Autoconnect. Connection in separate thread. Reconnection on error. UI

improvements
This commit is contained in:
estevez
2017-12-25 23:56:25 +02:00
parent ac8866ff73
commit 195b120e8b
5 changed files with 160 additions and 73 deletions

View File

@ -6,9 +6,8 @@
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/ic_launcher" android:icon="@drawable/icon"
android:label="@string/app_name" android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme"> android:theme="@style/AppTheme">
<activity android:name=".MainActivity" android:configChanges="orientation" <activity android:name=".MainActivity" android:configChanges="orientation"

View File

@ -8,6 +8,7 @@ import android.support.v7.app.AppCompatActivity;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.ImageView;
import android.widget.SeekBar; import android.widget.SeekBar;
import android.widget.TextView; import android.widget.TextView;
@ -20,7 +21,7 @@ import java.util.UUID;
public class MainActivity extends AppCompatActivity { public class MainActivity extends AppCompatActivity {
private final static int REQUEST_ENABLE_BT = 1; private final static int REQUEST_ENABLE_BT = 1;
Button btnConnect; TextView txtStatus;
OutputStream btOutStream; OutputStream btOutStream;
Boolean btConnected = false; Boolean btConnected = false;
BluetoothSocket btSocket = null; BluetoothSocket btSocket = null;
@ -28,25 +29,33 @@ public class MainActivity extends AppCompatActivity {
SeekBar motorB; SeekBar motorB;
TextView txtA; TextView txtA;
TextView txtB; TextView txtB;
int motorACommand = 2; private final static int MOTOR_FULL_FORWARD_COMMAND = 4;
int motorBCommand = 2; private final static int MOTOR_FULL_BACKWARD_COMMAND = 0;
private final static int MOTOR_STOP_COMMAND = 2;
ImageView imEngine;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
btnConnect = (Button)findViewById(R.id.btnConnect); txtStatus = (TextView) findViewById(R.id.txtStatus);
motorA = (SeekBar)findViewById(R.id.motorA); motorA = (SeekBar)findViewById(R.id.motorB);
motorA.setProgress(2); motorA.setProgress(MOTOR_STOP_COMMAND);
motorA.setMax(4); motorA.setMax(MOTOR_FULL_FORWARD_COMMAND);
motorB = (SeekBar)findViewById(R.id.motorB); motorB = (SeekBar)findViewById(R.id.motorA);
motorB.setProgress(2); motorB.setProgress(MOTOR_STOP_COMMAND);
motorB.setMax(4); motorB.setMax(MOTOR_FULL_FORWARD_COMMAND);
motorA.setEnabled(false);
motorB.setEnabled(false);
imEngine = (ImageView)findViewById(R.id.imCE);
imEngine.setVisibility(View.VISIBLE);
txtA = (TextView)findViewById(R.id.txtA); txtA = (TextView)findViewById(R.id.txtA);
txtB = (TextView)findViewById(R.id.txtB); txtB = (TextView)findViewById(R.id.txtB);
txtA.setText(Integer.toString(MOTOR_STOP_COMMAND));
txtB.setText(Integer.toString(MOTOR_STOP_COMMAND));
motorA.setOnSeekBarChangeListener( motorA.setOnSeekBarChangeListener(
new SeekBar.OnSeekBarChangeListener() { new SeekBar.OnSeekBarChangeListener() {
@ -54,7 +63,6 @@ public class MainActivity extends AppCompatActivity {
@Override @Override
public void onProgressChanged(SeekBar seekBar, public void onProgressChanged(SeekBar seekBar,
int progresValue, boolean fromUser) { int progresValue, boolean fromUser) {
motorBCommand = progresValue;
sendCommand(); sendCommand();
} }
@ -67,7 +75,7 @@ public class MainActivity extends AppCompatActivity {
@Override @Override
public void onStopTrackingTouch(SeekBar seekBar) { public void onStopTrackingTouch(SeekBar seekBar) {
seekBar.setProgress(2); seekBar.setProgress(MOTOR_STOP_COMMAND);
} }
}); });
@ -78,7 +86,6 @@ public class MainActivity extends AppCompatActivity {
@Override @Override
public void onProgressChanged(SeekBar seekBar, public void onProgressChanged(SeekBar seekBar,
int progresValue, boolean fromUser) { int progresValue, boolean fromUser) {
motorACommand = progresValue;
sendCommand(); sendCommand();
} }
@ -91,14 +98,51 @@ public class MainActivity extends AppCompatActivity {
@Override @Override
public void onStopTrackingTouch(SeekBar seekBar) { public void onStopTrackingTouch(SeekBar seekBar) {
seekBar.setProgress(2); seekBar.setProgress(MOTOR_STOP_COMMAND);
} }
}); });
btnConnect.setOnClickListener(new View.OnClickListener() { connectToCar();
public void onClick(View v) {
if (!btConnected) {
}
@Override
protected void onDestroy() {
disconnectFromCar();
super.onDestroy();
}
private void disconnectFromCar() {
try {
btOutStream.close();
} catch (Exception e) {
//e.printStackTrace();
}
try {
btSocket.close();
} catch (Exception e) {
//e.printStackTrace();
}
btConnected = false;
motorA.setEnabled(false);
motorB.setEnabled(false);
imEngine.setVisibility(View.GONE);
}
private void connectToCar() {
new Thread() {
public void run() {
while (btSocket==null || !btSocket.isConnected()) {
runOnUiThread(new Runnable() {
@Override
public void run() {
txtStatus.setText("Connecting...");
imEngine.setVisibility(View.VISIBLE);
}
});
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter == null) { if (adapter == null) {
// Device does not support Bluetooth // Device does not support Bluetooth
@ -106,62 +150,83 @@ public class MainActivity extends AppCompatActivity {
} }
if (!adapter.isEnabled()) { if (!adapter.isEnabled()) {
runOnUiThread(new Runnable() {
@Override
public void run() {
txtStatus.setText("Bluetooth is not enabled. Will retry in 5 sec.");
imEngine.setVisibility(View.VISIBLE);
}
});
//make sure the device's bluetooth is enabled //make sure the device's bluetooth is enabled
Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBluetooth, REQUEST_ENABLE_BT); startActivityForResult(enableBluetooth, REQUEST_ENABLE_BT);
} } else {
final UUID SERIAL_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); //UUID for serial connection final UUID SERIAL_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); //UUID for serial connection
String mac = "98:D3:31:F5:2D:2F"; //my laptop's mac adress String mac = "98:D3:31:F5:2D:2F"; //my laptop's mac adress
BluetoothDevice device = adapter.getRemoteDevice(mac); //get remote device by mac, we assume these two devices are already paired BluetoothDevice device = adapter.getRemoteDevice(mac); //get remote device by mac, we assume these two devices are already paired
// Get a BluetoothSocket to connect with the given BluetoothDevice // Get a BluetoothSocket to connect with the given BluetoothDevice
btSocket = null; btSocket = null;
btOutStream = null; btOutStream = null;
try { try {
btSocket = device.createRfcommSocketToServiceRecord(SERIAL_UUID); btSocket = device.createRfcommSocketToServiceRecord(SERIAL_UUID);
} catch (IOException e) { } catch (Exception e) {
e.printStackTrace(); runOnUiThread(new Runnable() {
@Override
public void run() {
txtStatus.setText("Error creating socket. Will retry in 5 sec.");
imEngine.setVisibility(View.VISIBLE);
}
});
} }
try { try {
btSocket.connect(); btSocket.connect();
btOutStream = btSocket.getOutputStream(); btOutStream = btSocket.getOutputStream();
btConnected = true; btConnected = true;
btnConnect.setText("Disconnect"); runOnUiThread(new Runnable() {
//now you can use out to send output via out.write @Override
} catch (IOException e) { public void run() {
e.printStackTrace(); txtStatus.setText("Connected");
} imEngine.setVisibility(View.GONE);
} else { motorA.setEnabled(true);
try { motorB.setEnabled(true);
btOutStream.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
btSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
btConnected = false;
btnConnect.setText("Connect");
}
} }
}); });
} catch (Exception e) {
final Exception er = e;
runOnUiThread(new Runnable() {
@Override
public void run() {
txtStatus.setText("Connection error. Will retry in 5 sec.");
imEngine.setVisibility(View.VISIBLE);
}
});
e.printStackTrace();
}
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
} }
private void sendCommand() { private void sendCommand() {
String m1 = Integer.toString(motorACommand); String m1 = Integer.toString(motorA.getProgress());
String m2 = Integer.toString(motorBCommand); String m2 = Integer.toString(motorB.getProgress());
txtA.setText(m1); txtA.setText(m1);
txtB.setText(m2); txtB.setText(m2);
try { try {
if (btOutStream != null)
btOutStream.write((m1+m2).getBytes()); btOutStream.write((m1+m2).getBytes());
} catch (IOException e) { } catch (Exception e) {
//e.printStackTrace(); txtStatus.setText("Disconnected");
disconnectFromCar();
connectToCar();
} }
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

View File

@ -9,9 +9,10 @@
<SeekBar <SeekBar
android:id="@+id/motorA" android:id="@+id/motorA"
style="@style/Widget.AppCompat.SeekBar.Discrete" style="@style/Widget.AppCompat.SeekBar.Discrete"
android:layout_width="182dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:max="500" android:max="500"
@ -20,16 +21,18 @@
android:rotation="270" android:rotation="270"
android:thumb="@android:drawable/ic_notification_overlay" android:thumb="@android:drawable/ic_notification_overlay"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<SeekBar <SeekBar
android:id="@+id/motorB" android:id="@+id/motorB"
style="@style/Widget.AppCompat.SeekBar.Discrete" style="@style/Widget.AppCompat.SeekBar.Discrete"
android:layout_width="182dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:max="500" android:max="500"
android:min="0" android:min="0"
@ -38,18 +41,7 @@
android:thumb="@android:drawable/ic_notification_overlay" android:thumb="@android:drawable/ic_notification_overlay"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintStart_toStartOf="@+id/guideline"
<Button
android:id="@+id/btnConnect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="Connect"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<TextView <TextView
@ -60,7 +52,7 @@
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:text="TextView" android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/motorA" /> app:layout_constraintStart_toStartOf="parent" />
<TextView <TextView
android:id="@+id/txtB" android:id="@+id/txtB"
@ -70,6 +62,37 @@
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:text="TextView" android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/motorB" /> app:layout_constraintEnd_toEndOf="parent" />
<android.support.constraint.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
<TextView
android:id="@+id/txtStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:text="Status..."
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<ImageView
android:id="@+id/imCE"
android:layout_width="101dp"
android:layout_height="63dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toStartOf="@+id/guideline"
app:layout_constraintStart_toStartOf="@+id/guideline"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/engine" />
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>