我目前正在開發一款應用程序,該應用程序應該每兩秒收集一次加速度計和麥克風數據。爲此,我啓動了一個服務(在內部運行一個計時器),以便在應用程序在後臺運行時收集數據。到現在爲止還挺好。如何在手機處於空閒狀態時收集加速度計數據
定時器啓動,收集數據並將該數據寫入XML文件。但是在看過生成的XML文件後,我意識到,當手機處於空閒狀態時,加速度計的值始終是相同的。我甚至使用喚醒鎖來每兩秒「喚醒」手機,但即使這樣也行不通。
下面是相關代碼:
@Override
public void onCreate() {
super.onCreate();
Toast.makeText(this, "Background Service Created", Toast.LENGTH_SHORT)
.show();
Log.d(TAG, "onCreate Service");
this.startActivities();
}
@Override
public void onDestroy() {
super.onDestroy();
// Kill timer, sensors and XML file
this.stopActivities();
Toast.makeText(this, "Background Service Stopped", Toast.LENGTH_SHORT)
.show();
Log.d(TAG, "onDestroy");
}
@Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "Background Service Started", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onStart");
}
/**
* Expanded modification function.
*/
private void startExpandedNotification(){
//Id for the intent of the expanded notification
final int myID = 1234;
//The intent to launch when the user clicks the expanded notification
Intent i = new Intent(this, MainMovement.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendIntent = PendingIntent.getActivity(this, 0, i, 0);
//This constructor is deprecated. Use Notification.Builder instead if programming for 3.0+
Notification notice = new Notification(R.drawable.ic_launcher, "Movement Sampling Activated", System.currentTimeMillis());
//This method is deprecated. Use Notification.Builder instead if programming for 3.0+
notice.setLatestEventInfo(this, "Movement Sampling", "Sensors activated", pendIntent);
notice.flags |= Notification.FLAG_NO_CLEAR;
startForeground(myID, notice);
}
/**
* Stop Expanded Notification
*/
private void stopExpandedNotification(){
stopForeground(true);
}
/**
* Starts everything that the service needs to collect the sensors data
* (timer, xml file, sensors, expanded notification)
*/
private void startActivities() {
// Define output file path
OUTPUT_FILE = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/Ze";// also added ""/Ze here
OUTPUT_FILE += "/audiorecordtest.3gp";
timer = new Timer(); // If I take this line out, it will lead to an
// exception. But if I do so, the acc values are
// measured while the phone is in the idle state (works only on samsung spika)
timer.scheduleAtFixedRate(new mainTask(), 0, _refreshRate);
xml = new DataStore();
this.startRecordingMic();
this.startRecordingAcc();
startExpandedNotification();
_sampling = true;
}
/**
* Stops everything that the service needs to collect the sensors data
* (timer, xml file, sensors, expanded notification)
*/
private void stopActivities() {
timer.cancel();
//Log.e(TAG, "timer: CANCELLED");
// close xml file
xml.closeFile();
//Log.e(TAG, "XML: CLOSED");
// unregister sensor
_sensorManager.unregisterListener(accelerationListener);
//Log.e(TAG, "Sensors: UNREGISTERED");
// stop recording
if (_recorder != null) {
_recorder.stop();
_recorder.release();
_recorder = null;
}
stopExpandedNotification();
_sampling = false;
}
/**
* Responsible for collecting the sensors data every two seconds
*/
private class mainTask extends TimerTask {
/**
* Collects the sensor data every 2 seconds
*/
@Override
public void run() {
MovementService.this.collectData();
}
}
/**
* Initiates the microphone in order to collect the amplitude value
*/
private void startRecordingMic() {
_recorder = new MediaRecorder();
_recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
_recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
_recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
_recorder.setOutputFile(OUTPUT_FILE);
try {
_recorder.prepare();
} catch (final IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (final IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
_recorder.start();
}
/**
* Initiates the acceleromenter sensor in order to collect movement data
*/
private void startRecordingAcc() {
// ACCELEROMETER
_sensorManager = (SensorManager) this
.getSystemService(Context.SENSOR_SERVICE);
_accelerometer = _sensorManager
.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
_sensorManager.registerListener(accelerationListener, _accelerometer,
SensorManager.SENSOR_DELAY_FASTEST);
}
private final SensorEventListener accelerationListener = new SensorEventListener() {
public void onAccuracyChanged(Sensor sensor, int acc) {
}
public void onSensorChanged(SensorEvent event) {
// sampling values per axis
_x = event.values[0];
_y = event.values[1];
_z = event.values[2];
//Log.e(TAG , "x: " + _x + " y: " + _y + " z:" + _z);
}
};
/**
* Send data (amplitude and decibel) to the xml file
*/
public void collectData() {
//The power lock ensures that the service will indeed collect the accelerometer data
PowerManager pm = (PowerManager) MovementService.this.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "YOUR TAG");
wl.acquire();
Log.v(TAG, "lock aquired");
if (xml != null) xml.writeOnFile(this.getAmplitude(), this.getAccelaration(), this.getTotalAccelaration());
wl.release();
Log.v(TAG, "lock released");
}
有你們任何建議,爲了解決這個問題呢?這真讓我抓狂。
Ps:我使用的是三星spika,android版本2.1。