com.zpci.firstsignhairclipdemo.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.zpci.firstsignhairclipdemo.MainActivity.java

Source

/*
 * Copyright (C) 2013 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.
 */

// Original source for uart service handler is from Nordic Semiconductor example code
// Modifications are for diagnostic and testing purposes only
// This is unreleased code.
// Modifications, Copyright 2014, Zephyr Engineering, Inc. All Rights Reserved.
// Last update: 5/23/2014 R0.1 - Alpha test version for hardware/firmware debug support
// 6/10/2014 adjusted demo mode medium sensitivity for acc from 16 to 8
// 6/11/2014 adjusted demo mode medium sensitivity for gyro from 64 to 40
//          removed data collection from demo mode

package com.zpci.firstsignhairclipdemo;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.text.DateFormat;
import java.util.Date;

import android.app.Activity;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements RadioGroup.OnCheckedChangeListener {
    private static final int REQUEST_SELECT_DEVICE = 1;
    private static final int REQUEST_ENABLE_BT = 2;
    private static final int REQUEST_DIAG_CMD = 3;
    private static final int UART_PROFILE_READY = 10;
    public static final String TAG = "Hairclip_MainActivity";
    private static final int UART_PROFILE_CONNECTED = 20;
    private static final int UART_PROFILE_DISCONNECTED = 21;
    private static final int STATE_OFF = 10;

    TextView mRemoteRssiVal;
    RadioGroup mRg;
    public int mState = UART_PROFILE_DISCONNECTED;
    public static UartService mService = null;
    private BluetoothDevice mDevice = null;
    private BluetoothAdapter mBtAdapter = null;
    private ListView messageListView;
    private ArrayAdapter<String> listAdapter;
    private Button btnConnectDisconnect, btnSend;
    private EditText edtMessage;
    private byte[] dcmd;
    public boolean armed = false;
    public boolean alarmsent = false;
    public static ByteArrayOutputStream adStream = new ByteArrayOutputStream(100000); //size grows if needed
    public static ByteArrayOutputStream SensorStream = new ByteArrayOutputStream(10000); // "
    public static int expectedAudioSamples = 8000; //8000 sps, 1 byte per sample
    public static int expectedSensorSamples = 100 * 12; //100 sps, 12 bytes per sample (2 bytes each Ax, Ay, Az, Rr, Rp, Ry)
    public static boolean demomode = true;
    public static Button c1, c2, dm1, dm2, sb1, sb2, sb3, alonb, aloffb;
    public static TextView stxt;

    // URLs
    private static final Uri URL_FS = Uri.parse("http://www.firstsign.us");

    // constants
    protected static final int FILETYPEAUDIO = 0;
    protected static final int FILETYPESENSOR = 1;
    private static final int ALARMAUDIOSAMPLES = 8000 * 10; //60 * 1; //FIXME before releasing - 10 seconds
    private static final int ALARMSENSORSAMPLES = 192 * 12 * 1; //FIXME too

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.diag);

        mBtAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBtAdapter == null) {
            Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
            finish();
            return;
        }
        messageListView = (ListView) findViewById(R.id.listMessage);
        listAdapter = new ArrayAdapter<String>(this, R.layout.message_detail);
        messageListView.setAdapter(listAdapter);
        messageListView.setDivider(null);
        btnConnectDisconnect = (Button) findViewById(R.id.btn_select);
        btnSend = (Button) findViewById(R.id.sendButton);
        edtMessage = (EditText) findViewById(R.id.sendText);

        // top level select either demo mode or diag mode
        dm1 = (Button) findViewById(R.id.DemoModeButton);
        dm2 = (Button) findViewById(R.id.DiagModeButton);

        // make other controls invisible until mode is selected
        c1 = (Button) findViewById(R.id.Command1Button);
        c2 = (Button) findViewById(R.id.Command2Button);
        sb1 = (Button) findViewById(R.id.Sens1Button);
        sb2 = (Button) findViewById(R.id.Sens2Button);
        sb3 = (Button) findViewById(R.id.Sens3Button);
        stxt = (TextView) findViewById(R.id.textSensy);
        Log.d(TAG, "stext = " + stxt);
        alonb = (Button) findViewById(R.id.DemoAlarmOnButton);
        aloffb = (Button) findViewById(R.id.DemoAlarmOffButton);
        Log.d(TAG, "demomode = " + demomode);
        c1.setVisibility(View.INVISIBLE);
        c2.setVisibility(View.INVISIBLE);
        btnSend.setVisibility(View.INVISIBLE);
        edtMessage.setVisibility(View.INVISIBLE);
        messageListView.setVisibility(View.INVISIBLE);
        sb1.setVisibility(View.GONE);
        sb2.setVisibility(View.GONE);
        sb3.setVisibility(View.GONE);
        stxt.setVisibility(View.GONE);
        alonb.setVisibility(View.GONE);
        aloffb.setVisibility(View.GONE);

        service_init();

        // Handler Disconnect & Connect button
        btnConnectDisconnect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!mBtAdapter.isEnabled()) {
                    Log.i(TAG, "onClick - BT not enabled yet");
                    Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                    startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
                } else {
                    if (btnConnectDisconnect.getText().equals("Connect")) {

                        //Connect button pressed, open DeviceListActivity class, with popup windows that scan for devices

                        Intent newIntent = new Intent(MainActivity.this, DeviceListActivity.class);
                        startActivityForResult(newIntent, REQUEST_SELECT_DEVICE);
                    } else {
                        //Disconnect button pressed
                        if (mDevice != null) {
                            mService.disconnect();

                        }
                    }
                }
            }
        });
        // Handler Send button  
        btnSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EditText editText = (EditText) findViewById(R.id.sendText);
                String message = editText.getText().toString();
                byte[] value;
                try {
                    //send data to service
                    value = message.getBytes("UTF-8");
                    mService.writeRXCharacteristic(value);
                    //Update the log with time stamp
                    String currentDateTimeString = DateFormat.getTimeInstance().format(new Date());
                    listAdapter.add("[" + currentDateTimeString + "] TX: " + message);
                    messageListView.smoothScrollToPosition(listAdapter.getCount() - 1);
                    edtMessage.setText("");
                } catch (UnsupportedEncodingException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        });

    }

    // ----------------------------------------------------------------------------------------------------

    public void onDemoModeButton(View view) {
        c1.setVisibility(View.INVISIBLE);
        c2.setVisibility(View.INVISIBLE);
        btnSend.setVisibility(View.INVISIBLE);
        edtMessage.setVisibility(View.INVISIBLE);
        messageListView.setVisibility(View.INVISIBLE);

        dm1.setVisibility(View.GONE);
        dm2.setVisibility(View.GONE);
        stxt.setVisibility(View.VISIBLE);
        sb1.setVisibility(View.VISIBLE);
        sb2.setVisibility(View.VISIBLE);
        sb3.setVisibility(View.VISIBLE);
        alonb.setVisibility(View.VISIBLE);
        aloffb.setVisibility(View.VISIBLE);
    }

    public void onDiagModeButton(View view) {

        c1.setVisibility(View.VISIBLE);
        c2.setVisibility(View.VISIBLE);
        btnSend.setVisibility(View.INVISIBLE);
        edtMessage.setVisibility(View.INVISIBLE);
        messageListView.setVisibility(View.VISIBLE);

        dm1.setVisibility(View.GONE);
        dm2.setVisibility(View.GONE);
        sb1.setVisibility(View.GONE);
        sb2.setVisibility(View.GONE);
        sb3.setVisibility(View.GONE);
        stxt.setVisibility(View.GONE);
        alonb.setVisibility(View.GONE);
        aloffb.setVisibility(View.GONE);
    }

    public void onCommandButton(View view) {
        if (mState == UART_PROFILE_CONNECTED) {
            Intent i = new Intent(this, DiagActivity.class);
            startActivityForResult(i, REQUEST_DIAG_CMD);
        } else {
            showMessage("Not Connected");
        }
    }

    public void onCmd2Button(View view) {
        if (mState == UART_PROFILE_CONNECTED) {
            Intent i = new Intent(this, Cmd2Activity.class);
            startActivityForResult(i, REQUEST_DIAG_CMD);
        } else {
            showMessage("Not Connected");
        }
    }

    public void onSens1Button(View view) {
        if (mState == UART_PROFILE_CONNECTED) {
            //set accelerometer and gyro to low sensitivity
            byte[] value = { 0x04, 0x01, (byte) 0x7f };
            Log.d(TAG, "Set Gyro threshold = " + value[2]);
            mService.writeRXCharacteristic(value);
            byte[] value2 = { 0x04, 0x00, (byte) 0x40 };
            Log.d(TAG, "Set Acc threshold = " + value2[2]);
            mService.writeRXCharacteristic(value2);
            showMessage("Sensitivity LOW");
        } else {
            showMessage("Not Connected");
        }
    }

    public void onSens2Button(View view) {
        if (mState == UART_PROFILE_CONNECTED) {
            //set accelerometer and gyro to medium sensitivity
            //06112014 gyro adjust from 0x40 to 0x30 
            //06132014 gyro adjust from 0x28 to 0x7f
            byte[] value = { 0x04, 0x01, (byte) 0x7f };
            Log.d(TAG, "Set Gyro threshold = " + value[2]);
            mService.writeRXCharacteristic(value);
            //06102014 customer says not sensitive enough
            //byte[] value2 = {0x04,0x00,(byte)0x10};
            byte[] value2 = { 0x04, 0x00, (byte) 0x08 };
            Log.d(TAG, "Set Acc threshold = " + value2[2]);
            mService.writeRXCharacteristic(value2);
            showMessage("Sensitivity MED");
        } else {
            showMessage("Not Connected");
        }
    }

    public void onSens3Button(View view) {
        if (mState == UART_PROFILE_CONNECTED) {
            //set accelerometer and gyro to high sensitivity
            //06132014 gyro adjust from 0x10 to 0x7f
            byte[] value = { 0x04, 0x01, (byte) 0x7f };
            Log.d(TAG, "Set Gyro threshold = " + value[2]);
            mService.writeRXCharacteristic(value);
            byte[] value2 = { 0x04, 0x00, (byte) 0x04 };
            Log.d(TAG, "Set Acc threshold = " + value2[2]);
            mService.writeRXCharacteristic(value2);
            showMessage("Sensitivity HIGH");
        } else {
            showMessage("Not Connected");
        }
    }

    public void onDemoAlarmOnButton(View view) {
        if (mState == UART_PROFILE_CONNECTED) {
            Log.d(TAG, "Demo Alarm On button pressed");
            byte[] value = { 0x05, 0x00 };
            mService.writeRXCharacteristic(value);
            armed = true;
            alarmsent = false;
            adStream.reset(); // reset audio data buffer
            expectedAudioSamples = ALARMAUDIOSAMPLES; // set to default number of samples
            SensorStream.reset(); // reset sensor data buffer
            expectedSensorSamples = ALARMSENSORSAMPLES; // set to default
            showMessage("Alarm On");
        } else {
            showMessage("Not Connected");
        }
    }

    public void onDemoAlarmOffButton(View view) {
        if (mState == UART_PROFILE_CONNECTED) {
            Log.d(TAG, "Demo Alarm Off button pressed");
            byte[] value = { 0x05, 0x01 };
            mService.writeRXCharacteristic(value);
            armed = false;
            showMessage("Alarm Off");
        } else {
            showMessage("Not Connected");
        }
    }

    public void onTestButton(View view) {
        //placeholder for debug tests. modify as needed

        //--------- test alarm activity ---------
        //Intent alarmintent = new Intent(getApplicationContext(), AlarmActivity.class);
        //startActivity(alarmintent);

        //-------- test wavefile writes -----
        /*
           byte[] testbuff = new byte[128000];
            
        //byte[] testbuff = {0,1,2,3,4,5,6,7,8,9};
           //saverawaudio(testbuff);
        for(int i=0;i<testbuff.length;i++)   {
           testbuff[i] = (byte) (int)(0.5 * (127 * Math.sin(2.0 * Math.PI * 440 * i /8000) + 127.5) +
                           0.5 * (127 * Math.sin(2.0 * Math.PI * 350 * i /8000) + 127.5));
        }
           saverawdata(testbuff,FILETYPEAUDIO);
           savewavefile(testbuff);
           */

        // display audio buffer length
        showMessage("Audio samples = " + adStream.size());
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        // if (id == R.id.action_settings) {
        //     return true;
        //}
        switch (item.getItemId()) {
        case android.R.id.home:
            onBackPressed();
            return true;
        case R.id.action_settings:
            showMessage("settings");
            break;
        case R.id.opt_about:
            onUrl(URL_FS);
            break;
        case R.id.opt_exit:
            finish();
            break;
        default:
            return super.onOptionsItemSelected(item);
        }
        return true;

    }

    private void onUrl(Uri uri) {
        Intent web = new Intent(Intent.ACTION_VIEW, uri);
        startActivity(web);
    }

    //UART service connected/disconnected
    private ServiceConnection mServiceConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder rawBinder) {
            mService = ((UartService.LocalBinder) rawBinder).getService();
            Log.d(TAG, "onServiceConnected mService= " + mService);
            if (!mService.initialize()) {
                Log.e(TAG, "Unable to initialize Bluetooth");
                finish();
            }

        }

        public void onServiceDisconnected(ComponentName classname) {
            ////     mService.disconnect(mDevice);
            mService = null;
        }
    };

    private Handler mHandler = new Handler() {
        @Override

        //Handler events that received from UART service 
        public void handleMessage(Message msg) {

        }
    };

    private final BroadcastReceiver UARTStatusChangeReceiver = new BroadcastReceiver() {

        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            final Intent mIntent = intent;

            //*********************//
            if (action.equals(UartService.ACTION_GATT_CONNECTED)) {
                runOnUiThread(new Runnable() {
                    public void run() {
                        String currentDateTimeString = DateFormat.getTimeInstance().format(new Date());
                        Log.d(TAG, "UART_CONNECT_MSG");
                        btnConnectDisconnect.setText("Disconnect");
                        //edtMessage.setEnabled(true);
                        //btnSend.setEnabled(true);
                        ((TextView) findViewById(R.id.deviceName))
                                .setText(mDevice.getName() + " - Connected and Monitoring");
                        listAdapter.add("[" + currentDateTimeString + "] Connected to: " + mDevice.getName());
                        messageListView.smoothScrollToPosition(listAdapter.getCount() - 1);
                        mState = UART_PROFILE_CONNECTED;
                    }
                });
            }

            //*********************//
            if (action.equals(UartService.ACTION_GATT_DISCONNECTED)) {
                runOnUiThread(new Runnable() {
                    public void run() {
                        String currentDateTimeString = DateFormat.getTimeInstance().format(new Date());
                        Log.d(TAG, "UART_DISCONNECT_MSG");
                        btnConnectDisconnect.setText("Connect");
                        //edtMessage.setEnabled(false);
                        // btnSend.setEnabled(false);
                        ((TextView) findViewById(R.id.deviceName)).setText("Not Connected");
                        listAdapter.add("[" + currentDateTimeString + "] Disconnected to: " + mDevice.getName());
                        mState = UART_PROFILE_DISCONNECTED;
                        mService.close();
                        //setUiState();

                    }
                });
            }

            //*********************//
            if (action.equals(UartService.ACTION_GATT_SERVICES_DISCOVERED)) {
                mService.enableTXNotification();
            }
            //*********************//
            if (action.equals(UartService.ACTION_DATA_AVAILABLE)) {
                // --------------------------------------------------------------
                // Data has been received from Hairclip
                // --------------------------------------------------------------

                // get data from uart service
                final byte[] txValue = intent.getByteArrayExtra(UartService.EXTRA_DATA);

                // alarm
                if ((armed && !alarmsent && (txValue[0] == (byte) 0x55) && (txValue[1] == (byte) 0xaa))
                        || ((txValue[0] == (byte) 0x55) && (txValue[1] == (byte) 0xab))) {
                    Log.d(TAG, "alarm2: " + "0x" + Integer.toHexString(txValue[0] & 0xff) + " 0x"
                            + Integer.toHexString(txValue[1] & 0xff));
                    Intent alarmintent = new Intent(getApplicationContext(), AlarmActivity.class);
                    startActivity(alarmintent);
                    try {
                        // turn off alarm notifications
                        byte[] value = { 0x05, 0x01 };
                        mService.writeRXCharacteristic(value);

                        //06112014 turn off data collection to allow quick re-trigger for demos
                        // get sensor data for alarm event
                        //value[0] = 0x06;
                        //value[1] = 0x00;
                        //mService.writeRXCharacteristic(value);

                        // get audio data for alarm event
                        //value[0] = 0x06;
                        //value[1] = 0x01;
                        //mService.writeRXCharacteristic(value);
                    } catch (Exception e) {
                        Log.e(TAG, e.toString());
                    }
                    alarmsent = true;
                }

                // audio data
                else if ((txValue[0] == (byte) 0x07 && txValue[1] == (byte) 0x03)
                        || (txValue[0] == (byte) 0x06 && txValue[1] == (byte) 0x01)) { // audio data
                    // append data to audio buffer 
                    // future - make more robust with save on timeout
                    if (expectedAudioSamples > 0) {
                        if (adStream.size() < expectedAudioSamples)
                            adStream.write(txValue, 2, txValue.length - 2);
                        if (adStream.size() >= expectedAudioSamples) {
                            Log.d(TAG, "adStream complete. buffer filled to: " + adStream.size());
                            saverawdata(adStream.toByteArray(), FILETYPEAUDIO);
                            savewavefile(adStream.toByteArray());
                            expectedAudioSamples = 0;
                        }
                    }
                }

                // sensor data
                else if ((txValue[0] == (byte) 0x07 && txValue[1] == (byte) 0x01)
                        || (txValue[0] == (byte) 0x06 && txValue[1] == (byte) 0x00)) { // sensor data
                    // append data to sensor buffer - up to expected number of samples
                    // future - make more robust with save on timeout
                    if (expectedSensorSamples > 0) {
                        if (SensorStream.size() < expectedSensorSamples) {
                            if (txValue[0] == (byte) 0x07) //diag sensor data includes 2 byte pkt# in header
                                SensorStream.write(txValue, 4, txValue.length - 4); //add data to buffer, skip first 4 header bytes
                            else
                                SensorStream.write(txValue, 2, txValue.length - 2); //add data to buffer, skip first 2 header bytes
                            Log.d(TAG, "SensorStream Buffer filled to: " + SensorStream.size());
                        }

                        if (SensorStream.size() >= expectedSensorSamples) {
                            Log.d(TAG, "SensorStream complete. Buffer filled to: " + SensorStream.size());
                            saverawdata(SensorStream.toByteArray(), FILETYPESENSOR);
                            expectedSensorSamples = 0;
                        }
                    } else
                        Log.d(TAG, "received more sensor data than expected");
                }

                runOnUiThread(new Runnable() {
                    public void run() {
                        try {
                            //String text = new String(txValue, "UTF-8");
                            Log.d(TAG, "txValue.length = " + txValue.length);
                            String msg = "";
                            for (int i = 0; i < txValue.length; i++) {
                                msg = msg + "0x" + Integer.toHexString(txValue[i] & 0xff) + " ";
                            }
                            String currentDateTimeString = DateFormat.getTimeInstance().format(new Date());
                            listAdapter.add("[" + currentDateTimeString + "] RX: " + msg);
                            messageListView.smoothScrollToPosition(listAdapter.getCount() - 1);

                        } catch (Exception e) {
                            Log.e(TAG, e.toString());
                        }
                    }
                });
            }
            //*********************//
            if (action.equals(UartService.DEVICE_DOES_NOT_SUPPORT_UART)) {
                showMessage("Device doesn't support UART service. Disconnecting");
                mService.disconnect();
            }

        }
    };

    private void service_init() {
        Intent bindIntent = new Intent(this, UartService.class);
        bindService(bindIntent, mServiceConnection, Context.BIND_AUTO_CREATE);

        LocalBroadcastManager.getInstance(this).registerReceiver(UARTStatusChangeReceiver,
                makeGattUpdateIntentFilter());
    }

    private static IntentFilter makeGattUpdateIntentFilter() {
        final IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(UartService.ACTION_GATT_CONNECTED);
        intentFilter.addAction(UartService.ACTION_GATT_DISCONNECTED);
        intentFilter.addAction(UartService.ACTION_GATT_SERVICES_DISCOVERED);
        intentFilter.addAction(UartService.ACTION_DATA_AVAILABLE);
        intentFilter.addAction(UartService.DEVICE_DOES_NOT_SUPPORT_UART);
        return intentFilter;
    }

    @Override
    public void onStart() {
        super.onStart();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy()");

        try {
            LocalBroadcastManager.getInstance(this).unregisterReceiver(UARTStatusChangeReceiver);
        } catch (Exception ignore) {
            Log.e(TAG, ignore.toString());
        }
        unbindService(mServiceConnection);
        mService.stopSelf();
        mService = null;

    }

    @Override
    protected void onStop() {
        Log.d(TAG, "onStop");
        super.onStop();
    }

    @Override
    protected void onPause() {
        Log.d(TAG, "onPause");
        super.onPause();
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d(TAG, "onRestart");
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.d(TAG, "onResume");
        if (!mBtAdapter.isEnabled()) {
            Log.i(TAG, "onResume - BT not enabled yet");
            Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
        }

    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {

        case REQUEST_SELECT_DEVICE:
            //When the DeviceListActivity return, with the selected device address
            if (resultCode == Activity.RESULT_OK && data != null) {
                String deviceAddress = data.getStringExtra(BluetoothDevice.EXTRA_DEVICE);
                mDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(deviceAddress);

                Log.d(TAG, "... onActivityResultdevice.address==" + mDevice + "mserviceValue" + mService);
                ((TextView) findViewById(R.id.deviceName)).setText(mDevice.getName() + " - connecting");
                mService.connect(deviceAddress);

            }
            break;
        case REQUEST_ENABLE_BT:
            // When the request to enable Bluetooth returns
            if (resultCode == Activity.RESULT_OK) {
                Toast.makeText(this, "Bluetooth has turned on ", Toast.LENGTH_SHORT).show();

            } else {
                // User did not enable Bluetooth or an error occurred
                Log.d(TAG, "BT not enabled");
                Toast.makeText(this, "Problem in BT Turning ON ", Toast.LENGTH_SHORT).show();
                finish();
            }
            break;
        case REQUEST_DIAG_CMD:
            if (resultCode == Activity.RESULT_OK) {
                byte[] value = data.getByteArrayExtra("cmd");
                Log.d(TAG, "Diag command request success. length = " + value.length + ", 0x"
                        + Integer.toHexString(value[0] & 0xff) + ", " + value[0]);
                if (value[0] == (byte) 0x05) { //alarm arm/disarm
                    if (value[1] == (byte) 0x00) {
                        armed = true;
                        alarmsent = false;
                        adStream.reset(); // reset audio data buffer
                        expectedAudioSamples = ALARMAUDIOSAMPLES; // set to default number of samples
                        SensorStream.reset(); // reset sensor data buffer
                        expectedSensorSamples = ALARMSENSORSAMPLES; // set to default
                    } else
                        armed = false;
                }
                try {
                    mService.writeRXCharacteristic(value);
                } catch (Exception e) {
                    Log.e(TAG, e.toString());
                }
                ;

                //Update the log with time stamp and message sent
                String msg = "";
                for (int i = 0; i < value.length; i++) {
                    msg = msg + "0x" + Integer.toHexString(value[i] & 0xff) + " ";
                }
                String currentDateTimeString = DateFormat.getTimeInstance().format(new Date());
                listAdapter.add("[" + currentDateTimeString + "] TX: " + msg);
                messageListView.smoothScrollToPosition(listAdapter.getCount() - 1);
            } else {
                Log.d(TAG, "Diag command request result fail");
            }
            break;
        default:
            Log.e(TAG, "bad activity result request code");
            break;
        }
    }

    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {

    }

    public void saverawdata(byte[] ra, int type) {
        String filename;
        boolean usetext = true;

        if (type == FILETYPEAUDIO)
            filename = "rawaudio.dat";
        else {
            if (usetext)
                filename = "rawsensor.csv";
            else
                filename = "rawsensor.dat";
        }

        try {
            //FileOutputStream adfos = openFileOutput(filename, Context.MODE_PRIVATE);
            //FileOutputStream adfos = openFileOutput(filename, Context.MODE_WORLD_READABLE);
            String state = Environment.getExternalStorageState();
            Log.d(TAG, "External storage state: " + state);
            if (Environment.MEDIA_MOUNTED.equals(state)) {

                //create firstsign directory
                File rootPath = new File(Environment.getExternalStorageDirectory(), "firstsign");
                if (!rootPath.exists()) {
                    rootPath.mkdirs();
                    Log.d(TAG, "mkdirs");
                }
                File file = new File(rootPath, filename);
                file.createNewFile();
                OutputStream os = new FileOutputStream(file);
                BufferedOutputStream bos = new BufferedOutputStream(os);
                DataOutputStream rf = new DataOutputStream(bos);

                if (usetext) {
                    rf.write("Ax Ay Az Rr Rp Ry\n".getBytes());
                    for (int i = 0, j = 0; i < ra.length; i += 2) {
                        short sval = (short) ((ra[i] << 8) | (ra[i + 1] & 0xff));
                        //Log.d(TAG,"sval = " + sval);
                        String ssval = Short.toString(sval) + " ";
                        j++;
                        if (j % 6 == 0)
                            ssval += "\n";
                        rf.write(ssval.getBytes());
                    }
                } else {
                    rf.write(ra);
                }

                File rfile = getFileStreamPath(filename);
                Log.d(TAG, "path: " + rfile);
                Log.d(TAG, "raw file write: " + filename + ra + "size = " + ra.length);
                rf.close();
                bos.close();
                os.close();
            } else {
                Toast.makeText(this, "SDCard not mounted", Toast.LENGTH_LONG).show();
            } //what do i do?

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void savewavefile(byte[] ra) {
        //prepend 44 byte wave header to data

        int sampleRate = 8000; // audio sample rate is 8000 SPS
        int numSecs = ra.length / sampleRate; // number of seconds of audio to record
        int samples = sampleRate * numSecs; // number of samples in file
        short bitsPerSample = 8; // one byte per sample
        int filesize = samples + 44; // check this?
        int fmtChunkSize = 16; // size of 'fmt' chunk
        short channels = 1; // mono
        int byteRate = sampleRate * channels * bitsPerSample / 8; // will be 8K for us
        short format = 1; // 1 == uncompressed pcm
        short blockalign = (short) (channels * bitsPerSample / 8); // bytes per sample
        int audiolen = samples * channels * bitsPerSample / 8; // length of audio in bytes

        try {
            //OutputStream os = openFileOutput("diagaudio.wav", Context.MODE_PRIVATE);
            String state = Environment.getExternalStorageState();
            Log.d(TAG, "External storage state: " + state);
            if (Environment.MEDIA_MOUNTED.equals(state)) {

                //create firstsign directory
                File rootPath = new File(Environment.getExternalStorageDirectory(), "firstsign");
                if (!rootPath.exists()) {
                    rootPath.mkdirs();
                    Log.d(TAG, "mkdirs");
                }
                File file = new File(rootPath, "hairclipaudio.wav");
                file.createNewFile();
                OutputStream os = new FileOutputStream(file);
                BufferedOutputStream bos = new BufferedOutputStream(os);
                DataOutputStream wf = new DataOutputStream(bos);

                wf.write("RIFF".getBytes());
                wf.writeInt(Integer.reverseBytes(filesize - 8));
                wf.write("WAVE".getBytes());
                wf.write("fmt ".getBytes());
                wf.writeInt(Integer.reverseBytes(fmtChunkSize));
                wf.writeShort(Short.reverseBytes(format));
                wf.writeShort(Short.reverseBytes(channels));
                wf.writeInt(Integer.reverseBytes(sampleRate));
                wf.writeInt(Integer.reverseBytes(byteRate));
                wf.writeShort(Short.reverseBytes(blockalign));
                wf.writeShort(Short.reverseBytes(bitsPerSample));
                wf.write("data".getBytes());
                wf.writeInt(Integer.reverseBytes(audiolen));
                wf.write(ra);

                wf.close();
                bos.close();
                os.close();

                Log.d(TAG, "wavefile write complete");
            } else {
                Toast.makeText(this, "SDCard not mounted", Toast.LENGTH_LONG).show();
            } //what do i do?

        } catch (Exception e) {
            Log.e(TAG, "exception in savewavefile");
            e.printStackTrace();
        }

    }

    public void showMessage(String msg) {
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();

    }

    @Override
    public void onBackPressed() {
        if (mState == UART_PROFILE_CONNECTED) {
            Intent startMain = new Intent(Intent.ACTION_MAIN);
            startMain.addCategory(Intent.CATEGORY_HOME);
            startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(startMain);
            showMessage("Hairclip demo running in background.\n             Disconnect to exit");
        } else {
            new AlertDialog.Builder(this).setIcon(android.R.drawable.ic_dialog_alert).setTitle(R.string.popup_title)
                    .setMessage(R.string.popup_message)
                    .setPositiveButton(R.string.popup_yes, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            finish();
                        }
                    }).setNegativeButton(R.string.popup_no, null).show();
        }
    }
}