2012-02-28 9 views
2

現在、加速度計とマイクのデータを2秒ごとに収集するはずのアプリケーションで作業しています。これを行うために、アプリケーションがバックグラウンドで実行されている間にデータを収集するためにサービスを開始しました(内部でタイマーを実行しています)。ここまでは順調ですね。携帯電話がアイドル状態にあるときに加速度計データを収集する方法

タイマーが開始され、データが収集され、そのデータがXMLファイルに書き込まれます。しかし、生成されたXMLファイルを見て、私は、携帯電話がアイドル状態にある間、加速度計の値は常に同じであることに気付きました。私は2秒ごとに電話を「目覚めさせる」ためにウェイクロックを使用しますが、それでも動作しませんでした。

@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:私はSamsungのspika、androidバージョン2.1を使用しています。

答えて

0

AFAIK加速度計は、デバイスがアイドル状態のときはサンプリングできません。 CPUを動作させ続けるPARTIAL_WAKE_LOCKを設定する必要があります。それでも画面は消えてしまいますが、バッテリーは通常より速く動作しなくなります。

http://developer.android.com/reference/android/os/PowerManager.html#PARTIAL_WAKE_LOCK

コード:また、マニフェストにこの権限エントリを含める必要が

PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); 
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag"); 
wl.acquire(); 
// ..screen will stay on during this section.. 
wl.release(); 

<uses-permission android:name="android.permission.WAKE_LOCK" /> 

この点について前の質問があります: How to sample accelerometer data in the background or on the sleep mode

は、
関連する問題