Search code examples
javaandroidlistviewandroid-studioandroid-sensors

Handle stream of data sensor


I'm trying to write a code I can write all the results values from accelerometer sensor into a .txt file. I can't write all the data in somehow. I think there is a problem in my loop. It is just reading about 10 to 15 samples. How can I write all the values of the sensor into that file until I toggle off the button to stop? here is the code I wrote. Thanks in advance!

public class MainActivity extends Activity implements SensorEventListener {
public SensorManager sm;
Sensor accelermeter;

private static final String DEBUG = "LogAccelermeter";
ToggleButton OnStore;
Button OffStore;
Button btnOn, btnOff;
TextView txtArduino, txtString, txtStringLength, sensorView0, sensorView1, sensorView2, sensorView3;
Handler bluetoothIn;

final int handlerState = 0;                         //used to identify handler message
private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket = null;
private StringBuilder recDataString = new StringBuilder();

private ConnectedThread mConnectedThread;

// SPP UUID service - this should work for most devices
private static final UUID BTMODULEUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
TextView sensorText;
// String for MAC address
private static String address;
private GestureDetectorCompat mDetector;
FileOutputStream fileOutputStream;

double TotalAccelerate;
ArrayList<Double> list;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    list = new ArrayList<Double>();

     //Link the buttons and textViews to respective views
    btnOn = (Button) findViewById(R.id.buttonOn);
    btnOff = (Button) findViewById(R.id.buttonOff);
    txtString = (TextView) findViewById(R.id.txtString);
    txtStringLength = (TextView) findViewById(R.id.testView1);
    sensorView0 = (TextView) findViewById(R.id.sensorView0);
    sensorView1 = (TextView) findViewById(R.id.sensorView1);
    sensorView2 = (TextView) findViewById(R.id.sensorView2);
    sensorView3 = (TextView) findViewById(R.id.sensorView3);

    //for Accelermeter
    sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    sensorText = (TextView) findViewById(R.id.sensor);
    accelermeter = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    sm.registerListener(this, accelermeter, SensorManager.SENSOR_DELAY_NORMAL);
    mDetector = new GestureDetectorCompat(this, new MyGestureListener());


    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        File Root = Environment.getExternalStorageDirectory();
        File dir = new File(Root.getAbsolutePath() + "/MyApp");
        if (!dir.exists()) {
            dir.mkdir();
        }
        File file = new File(dir, "MyMessage.txt");
        try {
            fileOutputStream = new FileOutputStream(file, true);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    } else {
        Toast.makeText(getApplicationContext(), "SDcard not found", Toast.LENGTH_LONG).show();
    }

    OnStore = (ToggleButton) findViewById(R.id.onStore);
    OnStore.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View view) {
            if (OnStore.isChecked()){
                try {
                    for(double TotalAccelerate : list){
                     //   System.out.println("final"+ TotalAccelerate);
                        String space = "\n";
                        byte[] convert = space.getBytes();
                        fileOutputStream.write(convert);
                        String finalData;
                        finalData = String.valueOf(TotalAccelerate);
                        fileOutputStream.write(finalData.getBytes());
                        Log.i(DEBUG, "ans: " + finalData);
                    }
                    // fileOutputStream.close();
                    Toast.makeText(getApplicationContext(), "Message saving", Toast.LENGTH_LONG).show();

                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }if (!OnStore.isChecked()){
                try {
                    fileOutputStream.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    fileOutputStream.close();
                    list.clear();
                    Collections.synchronizedList(list);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                Toast.makeText(getApplicationContext(),"Message Stopped.",Toast.LENGTH_LONG).show();

            }


        }

    });


    bluetoothIn = new Handler() {
        public void handleMessage(android.os.Message msg) {
            if (msg.what == handlerState) {                                        //if message is what we want
                String readMessage = (String) msg.obj;                        // msg.arg1 = bytes from connect thread
                recDataString.append(readMessage);                                    //keep appending to string until ~
                int endOfLineIndex = recDataString.indexOf("~");                    // determine the end-of-line
                if (endOfLineIndex > 0) {                                           // make sure there data before ~
                    String dataInPrint = recDataString.substring(0, endOfLineIndex);    // extract string
                    txtString.setText("Data Received = " + dataInPrint);
                    int dataLength = dataInPrint.length();                            //get length of data received
                    txtStringLength.setText("String Length = " + String.valueOf(dataLength));

                    if (recDataString.charAt(0) == '#')    //if it starts with # we know it is what we are looking for
                    {
                        String sensor0 = recDataString.substring(1, 5);             //get sensor value from string between indices 1-5
                        String sensor1 = recDataString.substring(6, 10);            //same again...
                        String sensor2 = recDataString.substring(11, 15);
                        String sensor3 = recDataString.substring(16, 20);

                        sensorView0.setText(" Sensor 0 Voltage = " + sensor0 + "V");    //update the textviews with sensor values
                        sensorView1.setText(" Sensor 1 Voltage = " + sensor1 + "V");
                        sensorView2.setText(" Sensor 2 Voltage = " + sensor2 + "V");
                        sensorView3.setText(" Sensor 3 Voltage = " + sensor3 + "V");
                    }
                    recDataString.delete(0, recDataString.length());                    //clear all string data
                    // strIncom =" ";
                    dataInPrint = " ";
                }
            }
        }
    };

    btAdapter = BluetoothAdapter.getDefaultAdapter();       // get Bluetooth adapter
    checkBTState();

    // Set up onClick listeners for buttons to send 1 or 0 to turn on/off LED
    btnOff.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            mConnectedThread.write("0");    // Send "0" via Bluetooth
            Toast.makeText(getBaseContext(), "Turn off LED", Toast.LENGTH_SHORT).show();
        }
    });
    btnOn.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            mConnectedThread.write("1");    // Send "1" via Bluetooth
            Toast.makeText(getBaseContext(), "Turn on LED", Toast.LENGTH_SHORT).show();
        }
    });

}//end OnCreate Method

