Android 不幸的是,加速度计停止了
我正在尝试编写一个android应用程序,收集不同的传感器数据,并用它进行一些计算。我希望每50毫秒持续收集一次数据,并将其存储在一个数组中,当我们收集到足够的数据windowsize=100时,我们会使用该数据进行一些计算 我使用AsyncTask作为计算部分。但我的问题是,每当我开始计算时,应用程序hanks和我都会得到这样的信息:不幸的是,加速度计已经停止 这是主活动代码:Android 不幸的是,加速度计停止了,android,android-asynctask,accelerometer,Android,Android Asynctask,Accelerometer,我正在尝试编写一个android应用程序,收集不同的传感器数据,并用它进行一些计算。我希望每50毫秒持续收集一次数据,并将其存储在一个数组中,当我们收集到足够的数据windowsize=100时,我们会使用该数据进行一些计算 我使用AsyncTask作为计算部分。但我的问题是,每当我开始计算时,应用程序hanks和我都会得到这样的信息:不幸的是,加速度计已经停止 这是主活动代码: package com.hrmb.accelometer; import java.text.SimpleDate
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);
}
}
}
这是Analyzer类的代码,这是我进行计算的地方,我没有把真正的计算放在这里
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;
}
}
部分问题可能是您读取音频数据的速度不够快。我建议将音频读入自己的线程,并具有音频紧急优先级,一旦数据从音频记录中取出,您可以决定在睡眠周期结束后丢弃您不想要的内容 : 应用程序负责轮询中的AudioRecord对象 使用以下三种方法之一计算时间
我用一种非常简单和奇怪的方式解决了我的问题 事实证明,在doInBackground中,当我调用另一个对象的函数时,它不起作用
我将方法代码放在doInBackground中,它可以工作。…我的问题可能与使用AsyncTask运行任务有关。当我删除此部分时,程序工作正常。谢谢您的回复。问题是,当我删除与创建AsyncTask ComputedDrivingParams bt=new ComputedDrivingParams;,相关的部分代码时;,这个程序运行得很好。因此,我的结论是,问题与创建一个异步任务有关。如果您的异步任务似乎挂起,可能会有另一个运行。异步任务在单个后台线程上串行运行。要解决这个问题,可以调用bt.executeOnExecutorAsyncTask.THREAD\u POOL\u EXECUTOR;看看这是否有帮助。