diff options
Diffstat (limited to 'electicAndroid/src')
3 files changed, 1126 insertions, 0 deletions
diff --git a/electicAndroid/src/com/futureproof/adaptics/electic/AdapticsBluetooth.java b/electicAndroid/src/com/futureproof/adaptics/electic/AdapticsBluetooth.java new file mode 100644 index 0000000..72ff1d4 --- /dev/null +++ b/electicAndroid/src/com/futureproof/adaptics/electic/AdapticsBluetooth.java @@ -0,0 +1,520 @@ +/* + * Tim Redfern 2011 + * based on android - bluetoothchat + * + * 001 refactor + * 002 correct SDP to connect to bluetoothbee + * 003 decoding messages, data doesn't seem to make sense + * 004 building interface widgets to accept it + * + * filter based on SDP? + */ + +package com.futureproof.adaptics.electic; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.UUID; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothSocket; +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.util.Log; + +/** + Adaptics bluetooth connects to a single device at a time, SPP, host-slave model + */ +public class AdapticsBluetooth { + // Debugging + private static final String TAG = "AdapticsBluetooth"; + private static final boolean D = true; + + /* + // Name for the SDP record when creating server socket + private static final String NAME_SECURE = "BluetoothChatSecure"; + private static final String NAME_INSECURE = "BluetoothChatInsecure"; + */ + + // Unique UUID for this application + private static final UUID MY_UUID = + UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); + + // Member fields + private final BluetoothAdapter mAdapter; + private final Handler mHandler; + //private AcceptThread mSecureAcceptThread; + //private AcceptThread mInsecureAcceptThread; + private ConnectThread mConnectThread; + private ConnectedThread mConnectedThread; + private int mState; + + // Constants that indicate the current connection state + public static final int STATE_NONE = 0; // we're doing nothing + //public static final int STATE_LISTEN = 1; // now listening for incoming connections + public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection + public static final int STATE_CONNECTED = 3; // now connected to a remote device + + /** + * Constructor. Prepares a new BluetoothChat session. + * @param context The UI Activity Context + * @param handler A Handler to send messages back to the UI Activity + */ + public AdapticsBluetooth(Context context, Handler handler) { + mAdapter = BluetoothAdapter.getDefaultAdapter(); + mState = STATE_NONE; + mHandler = handler; + } + + /** + * Set the current state of the chat connection + * @param state An integer defining the current connection state + */ + private synchronized void setState(int state) { + if (D) Log.d(TAG, "setState() " + mState + " -> " + state); + mState = state; + + // Give the new state to the Handler so the UI Activity can update + mHandler.obtainMessage(Electic.MESSAGE_STATE_CHANGE, state, -1).sendToTarget(); + } + + /** + * Return the current connection state. */ + public synchronized int getState() { + return mState; + } + + /** + * Start the chat service. Specifically start AcceptThread to begin a + * session in listening (server) mode. Called by the Activity onResume() */ + public synchronized void start() { + if (D) Log.d(TAG, "start"); + + // Cancel any thread attempting to make a connection + if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;} + + // Cancel any thread currently running a connection + if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;} + + setState(STATE_NONE); + + /* + // Start the thread to listen on a BluetoothServerSocket + if (mSecureAcceptThread == null) { + mSecureAcceptThread = new AcceptThread(true); + mSecureAcceptThread.start(); + } + if (mInsecureAcceptThread == null) { + mInsecureAcceptThread = new AcceptThread(false); + mInsecureAcceptThread.start(); + } + */ + } + + /** + * 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) { + if (D) Log.d(TAG, "connect to: " + device); + + // Cancel any thread attempting to make a connection + if (mState == STATE_CONNECTING) { + if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;} + } + + // Cancel any thread currently running a connection + if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;} + + // Start the thread to connect with the given device + mConnectThread = new ConnectThread(device); + mConnectThread.start(); + setState(STATE_CONNECTING); + } + + /** + * Start the ConnectedThread to begin managing a Bluetooth connection + * @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) { + if (D) Log.d(TAG, "connected"); + + // Cancel the thread that completed the connection + if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;} + + // Cancel any thread currently running a connection + if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;} + + /* + // Cancel the accept thread because we only want to connect to one device + if (mSecureAcceptThread != null) { + mSecureAcceptThread.cancel(); + mSecureAcceptThread = null; + } + if (mInsecureAcceptThread != null) { + mInsecureAcceptThread.cancel(); + mInsecureAcceptThread = null; + } + */ + + // Start the thread to manage the connection and perform transmissions + mConnectedThread = new ConnectedThread(socket); + mConnectedThread.start(); + + // Send the name of the connected device back to the UI Activity + Message msg = mHandler.obtainMessage(Electic.MESSAGE_DEVICE_NAME); + Bundle bundle = new Bundle(); + bundle.putString(Electic.DEVICE_NAME, device.getName()); + msg.setData(bundle); + mHandler.sendMessage(msg); + + setState(STATE_CONNECTED); + } + + /** + * Stop all threads + */ + public synchronized void stop() { + if (D) Log.d(TAG, "stop"); + + if (mConnectThread != null) { + mConnectThread.cancel(); + mConnectThread = null; + } + + if (mConnectedThread != null) { + mConnectedThread.cancel(); + mConnectedThread = null; + } + + /* + if (mSecureAcceptThread != null) { + mSecureAcceptThread.cancel(); + mSecureAcceptThread = null; + } + + if (mInsecureAcceptThread != null) { + mInsecureAcceptThread.cancel(); + mInsecureAcceptThread = null; + } + */ + setState(STATE_NONE); + } + + /** + * Write to the ConnectedThread in an unsynchronized manner + * @param out The bytes to write + * @see ConnectedThread#write(byte[]) + */ + public void write(byte[] out) { + // Create temporary object + ConnectedThread r; + // Synchronize a copy of the ConnectedThread + synchronized (this) { + if (mState != STATE_CONNECTED) return; + r = mConnectedThread; + } + // Perform the write unsynchronized + r.write(out); + } + + /** + * Indicate that the connection attempt failed and notify the UI Activity. + */ + private void connectionFailed() { + // Send a failure message back to the Activity + Message msg = mHandler.obtainMessage(Electic.MESSAGE_TOAST); + Bundle bundle = new Bundle(); + bundle.putString(Electic.TOAST, "Unable to connect device"); + msg.setData(bundle); + mHandler.sendMessage(msg); + + // Start the service over to restart listening mode + AdapticsBluetooth.this.start(); + } + + /** + * Indicate that the connection was lost and notify the UI Activity. + */ + private void connectionLost() { + // Send a failure message back to the Activity + Message msg = mHandler.obtainMessage(Electic.MESSAGE_TOAST); + Bundle bundle = new Bundle(); + bundle.putString(Electic.TOAST, "Device connection was lost"); + msg.setData(bundle); + mHandler.sendMessage(msg); + + // Start the service over to restart listening mode + AdapticsBluetooth.this.start(); + } + + /** + * This thread runs while listening for incoming connections. It behaves + * like a server-side client. It runs until a connection is accepted + * (or until cancelled). + */ + + /* + private class AcceptThread extends Thread { + // The local server socket + private final BluetoothServerSocket mmServerSocket; + private String mSocketType; + + public AcceptThread(boolean secure) { + BluetoothServerSocket tmp = null; + mSocketType = secure ? "Secure":"Insecure"; + + // Create a new listening server socket + try { + if (secure) { + tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, + MY_UUID_SECURE); + } else { + tmp = mAdapter.listenUsingInsecureRfcommWithServiceRecord( + NAME_INSECURE, MY_UUID_INSECURE); + } + } catch (IOException e) { + Log.e(TAG, "Socket Type: " + mSocketType + "listen() failed", e); + } + mmServerSocket = tmp; + } + + public void run() { + if (D) Log.d(TAG, "Socket Type: " + mSocketType + + "BEGIN mAcceptThread" + this); + setName("AcceptThread" + mSocketType); + + BluetoothSocket socket = null; + + // Listen to the server socket if we're not connected + while (mState != STATE_CONNECTED) { + try { + // This is a blocking call and will only return on a + // successful connection or an exception + socket = mmServerSocket.accept(); + } catch (IOException e) { + Log.e(TAG, "Socket Type: " + mSocketType + "accept() failed", e); + break; + } + + // If a connection was accepted + if (socket != null) { + synchronized (AdapticsBluetooth.this) { + switch (mState) { + case STATE_LISTEN: + case STATE_CONNECTING: + // Situation normal. Start the connected thread. + connected(socket, socket.getRemoteDevice(), + mSocketType); + break; + case STATE_NONE: + case STATE_CONNECTED: + // Either not ready or already connected. Terminate new socket. + try { + socket.close(); + } catch (IOException e) { + Log.e(TAG, "Could not close unwanted socket", e); + } + break; + } + } + } + } + if (D) Log.i(TAG, "END mAcceptThread, socket Type: " + mSocketType); + + } + + public void cancel() { + if (D) Log.d(TAG, "Socket Type" + mSocketType + "cancel " + this); + try { + mmServerSocket.close(); + } catch (IOException e) { + Log.e(TAG, "Socket Type" + mSocketType + "close() of server failed", e); + } + } + } +*/ + + /** + * This thread runs while attempting to make an outgoing connection + * with a device. It runs straight through; the connection either + * succeeds or fails. + */ + private class ConnectThread extends Thread { + private final BluetoothSocket mmSocket; + private final BluetoothDevice mmDevice; + + public ConnectThread(BluetoothDevice device) { + mmDevice = device; + BluetoothSocket tmp = null; + + + // Get a BluetoothSocket for a connection with the + // given BluetoothDevice + + // + // http://stackoverflow.com/questions/3397071/android-bluetooth-service-discovery-failed-exception + // + try { + tmp = device.createInsecureRfcommSocketToServiceRecord( + MY_UUID); + } catch (IOException e) { + Log.e(TAG, "Socket create() failed", e); + } + mmSocket = tmp; + } + + public void run() { + Log.i(TAG, "BEGIN mConnectThread"); + setName("ConnectThread"); + + // Always cancel discovery because it will slow down a connection + mAdapter.cancelDiscovery(); + + // Make a connection to the BluetoothSocket + try { + // This is a blocking call and will only return on a + // successful connection or an exception + mmSocket.connect(); + } catch (IOException e) { + // Close the socket + try { + mmSocket.close(); + } catch (IOException e2) { + Log.e(TAG, "unable to close() socket during connection failure", e2); + } + connectionFailed(); + return; + } + + // Reset the ConnectThread because we're done + synchronized (AdapticsBluetooth.this) { + mConnectThread = null; + } + + // Start the connected thread + connected(mmSocket, mmDevice); + } + + public void cancel() { + try { + mmSocket.close(); + } catch (IOException e) { + Log.e(TAG, "close() of connect socket failed", e); + } + } + } + + /** + * This thread runs during a connection with a remote device. + * It handles all incoming and outgoing transmissions. + */ + private class ConnectedThread extends Thread { + private final BluetoothSocket mmSocket; + private final InputStream mmInStream; + private final OutputStream mmOutStream; + + public ConnectedThread(BluetoothSocket socket) { + Log.d(TAG, "create ConnectedThread"); + mmSocket = socket; + InputStream tmpIn = null; + OutputStream tmpOut = null; + + // Get the BluetoothSocket input and output streams + try { + tmpIn = socket.getInputStream(); + tmpOut = socket.getOutputStream(); + } catch (IOException e) { + Log.e(TAG, "temp sockets not created", e); + } + + mmInStream = tmpIn; + mmOutStream = tmpOut; + } + + public void run() { + Log.i(TAG, "BEGIN mConnectedThread"); + byte[] temp = new byte[1024]; + byte[] buffer = new byte[1024]; + int bufferPtr=0; + byte[] message; + int bytes; + + // Keep listening to the InputStream while connected + while (true) { + try { + // Read from the InputStream + bytes = mmInStream.read(temp); + /* + * check the message segmentation and send on the payload + * keep a buffer of incoming messages + * look for the message signature + * and begin reading from there + * + */ + //String debugMess="bytes:"+bytes+" "; + //String sendMess=""; + for (int i=0;i<bytes;i++) { + buffer[bufferPtr+i]=temp[i]; + //debugMess+=buffer[bufferPtr+i]+" "; + } + //Log.i(TAG, debugMess); + bufferPtr+=bytes; + for (int i=0;i<bufferPtr-3;i++){ //message must be at least 1 byte + if (buffer[i]==-16&&buffer[i+1]==0&&bufferPtr>i+2+buffer[i+2]) { + int msgLen=buffer[i+2]; + message = new byte[msgLen]; + for (int j=0;j<msgLen;j++){ + message[j]=buffer[i+j+3]; + //sendMess+=buffer[i+j+3]+" "; + } + for (int k=0;k<bufferPtr-(i+msgLen+3);k++){ + buffer[k]=buffer[i+msgLen+3+k]; + } + bufferPtr-=(i+msgLen+3); + // Send the obtained bytes to the UI Activity + mHandler.obtainMessage(Electic.MESSAGE_READ, bytes, -1, message) + .sendToTarget(); + //Log.i(TAG, "++++SENT: "+sendMess); + } + } + + } catch (IOException e) { + Log.e(TAG, "disconnected", e); + connectionLost(); + break; + } + } + } + + /** + * Write to the connected OutStream. + * @param buffer The bytes to write + */ + public void write(byte[] buffer) { + try { + mmOutStream.write(buffer); + + // Share the sent message back to the UI Activity + mHandler.obtainMessage(Electic.MESSAGE_WRITE, -1, -1, buffer) + .sendToTarget(); + } catch (IOException e) { + Log.e(TAG, "Exception during write", e); + } + } + + public void cancel() { + try { + mmSocket.close(); + } catch (IOException e) { + Log.e(TAG, "close() of connect socket failed", e); + } + } + } +} diff --git a/electicAndroid/src/com/futureproof/adaptics/electic/DeviceListActivity.java b/electicAndroid/src/com/futureproof/adaptics/electic/DeviceListActivity.java new file mode 100644 index 0000000..27077ca --- /dev/null +++ b/electicAndroid/src/com/futureproof/adaptics/electic/DeviceListActivity.java @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.futureproof.adaptics.electic; + +import java.util.Set; + +import com.futureproof.adaptics.electic.R; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothClass; +import android.bluetooth.BluetoothDevice; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.view.Window; +import android.view.View.OnClickListener; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.ListView; +import android.widget.TextView; +import android.widget.AdapterView.OnItemClickListener; + +/** + * This Activity appears as a dialog. It lists any paired devices and + * devices detected in the area after discovery. When a device is chosen + * by the user, the MAC address of the device is sent back to the parent + * Activity in the result Intent. + */ +public class DeviceListActivity extends Activity { + // Debugging + private static final String TAG = "DeviceListActivity"; + private static final boolean D = true; + + // Return Intent extra + public static String EXTRA_DEVICE_ADDRESS = "device_address"; + + // Member fields + private BluetoothAdapter mBtAdapter; + private ArrayAdapter<String> mPairedDevicesArrayAdapter; + private ArrayAdapter<String> mNewDevicesArrayAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Setup the window + requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); + setContentView(R.layout.device_list); + + // Set result CANCELED incase the user backs out + setResult(Activity.RESULT_CANCELED); + + // Initialize the button to perform device discovery + Button scanButton = (Button) findViewById(R.id.button_scan); + scanButton.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + doDiscovery(); + v.setVisibility(View.GONE); + } + }); + + // Initialize array adapters. One for already paired devices and + // one for newly discovered devices + mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name); + mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name); + + // Find and set up the ListView for paired devices + ListView pairedListView = (ListView) findViewById(R.id.paired_devices); + pairedListView.setAdapter(mPairedDevicesArrayAdapter); + pairedListView.setOnItemClickListener(mDeviceClickListener); + + // Find and set up the ListView for newly discovered devices + ListView newDevicesListView = (ListView) findViewById(R.id.new_devices); + newDevicesListView.setAdapter(mNewDevicesArrayAdapter); + newDevicesListView.setOnItemClickListener(mDeviceClickListener); + + // Register for broadcasts when a device is discovered + IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); + this.registerReceiver(mReceiver, filter); + + // Register for broadcasts when discovery has finished + filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); + this.registerReceiver(mReceiver, filter); + + // Get the local Bluetooth adapter + mBtAdapter = BluetoothAdapter.getDefaultAdapter(); + + // Get a set of currently paired devices + Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices(); + + // If there are paired devices, add each one to the ArrayAdapter + if (pairedDevices.size() > 0) { + findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE); + for (BluetoothDevice device : pairedDevices) { + mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress()); + } + } else { + String noDevices = getResources().getText(R.string.none_paired).toString(); + mPairedDevicesArrayAdapter.add(noDevices); + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + + // Make sure we're not doing discovery anymore + if (mBtAdapter != null) { + mBtAdapter.cancelDiscovery(); + } + + // Unregister broadcast listeners + this.unregisterReceiver(mReceiver); + } + + /** + * Start device discover with the BluetoothAdapter + */ + private void doDiscovery() { + if (D) Log.d(TAG, "doDiscovery()"); + + // Indicate scanning in the title + setProgressBarIndeterminateVisibility(true); + setTitle(R.string.scanning); + + // Turn on sub-title for new devices + findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE); + + // If we're already discovering, stop it + if (mBtAdapter.isDiscovering()) { + mBtAdapter.cancelDiscovery(); + } + + // Request discover from BluetoothAdapter + mBtAdapter.startDiscovery(); + } + + // The on-click listener for all devices in the ListViews + private OnItemClickListener mDeviceClickListener = new OnItemClickListener() { + public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) { + // Cancel discovery because it's costly and we're about to connect + mBtAdapter.cancelDiscovery(); + + // Get the device MAC address, which is the last 17 chars in the View + String info = ((TextView) v).getText().toString(); + String address = info.substring(info.length() - 17); + + // Create the result Intent and include the MAC address + Intent intent = new Intent(); + intent.putExtra(EXTRA_DEVICE_ADDRESS, address); + + // Set result and finish this Activity + setResult(Activity.RESULT_OK, intent); + finish(); + } + }; + + // The BroadcastReceiver that listens for discovered devices and + // changes the title when discovery is finished + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + + // When discovery finds a device + if (BluetoothDevice.ACTION_FOUND.equals(action)) { + // Get the BluetoothDevice object from the Intent + BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + BluetoothClass bclass = intent.getParcelableExtra(BluetoothDevice.EXTRA_CLASS); + // If it's already paired, skip it, because it's been listed already + + // + // + // filter for the right type of devices? + // + // + + if (device.getBondState() != BluetoothDevice.BOND_BONDED) { + mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress()); //+ "\n" + bclass.getDeviceClass()); + } + // When discovery is finished, change the Activity title + } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { + setProgressBarIndeterminateVisibility(false); + setTitle(R.string.select_device); + if (mNewDevicesArrayAdapter.getCount() == 0) { + String noDevices = getResources().getText(R.string.none_found).toString(); + mNewDevicesArrayAdapter.add(noDevices); + } + } + } + }; + +} diff --git a/electicAndroid/src/com/futureproof/adaptics/electic/Electic.java b/electicAndroid/src/com/futureproof/adaptics/electic/Electic.java new file mode 100644 index 0000000..7de9104 --- /dev/null +++ b/electicAndroid/src/com/futureproof/adaptics/electic/Electic.java @@ -0,0 +1,393 @@ +/* + * Tim Redfern 2011 + * + * + * number view display + * decision: decipher in mcu? + * ie - need to range quickly based on this? + * decide protocol for setting commands + * make a couple of buttons and use these to change + */ + +package com.futureproof.adaptics.electic; + + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.util.Log; +import android.view.Menu; +import android.view.Window; +import android.widget.CheckBox; +import android.widget.RadioGroup; +import android.widget.TextView; +import android.widget.Toast; + +/** + * This is the main Activity that displays the current chat session. + */ +public class Electic extends Activity { + // Debugging + private static final String TAG = "Electic"; + private static final boolean D = true; + + // 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 int MESSAGE_WRITE = 3; + public static final int MESSAGE_DEVICE_NAME = 4; + public static final int MESSAGE_TOAST = 5; + + // Key names received from the BluetoothChatService Handler + public static final String DEVICE_NAME = "device_name"; + public static final String TOAST = "toast"; + + // Intent request codes + private static final int REQUEST_CONNECT_DEVICE = 1; + private static final int REQUEST_ENABLE_BT = 2; + + // Layout Views + private TextView mTitle; + + // Name of the connected device + private String mConnectedDeviceName = null; + // Local Bluetooth adapter + private BluetoothAdapter mBluetoothAdapter = null; + // Member object for the chat services + private AdapticsBluetooth adapBT = null; + + //electic UI elements + TextView sadcReadout; + TextView fadcReadout; + + TextView sadcReadout1; + TextView fadcReadout1; + + CheckBox PMINbox; + CheckBox PMAXbox; + CheckBox alarmBox; + RadioGroup sampleSpeedGroup; + + int SAMPLESPEED2 = R.id.rb_2; + int SAMPLESPEED05 = R.id.rb_05; + int SAMPLESPEED01 = R.id.rb_01; + + int sampleSpeed = SAMPLESPEED2; + + short ASIGNbit = (short) Integer.parseInt("10000000", 2); + short BSIGNbit = (short) Integer.parseInt("1000000", 2); + short PMAXbit = (short) Integer.parseInt("100000", 2); + short PMINbit = (short) Integer.parseInt("10000", 2); + short ALARMbit = (short) Integer.parseInt("1", 2); + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if(D) Log.e(TAG, "+++ ON CREATE +++"); + + // Set up the window layout + requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); + setContentView(R.layout.main); + getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title); + + // Set up the custom title + mTitle = (TextView) findViewById(R.id.title_left_text); + mTitle.setText(R.string.app_name); + mTitle = (TextView) findViewById(R.id.title_right_text); + + // Get local Bluetooth adapter + mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + + // If the adapter is null, then Bluetooth is not supported + if (mBluetoothAdapter == null) { + Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show(); + finish(); + return; + } + } + + @Override + public void onStart() { + super.onStart(); + if(D) Log.e(TAG, "++ ON START ++"); + + // If BT is not on, request that it be enabled. + // setupChat() will then be called during onActivityResult + if (!mBluetoothAdapter.isEnabled()) { + Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); + startActivityForResult(enableIntent, REQUEST_ENABLE_BT); + // Otherwise, setup the chat session + } else { + if (adapBT == null) setupUI(); + } + } + + @Override + public synchronized void onResume() { + super.onResume(); + if(D) Log.e(TAG, "+ ON RESUME +"); + + // Performing this check in onResume() covers the case in which BT was + // not enabled during onStart(), so we were paused to enable it... + // onResume() will be called when ACTION_REQUEST_ENABLE activity returns. + if (adapBT != null) { + // Only if the state is STATE_NONE, do we know that we haven't started already + if (adapBT.getState() == AdapticsBluetooth.STATE_NONE) { + // Start the Bluetooth chat services + adapBT.start(); + } + } + } + + private void setupUI() { + Log.d(TAG, "setupUI()"); + + //initialise electic UI elements + sadcReadout=(TextView) findViewById(R.id.sadcText); + fadcReadout=(TextView) findViewById(R.id.fadcText); + + sadcReadout1=(TextView) findViewById(R.id.sadcText1); + fadcReadout1=(TextView) findViewById(R.id.fadcText1); + + PMAXbox=(CheckBox) findViewById(R.id.pmaxBox); + PMINbox=(CheckBox) findViewById(R.id.pminBox); + alarmBox=(CheckBox) findViewById(R.id.alarmBox); + + sampleSpeedGroup = (RadioGroup) findViewById(R.id.samplespeed_group); + sampleSpeedGroup.check(sampleSpeed); + + sadcReadout.setText("0".toCharArray(), 0, 1); + fadcReadout.setText("0".toCharArray(), 0, 1); + + sadcReadout1.setText("0".toCharArray(), 0, 1); + fadcReadout1.setText("0".toCharArray(), 0, 1); + PMAXbox.setChecked(false); + PMINbox.setChecked(false); + alarmBox.setChecked(false); + + sampleSpeedGroup.setOnCheckedChangeListener( + new RadioGroup.OnCheckedChangeListener() { + public void onCheckedChanged(RadioGroup group, + int checkedId) { + setSampleSpeed(checkedId==SAMPLESPEED2?1:checkedId==SAMPLESPEED05?2:3); + } + }); + + // Initialize the service to perform bluetooth connections + adapBT = new AdapticsBluetooth(this, mHandler); + + + } + + @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 (adapBT != null) adapBT.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); + } + } + */ + + + + + // The Handler that gets information back from the BluetoothChatService + private final Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MESSAGE_STATE_CHANGE: + if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1); + switch (msg.arg1) { + case AdapticsBluetooth.STATE_CONNECTED: + mTitle.setText(R.string.title_connected_to); + mTitle.append(mConnectedDeviceName); + break; + case AdapticsBluetooth.STATE_CONNECTING: + mTitle.setText(R.string.title_connecting); + break; + // case AdapticsBluetooth.STATE_LISTEN: + case AdapticsBluetooth.STATE_NONE: + mTitle.setText(R.string.title_not_connected); + break; + } + break; + case MESSAGE_READ: + byte[] readBuf = (byte[]) msg.obj; + // construct a string from the valid bytes in the buffer + /* + * figure out how to decode data + * data has been checked at this point - message constructed + * + */ + long sadc = (ubyte64(readBuf[4]))+(ubyte64(readBuf[3])<<8)+(ubyte64(readBuf[2])<<16)+(ubyte64(readBuf[1])<<24); + int fadc = ubyte32(readBuf[6])+(ubyte32(readBuf[5])<<8); + + //reverse byte order + long sadc1=0; + for (int i=0;i<18;i++){ + sadc1+=((sadc&(((long)0x01)<<i))>>i)<<(17-i); + } + int fadc1=0; + for (int i=0;i<10;i++){ + fadc1+=((fadc&(((long)0x01)<<i))>>i)<<(9-i); + } + + if (((short)readBuf[0]&ASIGNbit)>0) { + sadc*=-1; + sadc1*=-1; + } + if (((short)readBuf[0]&BSIGNbit)>0) { + fadc*=-1; + fadc1*=-1; + } + short status=(short)readBuf[0]; + + String sadcS=Float.toString(((float)sadc)/6000.0f); + String fadcS=Float.toString(((float)fadc)/600.0f); + + String sadc1S=Float.toString(((float)sadc1)/6000.0f); + String fadc1S=Float.toString(((float)fadc1)/600.0f); + + sadcReadout.setText(sadcS.toCharArray(), 0, sadcS.length()); + fadcReadout.setText(fadcS.toCharArray(), 0, fadcS.length()); + + sadcReadout1.setText(sadc1S.toCharArray(), 0, sadc1S.length()); + fadcReadout1.setText(fadc1S.toCharArray(), 0, fadc1S.length()); + + PMAXbox.setChecked(((short)readBuf[0]&PMAXbit)>0); + PMINbox.setChecked(((short)readBuf[0]&PMINbit)>0); + alarmBox.setChecked(((short)readBuf[0]&ALARMbit)>0); + Log.i(TAG, "++++RECEIVED: "+readBuf[0]+" "+readBuf[1]+" "+readBuf[2]+" "+readBuf[3]+" "+readBuf[4]+" "+readBuf[5]+" "+readBuf[6]+" AS: "+status+" "+sadc+" "+fadc); + //String readMessage = new String(readBuf, 0, msg.arg1); + break; + case MESSAGE_DEVICE_NAME: + // save the connected device's name + mConnectedDeviceName = msg.getData().getString(DEVICE_NAME); + Toast.makeText(getApplicationContext(), "Connected to " + + mConnectedDeviceName, Toast.LENGTH_SHORT).show(); + break; + case MESSAGE_TOAST: + Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST), + Toast.LENGTH_SHORT).show(); + break; + } + } + }; + + public void onActivityResult(int requestCode, int resultCode, Intent data) { + if(D) Log.d(TAG, "onActivityResult " + resultCode); + switch (requestCode) { + case REQUEST_CONNECT_DEVICE: + // When DeviceListActivity returns with a device to connect + if (resultCode == Activity.RESULT_OK) { + connectDevice(data); + } + break; + case REQUEST_ENABLE_BT: + // When the request to enable Bluetooth returns + if (resultCode == Activity.RESULT_OK) { + // Bluetooth is now enabled, so set up a chat session + setupUI(); + } else { + // User did not enable Bluetooth or an error occured + Log.d(TAG, "BT not enabled"); + Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show(); + finish(); + } + } + } + + 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 + adapBT.connect(device); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + /* + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.option_menu, menu); + return true; + */ + Intent serverIntent = new Intent(this, DeviceListActivity.class); + startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE); + return true; + } +/* + @Override + public boolean onOptionsItemSelected(MenuItem item) { + Intent serverIntent = null; + switch (item.getItemId()) { + 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); + return true; + case R.id.insecure_connect_scan: + // Launch the DeviceListActivity to see devices and do scan + serverIntent = new Intent(this, DeviceListActivity.class); + startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE); + return true; + case R.id.discoverable: + // Ensure this device is discoverable by others + ensureDiscoverable(); + return true; + } + return false; + } + */ + private void setSampleSpeed(int speedCode) { + // Check that we're actually connected before trying anything + if (adapBT.getState() != AdapticsBluetooth.STATE_CONNECTED) { + Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show(); + return; + } + byte[] message=new byte[1]; + message[0]=(byte) speedCode; + adapBT.write(message); + + } + private int ubyte32(byte b){ + int i=(int) b; + if (i<0) i+=128; + return i; + } + private long ubyte64(byte b){ + long l=(long) b; + if (l<0) l+=128; + return l; + } + +} |
