package nl.rhinofly.twelvetalk;
import org.apache.commons.codec.binary.Hex;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
import android.util.Log;
public class TTMainActivity extends Activity {
private static final String TAG = TTMainActivity.class.getSimpleName();
private TTApplication TTApp;
//private final WebSocketConnection mConnection = new WebSocketConnection();
// Debugging
private boolean D = true;
// Message types sent from the TTBluetoothService 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_POLL_CONNECTED = 4;
public static final int MESSAGE_POLL_DISCONNECTED = 5;
public static final int MESSAGE_LOG = 6;
public static final int MESSAGE_POLL = 7;
public static final int MESSAGE_CONNECTED = 8;
public static final int MESSAGE_DISCONNECTED = 9;
// Message types sent from the TTWebsocketService Handler
public static final int WS_MESSAGE_READ = 1;
public static final int WS_MESSAGE_LOG = 3;
public static final int WS_MESSAGE_CONNECTED = 4;
public static final int WS_MESSAGE_DISCONNECTED = 5;
// Key names received from the TTBluetoothService Handler
public static final String DEVICE_NAME = "device_name";
public static final String TOAST = "toast";
public static final String LOG = "log";
public static final String MESSAGE = "message";
// Intent request codes
private static final int REQUEST_CONNECT_DEVICE_SECURE = 1;
private static final int REQUEST_ENABLE_BT = 3;
// Layout Views
private ToggleButton toggleBT;
private ToggleButton toggleWS;
private ToggleButton togglePL;
// Name of the connected device
private String mConnectedDeviceName = null;
// Local Bluetooth adapter
private BluetoothAdapter mBluetoothAdapter = null;
private TTBluetoothService BTService = null;
private TTWebsocketService WSService = null;
// nxt address ( a specific NXT address, won't work for any other NTX !!!)
final String macAddress = "00:16:53:15:4D:9A"; //NXT
//final String macAddress = "D8:B3:77:0B:42:53"; //HTC FLYER
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.TTApp = (TTApplication) getApplication();
this.TTApp.setLogView((TextView) findViewById(R.id.mainLogView));
this.D = TTApp.getPrefs().getBoolean("debug", false);
// disable screen dimming
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
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();
TTApp.log("Exiting, bluetooth not available");
finish();
return;
}
toggleBT = (ToggleButton) findViewById(R.id.bluetoothToggle);
toggleWS = (ToggleButton) findViewById(R.id.websocketToggle);
togglePL = (ToggleButton) findViewById(R.id.pollingToggle);
toggleWS.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
if (toggleWS.isChecked()){
WSService.connect();
}else{
WSService.disconnect();
}
}
});
togglePL.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
if (togglePL.isChecked()){
BTService.startPoll();
}else{
BTService.stopPoll();
}
}
});
toggleBT.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
if (toggleBT.isChecked()){
BTService.startBluetooth();
}else{
BTService.stopBluetooth();
}
}
});
// will be followed up by onStart;
}
@Override
public void onStart() {
super.onStart();
if(D) Log.e(TAG, "++ ON START ++");
// If BT is not on, request that it be enabled.
// startCommunications() will then be called during onActivityResult
if (!mBluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
// Otherwise, setup communications
} else {
if (BTService == null) {
startCommunications();
}
}
}
@Override
public synchronized void onResume() {
super.onResume();
if(D) TTApp.log(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 (BTService != null) {
// Only if the state is STATE_NONE, do we know that we haven't started already
if (BTService.getState() == TTBluetoothService.STATE_NONE) {
// Start the Bluetooth services
BTService.start();
}
}
}
@Override
public synchronized void onPause() {
super.onPause();
if(D) TTApp.log(TAG, "- ON PAUSE -");
}
@Override
public void onStop() {
super.onStop();
if(D) TTApp.log(TAG, "-- ON STOP --");
}
@Override
public void onDestroy() {
super.onDestroy();
// Stop the Bluetooth services
if (BTService != null) BTService.stop();
if (WSService != null && WSService.isConnected()) WSService.disconnect();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater(); //
inflater.inflate(R.menu.menu, menu); //
return true; //
}
// Called when an options item is clicked
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { //
case R.id.prefs:
startActivity(new Intent(this, TTPrefsActivity.class)); // break;
}
return true; //
}
private void connectDevice(Intent data) {
// Get the device MAC address
String address = data.getExtras().getString(TTDeviceListActivity.EXTRA_DEVICE_ADDRESS);
// Get the BluetoothDevice object
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
// Attempt to connect to the device
BTService.connect();
}
private void startCommunications() {
TTApp.log(TAG, "setup communications...");
// connect device
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(macAddress);
// Initialize the TTBluetoothService to perform bluetooth connections
BTService = new TTBluetoothService(btHandler, TTApp,device);
// Attempt to connect to the device
BTService.connect();
//initialize Websocket service
WSService = new TTWebsocketService(wsHandler, TTApp);
WSService.startWebsocketCommunication();
return;
}
/**
* Sends a message.
* @param message byte array to send.
*/
private void sendBTMessage(byte[] message) {
// Check that we're actually connected before trying anything
if (BTService.getState() != TTBluetoothService.STATE_CONNECTED) {
TTApp.log(TAG,"Can't send to Bluetooth device; not connected.");
return;
}
BTService.write(message);
// Reset out string buffer to zero and clear the edit text field
}
/**
* Sends a message.
* @param message byte array to send.
*/
private void sendWSMessage(byte[] message) {
// Check that we're actually connected before trying anything
if (!WSService.isConnected()) {
TTApp.log(TAG,"Can't send to websocket; not connected.");
return;
}
WSService.writeBinary(message);
// Reset out string buffer to zero and clear the edit text field
}
// The Handler that gets information back from the TTBluetoothService
private final Handler btHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_WRITE:
// not implemented
case MESSAGE_POLL:
byte[] polBuf = (byte[]) msg.obj;
// construct a string from the buffer
if (polBuf != null){
TTApp.log(TAG,"Poller sent: "+ new String(Hex.encodeHex(polBuf)));
}
break;
case MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
String hexString = new String(Hex.encodeHex(readBuf));
TTApp.log(TAG,"Bluetooth: device sent: "+hexString );
sendWSMessage(readBuf);
break;
case MESSAGE_CONNECTED:
// save the connected device's name
mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
TTApp.log(TAG,"Bluetooth: connected to "+ mConnectedDeviceName);
toggleBT.setBackgroundResource(R.drawable.on);
toggleBT.setChecked(true);
break;
case MESSAGE_DISCONNECTED:
// save the connected device's name
TTApp.log(TAG,"Bluetooth: connection lost");
toggleBT.setBackgroundResource(R.drawable.off);
toggleBT.setChecked(false);
break;
case MESSAGE_POLL_CONNECTED:
TTApp.log(TAG,msg.getData().getString(MESSAGE));
togglePL.setBackgroundResource(R.drawable.on);
togglePL.setChecked(true);
break;
case MESSAGE_POLL_DISCONNECTED:
TTApp.log(TAG,msg.getData().getString(MESSAGE));
togglePL.setBackgroundResource(R.drawable.off);
togglePL.setChecked(false);
break;
case MESSAGE_LOG:
TTApp.log(TAG,"Bluetooth: "+msg.getData().getString(MESSAGE));
break;
}
}
};
// The Handler that gets information back from the TTBWebsocketService
private final Handler wsHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case WS_MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
String readMessage = new String(readBuf, 0, msg.arg1);
TTApp.log(TAG,("Websocket: system sent: (Stringified)"+readMessage));
sendBTMessage(readBuf);
break;
case WS_MESSAGE_CONNECTED:
TTApp.log(TAG,"Websocket: "+msg.getData().getString(MESSAGE));
toggleWS.setBackgroundResource(R.drawable.on);
toggleWS.setChecked(true);
break;
case WS_MESSAGE_DISCONNECTED:
TTApp.log(TAG,"Websocket: "+msg.getData().getString(MESSAGE));
toggleWS.setBackgroundResource(R.drawable.off);
toggleWS.setChecked(false);
break;
case WS_MESSAGE_LOG:
TTApp.log(TAG,"Websocket: "+msg.getData().getString(MESSAGE));
}
}
};
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(D) TTApp.log(TAG, "onActivityResult " + resultCode);
switch (requestCode) {
case REQUEST_CONNECT_DEVICE_SECURE:
// 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 BT communications
startCommunications();
} else {
// User did not enable Bluetooth or an error occurred
Log.d(TAG, "BT not enabled");
Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
TTApp.log(TAG,"Bluetooth: not enabled. Leaving.");
finish();
}
}
}
}