Search code examples
androidandroid-asynctaskstoreaccelerometeronclicklistener

How to properly apply AsyncTask?


I am working on the following code, I looked into other questions such as AsyncTask Android example and How to properly use AsyncTask but I still have problems, could you please let me know what I am missing? Thanks a lot!!!

So, in UI I have a start button, s stop button, and a text view. I am getting the data from accelerometer sensor and store in a csv file. without using AsyncTask, the codes works fine, but when using it (as shown below), I get this error: a_datatest cannot be resolved to a variable

so, basically what I want is to start writing the accelerometer data in the background as soon as the start button is clicked, and then once the stop button is clicked, the text view shows "Data Stored!"

I appreciate any help!

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Criteria;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity implements SensorEventListener, OnClickListener {

    private SensorManager sensorManager;
    private LocationManager locationManager;
    private Button start_bt;
    private Button stop_bt;
    private TextView result_view;
    private boolean started = false;
    String towers;    
    FileOutputStream fos;
    String FILENAME = "AccelOutput";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        Criteria crit = new Criteria();
        towers = locationManager.getBestProvider(crit, false);
        start_bt = (Button) findViewById(R.id.startButton);
        stop_bt = (Button) findViewById(R.id.stopButton);
        result_view = (TextView) findViewById(R.id.resultTextView);
        start_bt.setOnClickListener(this);
        stop_bt.setOnClickListener(this);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {        
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (started) {
            Sensor sensortype = event.sensor;

            if (sensortype.getType() == Sensor.TYPE_ACCELEROMETER) {

                double a_x = event.values[0];
                double a_y = event.values[1];
                double a_z = event.values[2];
                double a_a = event.accuracy;
                double a_ts = event.timestamp;
                long a_timestamp = System.currentTimeMillis();
                AccelData a_data = new AccelData(a_timestamp, a_ts, a_x, a_y, a_z, a_a);                
                String a_datatest = a_data.toString();

                new writeData().execute();
            }       
        }
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.startButton) {
            started = true;
            Sensor accel = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
            sensorManager.registerListener(this, accel, SensorManager.SENSOR_DELAY_FASTEST);
        } else if(v.getId() == R.id.stopButton) {
            started = false;
            sensorManager.unregisterListener(this);
        }
    }

    private class writeData extends AsyncTask<Void, Void, String>{

        @Override
        protected String doInBackground(Void... params) {
            // TODO Auto-generated method stub
            File sdCard = Environment.getExternalStorageDirectory();
            File directory = new File (sdCard.getAbsolutePath() + "/output");
            directory.mkdirs();

            String a_filename = "accelerometer.csv";
            File a_file = new File(directory, a_filename);
            FileOutputStream a_fOut = null;
            try {
                a_fOut = new FileOutputStream(a_file, true);
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            OutputStreamWriter a_osw = new OutputStreamWriter(a_fOut);
            try {
                a_osw.write(a_datatest + "\n");
                a_osw.flush();
                a_osw.close();
            } catch (IOException e) {

                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String result) {
              result_view.setText("Data Stored!"); 
        }
    }
}

Solution

  • declare the variable within the class scope. i.e use it as a member variable

    you are declaring a_datatest in onSensorChanged method so it has no validity out of this scope. So you can not use it in doInBackGround method

    delcare within the class like

    private String a_datatest;
    

    in onSensorChanged method use like

    a_datatest = a_data.toString();