@Override
public final void onAccuracyChanged(Sensor sensor, int accuracy) {
    // Do something here if sensor accuracy changes.
}

@Override
public final void onSensorChanged(SensorEvent event) {
    // The light sensor returns a single value.
    // Many sensors return 3 values, one for each axis.
    double xx = event.values[0];
    double yy = event.values[1];
    double zz = event.values[2];
    TotalAccelerate = Math.round(Math.sqrt(Math.pow(xx, 2)
            + Math.pow(yy, 2)
            + Math.pow(zz, 2)));
    Log.i(DEBUG, "Accelerometer = " + TotalAccelerate);

    list.add(TotalAccelerate);
    findPeaks(list);
   sensorText.setText("Total: " + TotalAccelerate);
    Log.i(DEBUG, "list values " + list);

}

//Find peak values.
public static ArrayList<Double> findPeaks(List<Double> points) {
    ArrayList<Double> peaks = new ArrayList<Double>();

    if (points == null || points.size() < 1)
        return peaks;

    Double x1_n_ref = 0.0;
    int alpha = 0; //0=down, 1=up.
    int size = points.size();// -1)/100;
    for (int i = 0; i < size; i += 5) {
        Double IndexValues = points.get(i);
        if (IndexValues > 9) {
            Double delta = (x1_n_ref - IndexValues);
            if (delta < 0) {
                x1_n_ref = IndexValues;
                alpha = 1;

            } else if (alpha == 1 && delta > 0) {
                peaks.add(x1_n_ref);

                alpha = 0;
            }

        } else if (alpha == 0) {
            x1_n_ref = IndexValues;
        }
    }

    return peaks;
}


@Override
public boolean onTouchEvent(MotionEvent event) {
    this.mDetector.onTouchEvent(event);
    return super.onTouchEvent(event);
}

class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
    private static final String DEBUG_TAG = "Gestures";

    @Override
    public boolean onDown(MotionEvent event) {
        Log.d(DEBUG_TAG, "onDown: " + event.toString());
        Toast.makeText(getApplication(), "OnDown Touch Occur", Toast.LENGTH_LONG).show();
        if (event.getX() > 0) {
            mConnectedThread.write("1");
        }
        return true;
    }

    @Override
    public void onLongPress(MotionEvent event) {
        Log.d(DEBUG_TAG, "onLongPress: " + event.toString());
        mConnectedThread.write("0");

    }

private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {

    return device.createRfcommSocketToServiceRecord(BTMODULEUUID);
    //creates secure outgoing connecetion with BT device using UUID
}

@Override
public void onResume() {
    super.onResume();

    //Get MAC address from DeviceListActivity via intent
    Intent intent = getIntent();

    //Get the MAC address from the DeviceListActivty via EXTRA
    address = intent.getStringExtra(DeviceListActivity.EXTRA_DEVICE_ADDRESS);

    //create device and set the MAC address
    BluetoothDevice device = btAdapter.getRemoteDevice(address);

    try {
        btSocket = createBluetoothSocket(device);
    } catch (IOException e) {
        Toast.makeText(getBaseContext(), "Socket creation failed", Toast.LENGTH_LONG).show();
    }
    // Establish the Bluetooth socket connection.
    try {
        btSocket.connect();
    } catch (IOException e) {
        try {
            btSocket.close();
        } catch (IOException e2) {
            //insert code to deal with this
        }
    }
    mConnectedThread = new ConnectedThread(btSocket);
    mConnectedThread.start();

    //I send a character when resuming.beginning transmission to check device is connected
    //If it is not an exception will be thrown in the write method and finish() will be called
    mConnectedThread.write("x");
}

