android:layout_width="match_parent"
android:layout_height="match_parent"
>
- <ListView android:id="@+id/in"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:stackFromBottom="true"
- android:transcriptMode="alwaysScroll"
+
+ <TextView
+ android:id="@+id/in"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
android:layout_weight="1"
- />
+ android:gravity="bottom"
+ android:scrollbars="vertical"
+ android:typeface="monospace" />
+
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
- <EditText android:id="@+id/edit_text_out"
+
+ <EditText
+ android:id="@+id/edit_text_out"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_weight="1"
android:layout_gravity="bottom"
- />
+ android:layout_weight="1"
+ android:inputType="text|textNoSuggestions" />
+
<Button android:id="@+id/button_send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
limitations under the License.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/connect_scan"
+ android:icon="@android:drawable/ic_menu_search"
+ android:title="@string/connect_device" />
<item android:id="@+id/telemetry_service_control"
android:icon="@android:drawable/ic_menu_manage"
android:title="@string/telemetry_service_control" />
<item android:id="@+id/telemetry_service_bind"
android:icon="@android:drawable/ic_menu_rotate"
android:title="@string/telemetry_service_bind" />
- <item android:id="@+id/secure_connect_scan"
- android:icon="@android:drawable/ic_menu_search"
- android:title="@string/secure_connect" />
- <item android:id="@+id/insecure_connect_scan"
- android:icon="@android:drawable/ic_menu_search"
- android:title="@string/insecure_connect" />
- <item android:id="@+id/discoverable"
- android:icon="@android:drawable/ic_menu_mylocation"
- android:title="@string/discoverable" />
</menu>
<string name="send">Send</string>
<string name="not_connected">You are not connected to a device</string>
<string name="bt_not_enabled_leaving">Bluetooth was not enabled. Leaving Bluetooth Chat.</string>
- <string name="title_connecting">connecting...</string>
+ <string name="title_connecting">connecting…</string>
<string name="title_connected_to">connected: </string>
<string name="title_not_connected">not connected</string>
<!-- DeviceListActivity -->
- <string name="scanning">scanning for devices...</string>
+ <string name="scanning">scanning for devices…</string>
<string name="select_device">select a device to connect</string>
<string name="none_paired">No devices have been paired</string>
<string name="none_found">No devices found</string>
<string name="button_scan">Scan for devices</string>
<!-- Options Menu -->
- <string name="secure_connect">Connect a device - Secure</string>
- <string name="insecure_connect">Connect a device - Insecure</string>
- <string name="discoverable">Make discoverable</string>
+ <string name="connect_device">Connect a device</string>
+ <string name="telemetry_service_control">Control Service</string>
+ <string name="telemetry_service_bind">(Un)Bind Service</string>
<!-- Service -->
<string name="telemetry_service_label">AltOS Telemetry Service</string>
<string name="telemetry_service_stopped">Telemetry Service Stopped</string>
-
- <string name="telemetry_service_control">Start/Stop Service</string>
- <string name="telemetry_service_bind">Bind/Unbind Service</string>
-
<string name="activity_telemetry_service_controller">App/Service/Local Service Controller</string>
<string name="telemetry_service_controller">This demonstrates how you can implement persistent services that
may be started and stopped as desired.</string>
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
+import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.Window;
import android.view.View.OnClickListener;
import android.view.inputmethod.EditorInfo;
-import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
-import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import org.altusmetrum.AltosDroid.R;
*/
public class AltosDroid extends Activity {
// Debugging
- private static final String TAG = "BluetoothChat";
+ private static final String TAG = "AltosDroid";
private static final boolean D = true;
- private static final AltosLine q = new AltosLine();
-
// Message types sent from the BluetoothChatService Handler
public static final int MESSAGE_STATE_CHANGE = 1;
public static final int MESSAGE_READ = 2;
public static final String TOAST = "toast";
// Intent request codes
- private static final int REQUEST_CONNECT_DEVICE_SECURE = 1;
- private static final int REQUEST_CONNECT_DEVICE_INSECURE = 2;
- private static final int REQUEST_ENABLE_BT = 3;
+ private static final int REQUEST_CONNECT_DEVICE = 1;
+ private static final int REQUEST_ENABLE_BT = 2;
// Layout Views
private TextView mTitle;
- private ListView mConversationView;
+ private TextView mSerialView;
private EditText mOutEditText;
private Button mSendButton;
// Name of the connected device
private String mConnectedDeviceName = null;
- // Array adapter for the conversation thread
- private ArrayAdapter<String> mConversationArrayAdapter;
// String buffer for outgoing messages
private StringBuffer mOutStringBuffer;
// Local Bluetooth adapter
}
}
+ @Override
+ public synchronized void onPause() {
+ super.onPause();
+ if(D) Log.e(TAG, "- ON PAUSE -");
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ if(D) Log.e(TAG, "-- ON STOP --");
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ // Stop the Bluetooth chat services
+ if (mChatService != null) mChatService.stop();
+ if(D) Log.e(TAG, "--- ON DESTROY ---");
+ }
+
+
+
private void setupChat() {
Log.d(TAG, "setupChat()");
- // Initialize the array adapter for the conversation thread
- mConversationArrayAdapter = new ArrayAdapter<String>(this, R.layout.message);
- mConversationView = (ListView) findViewById(R.id.in);
- mConversationView.setAdapter(mConversationArrayAdapter);
+ mSerialView = (TextView) findViewById(R.id.in);
+ mSerialView.setMovementMethod(new ScrollingMovementMethod());
+ mSerialView.setClickable(false);
+ mSerialView.setLongClickable(false);
// Initialize the compose field with a listener for the return key
mOutEditText = (EditText) findViewById(R.id.edit_text_out);
mOutStringBuffer = new StringBuffer("");
}
- @Override
- public synchronized void onPause() {
- super.onPause();
- if(D) Log.e(TAG, "- ON PAUSE -");
- }
-
- @Override
- public void onStop() {
- super.onStop();
- if(D) Log.e(TAG, "-- ON STOP --");
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- // Stop the Bluetooth chat services
- if (mChatService != null) mChatService.stop();
- if(D) Log.e(TAG, "--- ON DESTROY ---");
- }
-
- private void ensureDiscoverable() {
- if(D) Log.d(TAG, "ensure discoverable");
- if (mBluetoothAdapter.getScanMode() !=
- BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
- Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
- discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
- startActivity(discoverableIntent);
- }
- }
-
/**
* Sends a message.
* @param message A string of text to send.
case BluetoothChatService.STATE_CONNECTED:
mTitle.setText(R.string.title_connected_to);
mTitle.append(mConnectedDeviceName);
- mConversationArrayAdapter.clear();
+ mSerialView.setText("");
break;
case BluetoothChatService.STATE_CONNECTING:
mTitle.setText(R.string.title_connecting);
byte[] writeBuf = (byte[]) msg.obj;
// construct a string from the buffer
String writeMessage = new String(writeBuf);
- mConversationArrayAdapter.add("Me: " + writeMessage);
+ mSerialView.append(writeMessage + '\n');
break;
case MESSAGE_READ:
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);
+ mSerialView.append(readMessage);
break;
case MESSAGE_DEVICE_NAME:
// save the connected device's name
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(D) Log.d(TAG, "onActivityResult " + resultCode);
switch (requestCode) {
- case REQUEST_CONNECT_DEVICE_SECURE:
- // When DeviceListActivity returns with a device to connect
+ case REQUEST_CONNECT_DEVICE:
+ // When DeviceListActivity returns with a device to connect to
if (resultCode == Activity.RESULT_OK) {
- connectDevice(data, true);
- }
- break;
- case REQUEST_CONNECT_DEVICE_INSECURE:
- // When DeviceListActivity returns with a device to connect
- if (resultCode == Activity.RESULT_OK) {
- connectDevice(data, false);
+ connectDevice(data);
}
break;
case REQUEST_ENABLE_BT:
}
}
- private void connectDevice(Intent data, boolean secure) {
+ private void connectDevice(Intent data) {
// Get the device MAC address
String address = data.getExtras()
.getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
// Get the BLuetoothDevice object
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
// Attempt to connect to the device
- mChatService.connect(device, secure);
+ mChatService.connect(device);
}
@Override
serverIntent = new Intent(this, TelemetryServiceActivities.Binding.class);
startActivity(serverIntent);
return true;
- case R.id.secure_connect_scan:
- // Launch the DeviceListActivity to see devices and do scan
- serverIntent = new Intent(this, DeviceListActivity.class);
- startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_SECURE);
- return true;
- case R.id.insecure_connect_scan:
+ case R.id.connect_scan:
// Launch the DeviceListActivity to see devices and do scan
serverIntent = new Intent(this, DeviceListActivity.class);
- startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_INSECURE);
- return true;
- case R.id.discoverable:
- // Ensure this device is discoverable by others
- ensureDiscoverable();
+ startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
return true;
}
return false;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-//import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
+import java.util.UUID;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
/**
* Start the ConnectThread to initiate a connection to a remote device.
* @param device The BluetoothDevice to connect
- * @param secure Socket Security type - Secure (true) , Insecure (false)
*/
- public synchronized void connect(BluetoothDevice device, boolean secure) {
+ public synchronized void connect(BluetoothDevice device) {
if (D) Log.d(TAG, "connect to: " + device);
// Cancel any thread attempting to make a connection
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
// Start the thread to connect with the given device
- mConnectThread = new ConnectThread(device, secure);
+ mConnectThread = new ConnectThread(device);
mConnectThread.start();
setState(STATE_CONNECTING);
}
* @param socket The BluetoothSocket on which the connection was made
* @param device The BluetoothDevice that has been connected
*/
- public synchronized void connected(BluetoothSocket socket, BluetoothDevice
- device, final String socketType) {
- if (D) Log.d(TAG, "connected, Socket Type:" + socketType);
+ public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {
+ if (D) Log.d(TAG, "connected");
// Cancel the thread that completed the connection
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
// Start the thread to manage the connection and perform transmissions
- mConnectedThread = new ConnectedThread(socket, socketType);
+ mConnectedThread = new ConnectedThread(socket);
mConnectedThread.start();
// Send the name of the connected device back to the UI Activity
* succeeds or fails.
*/
private class ConnectThread extends Thread {
+ private final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
- private String mSocketType;
- public ConnectThread(BluetoothDevice device, boolean secure) {
+ public ConnectThread(BluetoothDevice device) {
mmDevice = device;
BluetoothSocket tmp = null;
- mSocketType = secure ? "Secure" : "Insecure";
- // Get a BluetoothSocket for a connection with the
- // given BluetoothDevice
try {
- if (secure) {
- Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
- tmp = (BluetoothSocket) m.invoke(device, 2);
-// tmp = device.createRfcommSocket(1);
- } else {
- Method m = device.getClass().getMethod("createInsecureRfcommSocket", new Class[] {int.class});
- tmp = (BluetoothSocket) m.invoke(device, 2);
-// tmp = device.createInsecureRfcommSocket(1);
- }
- } catch (Exception e) {
- Log.e(TAG, "Socket Type: " + mSocketType + "create() failed", e);
+ tmp = mmDevice.createInsecureRfcommSocketToServiceRecord(SPP_UUID);
+ } catch (IOException e) {
e.printStackTrace();
}
mmSocket = tmp;
}
public void run() {
- Log.i(TAG, "BEGIN mConnectThread SocketType:" + mSocketType);
- setName("ConnectThread" + mSocketType);
+ Log.i(TAG, "BEGIN mConnectThread");
+ setName("ConnectThread");
// Always cancel discovery because it will slow down a connection
mAdapter.cancelDiscovery();
try {
mmSocket.close();
} catch (IOException e2) {
- Log.e(TAG, "unable to close() " + mSocketType +
- " socket during connection failure", e2);
+ Log.e(TAG, "unable to close() socket during connection failure", e2);
}
connectionFailed();
return;
}
// Start the connected thread
- connected(mmSocket, mmDevice, mSocketType);
+ connected(mmSocket, mmDevice);
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
- Log.e(TAG, "close() of connect " + mSocketType + " socket failed", e);
+ Log.e(TAG, "close() of connect socket failed", e);
}
}
}
private final InputStream mmInStream;
private final OutputStream mmOutStream;
- public ConnectedThread(BluetoothSocket socket, String socketType) {
- Log.d(TAG, "create ConnectedThread: " + socketType);
+ public ConnectedThread(BluetoothSocket socket) {
+ Log.d(TAG, "create ConnectedThread");
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI Activity
- mHandler.obtainMessage(AltosDroid.MESSAGE_READ, bytes, -1, buffer)
+ mHandler.obtainMessage(AltosDroid.MESSAGE_READ, bytes, -1, buffer.clone())
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);
+ mmOutStream.write('\n');
// Share the sent message back to the UI Activity
mHandler.obtainMessage(AltosDroid.MESSAGE_WRITE, -1, -1, buffer)