我正在尝试编写一个收集不同传感器数据的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;
}
}
答案 0 :(得分:0)
您的部分问题可能是您没有足够快地读取音频数据。我建议将音频读取到音频紧急优先级的自己的线程中,一旦数据超出AudioRecord,你就可以决定扔掉你在睡眠周期后不想要的东西。
http://developer.android.com/reference/android/media/AudioRecord.html:
应用程序负责轮询AudioRecord对象 时间使用以下三种方法之一
答案 1 :(得分:0)
我以一种非常简单而奇怪的方式解决了我的问题。
当我调用另一个对象的函数时,在doInBackground中,它不起作用!!!!
我把方法的代码放在doInBackground中,它可以工作....