不幸的是,Accelerometer已停止

时间:2014-12-09 20:48:58

标签: android android-asynctask accelerometer

我正在尝试编写一个收集不同传感器数据的Android应用程序,并使用它进行一些计算。我希望每50毫秒不断收集数据并将其存储为一个数组,当我们收集足够的数据(windowsize = 100)时,我们会对这些数据进行一些计算。

我使用AsyncTask作为计算部分。但我的问题是每当我开始计算时,应用程序都会出现问题并且我收到了这条消息:不幸的是,Accelerometer已停止

这是MainActivity代码:

package com.hrmb.accelometer;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.ExecutionException;

import android.hardware.SensorManager;
import android.location.Location;
import android.location.LocationManager;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.widget.TextView;

public class MainActivity extends Activity {    
SensorManager sm;   
TextView result_textView;
TextView result2_textView;
TextView textView1;
// the data variable stores the current window size data.
sensordata[] data;
sensordata currentdata = new sensordata();
sensors sensorobj;

private LocationManager lm;
locationReader locReader;
behaviorAnalyser analyser;          

// index in the data
private final int windowSize = constants.windowSize;
private int index =0;

//
private static final int sampleRate = 8000;
private AudioRecord audio;
private int bufferSize;
//private double lastLevel = 0;
private Thread thread;
private static final int SAMPLE_DELAY = constants.SAMPLE_DELAY;

@Override
protected void onCreate(Bundle savedInstanceState) {        

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE); 

    sm = (SensorManager) getSystemService(SENSOR_SERVICE);                       
    result_textView = (TextView) findViewById(R.id.result_textView);
    result2_textView = (TextView) findViewById(R.id.result2_textView);
    textView1 = (TextView) findViewById(R.id.textView1);

    textView1.append("onCreate\n");

    data = new sensordata[windowSize];
    sensorobj = new sensors(sm);        
    locReader = new locationReader(lm);
    analyser = new behaviorAnalyser();        

    try {
        bufferSize = AudioRecord
                .getMinBufferSize(sampleRate, AudioFormat.CHANNEL_IN_MONO,
                        AudioFormat.ENCODING_PCM_16BIT);
    } catch (Exception e) {
        android.util.Log.e("TrackingFlow", "Exception", e);
    }


}


@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;
}

protected void onResume() {
    textView1.append("onResume\n");

    super.onResume();               

    audio = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRate,
            AudioFormat.CHANNEL_IN_MONO,
            AudioFormat.ENCODING_PCM_16BIT, bufferSize);

    audio.startRecording();
    thread = new Thread(new Runnable() {
        public void run() {
            while(thread != null && !thread.isInterrupted()){
                //Let's make the thread sleep for a the approximate sampling time
                try{Thread.sleep(SAMPLE_DELAY);}catch(InterruptedException ie){ie.printStackTrace();}

                currentdata = sensorobj.getSensorData();
                readAudioBuffer();//After this call we can get the last value assigned to the currentdata.SOUNDLEVEL variable
                // read the data from other sensors                 

                Location myloc = locReader.getCurrentLocation();
                currentdata.LOC_LAT = (float) myloc.getLatitude();
                currentdata.LOC_LNG = (float) myloc.getLongitude();                                     

                //storing data into array
                index = index % windowSize;
                data[index] = currentdata;
                index ++;


                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {                                                                                                                 


                        if(index == (constants.windowSize -1)){
                            //calculating driving parameters
                            sensordata[] data2 = new sensordata[constants.windowSize];
                            System.arraycopy(data, 0, data2, 0, data.length);
                            drivingParameters result = new drivingParameters();
                            computeDrivingParams bt = new computeDrivingParams();
                            bt.execute(data2);  

                            try {
                                result = bt.get();
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            } catch (ExecutionException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }

                            result2_textView.setText(" Analyse Driving: \n" + "Num Turn Right: "+ result.numTurnRight + "\n" +
                                    "Num Turn Left: "+ result.numTurnLeft + "\n" +
                                    "Num Acceleration: "+ result.numAcceleration + "\n" + 
                                    "Num Breaks: "+ result.numBreaks + "\n");
                        }                                                                                                       

                        result_textView.setText("ACC X: "+ currentdata.ACC_X + " , ACC Y: "+ currentdata.ACC_Y +
                                " , ACC Z: "+ currentdata.ACC_Z + "\n" +
                                "GYR X: "+ currentdata.GYR_X + " , GYR Y: "+ currentdata.GYR_Y +
                                " , GYR Z: "+ currentdata.GYR_Z + "\n" + 
                                " LAT : "+ currentdata.LOC_LAT + " , LOG : "+ currentdata.LOC_LNG + "\n" +
                                currentdata.CURR_DATE + " , "+ currentdata.CURR_TIME + "\n" +
                                "noise: "+ currentdata.SOUNDLEVEL + "\n");
                    }
                });
            }
        }
    });
    thread.start();
}

/**
 * Functionality that gets the sound level out of the sample
 */
private void readAudioBuffer() {

    try {
        short[] buffer = new short[bufferSize];

        int bufferReadResult = 1;

        if (audio != null) {

            // Sense the voice...
            bufferReadResult = audio.read(buffer, 0, bufferSize);
            double sumLevel = 0;
            for (int i = 0; i < bufferReadResult; i++) {
                sumLevel += buffer[i];
            }
            currentdata.SOUNDLEVEL = (float)Math.abs((sumLevel / bufferReadResult));
        }

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

@Override
protected void onPause() {
    textView1.append("onPause\n");

    super.onPause();                                            

    thread.interrupt();
    thread = null;
    try {
        if (audio != null) {
            audio.stop();
            audio.release();
            audio = null;
        }
    } catch (Exception e) {e.printStackTrace();}
}

private class computeDrivingParams extends AsyncTask<sensordata, Void, drivingParameters>{

    @Override
    protected drivingParameters doInBackground(sensordata... arg0) {
        // TODO Auto-generated method stub
        return analyser.analyseDrivingParam(arg0);          
    }

}


}

这里是分析器类的代码,它是我进行计算的地方,我没有在这里进行实际计算。

package com.hrmb.accelometer;

public class behaviorAnalyser {

public drivingParameters analyseDrivingParam(sensordata[] arg0){
    drivingParameters result = new drivingParameters();


    int len = arg0.length;
    float sumacc =0;
    for(int i=0; i<len; i++){
        sumacc = arg0[i].ACC_X ; 
    }

    result.numAcceleration = (int) sumacc/len;
    result.numTurnRight = 2;
    result.numTurnLeft = 5;
    result.numBreaks = 10;
    //end of analysing
    return result;
}       
}

2 个答案:

答案 0 :(得分:0)

您的部分问题可能是您没有足够快地读取音频数据。我建议将音频读取到音频紧急优先级的自己的线程中,一旦数据超出AudioRecord,你就可以决定扔掉你在睡眠周期后不想要的东西。

http://developer.android.com/reference/android/media/AudioRecord.html

  

应用程序负责轮询AudioRecord对象   时间使用以下三种方法之一

答案 1 :(得分:0)

我以一种非常简单而奇怪的方式解决了我的问题。

当我调用另一个对象的函数时,在doInBackground中,它不起作用!!!!

我把方法的代码放在doInBackground中,它可以工作....