@Override
public void onPause() {
    super.onPause();
    try {
        //Don't leave Bluetooth sockets open when leaving activity
        btSocket.close();
    } catch (IOException e2) {
        //insert code to deal with this
    }
}

//Checks that the Android device Bluetooth is available and prompts to be turned on if off
private void checkBTState() {

    if (btAdapter == null) {
        Toast.makeText(getBaseContext(), "Device does not support bluetooth", Toast.LENGTH_LONG).show();
    } else {
        if (btAdapter.isEnabled()) {
        } else {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, 1);
        }
    }
}

//create new class for connect thread
private class ConnectedThread extends Thread {
    private final InputStream mmInStream;
    private final OutputStream mmOutStream;

    //creation of the connect thread
    public ConnectedThread(BluetoothSocket socket) {
        InputStream tmpIn = null;
        OutputStream tmpOut = null;

        try {
            //Create I/O streams for connection
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();
        } catch (IOException e) {
        }

        mmInStream = tmpIn;
        mmOutStream = tmpOut;
    }


    public void run() {
        byte[] buffer = new byte[256];
        int bytes;

        // Keep looping to listen for received messages
        while (true) {
            try {
                bytes = mmInStream.read(buffer);            //read bytes from input buffer
                String readMessage = new String(buffer, 0, bytes);
                // Send the obtained bytes to the UI Activity via handler
                bluetoothIn.obtainMessage(handlerState, bytes, -1, readMessage).sendToTarget();
            } catch (IOException e) {
                break;
            }
        }
    }

    //write method
    public void write(String input) {
        byte[] msgBuffer = input.getBytes();           //converts entered String into bytes
        try {
            mmOutStream.write(msgBuffer);                //write bytes over BT connection via outstream
        } catch (IOException e) {
            //if you cannot write, close the application
            Toast.makeText(getBaseContext(), "Connection Failure", Toast.LENGTH_LONG).show();
            finish();

        }
    }
}

}


Solution

  • Could you try this for the toggle button onClick callback? It should write all the data when it's unchecked.

    OnStore.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View view) {
            if (OnStore.isChecked()){
                // should do nothing
            } else if (!OnStore.isChecked()){
                try {
                    for(double TotalAccelerate : list){
                        //System.out.println("final"+ TotalAccelerate);
                        String space = "\n";
                        byte[] convert = space.getBytes();
                        fileOutputStream.write(convert);
                        String finalData;
                        finalData = String.valueOf(TotalAccelerate);
                        fileOutputStream.write(finalData.getBytes());
                        Log.i(DEBUG, "ans: " + finalData);
                    }
                    fileOutputStream.flush();
                    fileOutputStream.close();
                    Toast.makeText(getApplicationContext(), "Message saving", Toast.LENGTH_LONG).show();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                Toast.makeText(getApplicationContext(),"Message Stopped.",Toast.LENGTH_LONG).show();
            }
        }
    });
    

    To regulate the code to start/stop listen to the sensor event, add the following variable somewhere in this class:

    private boolean isListening = false;
    

    And make the following modifications to your existing code:

    OnStore.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View view) {
            if (OnStore.isChecked()){
                //
                // set listening flag to true
                //
                isListening = true;
            } else if (!OnStore.isChecked()){
                //
                // set listening flag to false
                //
                isListening = false;
                try {
                    for(double TotalAccelerate : list){
                        //System.out.println("final"+ TotalAccelerate);
                        String space = "\n";
                        byte[] convert = space.getBytes();
                        fileOutputStream.write(convert);
                        String finalData;
                        finalData = String.valueOf(TotalAccelerate);
                        fileOutputStream.write(finalData.getBytes());
                        Log.i(DEBUG, "ans: " + finalData);
                    }
                    fileOutputStream.flush();
                    fileOutputStream.close();
                    Toast.makeText(getApplicationContext(), "Message saving", Toast.LENGTH_LONG).show();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                Toast.makeText(getApplicationContext(),"Message Stopped.",Toast.LENGTH_LONG).show();
            }
        }
    });
    
    
    @Override
    public final void onSensorChanged(SensorEvent event) {
        // The light sensor returns a single value.
        // Many sensors return 3 values, one for each axis.
        //
        // regulate
        //
        if (isListening) {
            double xx = event.values[0];
            double yy = event.values[1];
            double zz = event.values[2];
            TotalAccelerate = Math.round(Math.sqrt(Math.pow(xx, 2)
                + Math.pow(yy, 2)
                + Math.pow(zz, 2)));
            Log.i(DEBUG, "Accelerometer = " + TotalAccelerate);
    
            list.add(TotalAccelerate);
            findPeaks(list);
            sensorText.setText("Total: " + TotalAccelerate);
            Log.i(DEBUG, "list values " + list);
        }
    }