Отображение таймера во время записи видео android

Я делаю видеомагнитофон, и я хочу иметь продолжительность времени, сколько времени пользователь записал видео. Время будет отсчитываться вверх.

чтобы рассчитать время, я использую поток, и расчет начинается, когда пользователь нажимает кнопку «Пуск», и останавливается, когда пользователь нажимает кнопку «Стоп».

для потока таймера я ссылаюсь на учебник из здесь. однако моя проблема в том, что таймер не работает, и я думаю, что поток не выполняет свою работу. ниже мой логарифм.

введите здесь описание изображения

Вот мой код для основного действия

public class Videotest1Activity extends Activity implements 
    SurfaceHolder.Callback, OnInfoListener, OnErrorListener{

    Camera camera;
    VideoView videoView;
    SurfaceHolder holder;
    TextView msg;
    Button initBtn, startBtn, stopBtn, playBtn, stprevBtn;
    MediaRecorder recorder;

    String outputFileName;
    static final String TAG = "RecordVideo";
    int maxDuration = 7000;//7sec
    int frameRate = 1;//15

String serverIP = "172.19.117.12";
int serverPort = 2000;
Socket socket;

int mCount;
TimerThread mTimer;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_videotest1);

    videoView = (VideoView) findViewById(R.id.videoView1);
    initBtn = (Button) findViewById(R.id.initialize);
    startBtn = (Button) findViewById(R.id.button1);
    stopBtn = (Button) findViewById(R.id.button3);
    msg = (TextView) findViewById(R.id.textView1);
    playBtn = (Button) findViewById(R.id.reviewBtn);
    stprevBtn = (Button) findViewById(R.id.stprevBtn);

    mTimer= new TimerThread();
    mTimer.setOnAlarmListener(mSTimer_OnAlarm);
    mTimer.setPeriod(100);
}

public void buttonTapped(View view){
    switch(view.getId()){
    case R.id.initialize:
        initRecorder();
        break;
    case R.id.button1:
        beginRecording();
        break;
    case R.id.button3:
        stopRecording();
        break;
    case R.id.reviewBtn:
        playRecording();
        break;
    case R.id.stprevBtn:
        stopPlayback();
        break;
    }
}

@Override
public void onError(MediaRecorder mr, int what, int extra) {
    Log.e(TAG, "Record error");
    stopRecording();
    Toast.makeText(this, "Recording limit reached", 2500).show();
}

@Override
public void onInfo(MediaRecorder mr, int what, int extra) {
    Log.i(TAG, "recording event");
    if(what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED){
        Log.i(TAG, "...max duration reached");
        stopRecording();
        Toast.makeText(this, "Recording limit info", 2500).show();
    }
}

@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {

}

@Override
public void surfaceCreated(SurfaceHolder arg0) {
    Log.v(TAG, "in surfaceCreated");

    try{
        camera.setPreviewDisplay(holder);
        camera.startPreview();
    }catch(IOException e){
        Log.v(TAG, "Could not start the preview");
        e.printStackTrace();
    }
    initBtn.setEnabled(true);
    startBtn.setEnabled(true);
    stopBtn.setEnabled(true);
}

@Override
public void surfaceDestroyed(SurfaceHolder arg0) {

}

protected void onResume(){
    Log.v(TAG, "in onResume");
    super.onResume();
    initBtn.setEnabled(false);
    startBtn.setEnabled(false);
    stopBtn.setEnabled(false);
    playBtn.setEnabled(false);
    stprevBtn.setEnabled(false);
    if(!initCamera())
        finish();
}

public boolean initCamera(){
    try{
        camera = Camera.open();
        Camera.Parameters camParam = camera.getParameters();
        camera.lock();
        holder = videoView.getHolder();
        holder.addCallback(this);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        //Thread thread = new Thread(new hantarThread());
        //thread.start();
    }catch(RuntimeException re){
        Log.v(TAG, "Could not initialize the camera");
        re.printStackTrace();
        return false;
    }
    return true;
}

public void initRecorder(){
    if(recorder == null){
        Toast.makeText(this, "record null", 2500).show();           
    }
    else{
        Toast.makeText(this, "record have", 2500).show();
    }
    outputFileName = Environment.getExternalStorageDirectory() + "/videooutput.mp4";

    File outputFile = new File(outputFileName);
    if(outputFile.exists())
        outputFile.delete();//knp nk dlt?

    try{
        camera.stopPreview();
        camera.unlock();
        recorder = new MediaRecorder();
        recorder.setCamera(camera);

        recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
        recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        recorder.setVideoSize(176, 144);
        recorder.setVideoFrameRate(frameRate);//15
        recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        recorder.setMaxDuration(maxDuration);
        recorder.setPreviewDisplay(holder.getSurface());
        recorder.setOutputFile(outputFileName);

        recorder.prepare();
        Log.v(TAG, "MediaRecorder initialized");
        initBtn.setEnabled(false);
        startBtn.setEnabled(true);
    }catch(Exception e){
        Log.v(TAG, "MediaRecorder failed");
        e.printStackTrace();
    }
}

public void beginRecording(){
    mCount = 0;
    mTimer.start();

    recorder.setOnInfoListener(this);
    recorder.setOnErrorListener(this);
    recorder.start();               

    msg.setText("Recording");
    startBtn.setEnabled(false);
    stopBtn.setEnabled(true);
}

public void stopRecording(){
    if(recorder != null){
        recorder.setOnErrorListener(null);
        recorder.setOnInfoListener(null);
        try{
            recorder.stop();        
            mTimer.stop();
        }catch(IllegalStateException e){
            Log.e(TAG, "Got Illegal");
        }
        releaseRecorder();
        msg.setText("");
        releaseCamera();
        startBtn.setEnabled(false);
        stopBtn.setEnabled(false);
        playBtn.setEnabled(true);
    }
}

private void releaseCamera(){
    if(camera != null){
        try{
            camera.reconnect();
        }catch(IOException e){
            e.printStackTrace();
        }
        camera.release();
        camera = null;
    }
}

private void releaseRecorder(){
    if(recorder != null){
        recorder.release();
        recorder = null;
    }
}

private void playRecording(){
    MediaController mc = new MediaController(this);
    videoView.setMediaController(mc);
    videoView.setVideoPath(outputFileName);
    videoView.start();
    stprevBtn.setEnabled(true);
}

private void stopPlayback(){
    videoView.stopPlayback();
}


//----time thread---
OnAlarmListener mSTimer_OnAlarm= new OnAlarmListener() {
    @Override 
    public void OnAlarm(TimerThread source) {
        mCount++;
        msg.setText("Count="+mCount);
        if( mCount==100) source.stop();
    }
};
//----end time thread---

вот мой код для TimerThread.java

  package com.example.videotest1;

import android.os.Handler;

/**
 * A class that implements a simple timer.
 * The timer does not create a separate thread, so there are no multi-threading issues in your activity.
 * The timer uses an event listener as callback when it expires ("alarm") .
 * @author Maarten Pennings 2011 September 26
 */
public class TimerThread {

    // The minimal value for the period of a timer (in milliseconds).
    public static final int MinPeriod = 10; 

    //  Interface definition for a callback to be invoked when a timer expires ("alarm").    
    public interface OnAlarmListener {
        /**
         * Callback that timer 'source' has expired ("alarm").
         * @param source  Timer that expired (when multiple timers use same listener)
         */
        void OnAlarm( TimerThread source );
    }

    protected int             mPeriod= 100;              // what is the period of the timer (in milliseconds)
    protected boolean         mEnabled= false;           // is the timer enabled?
    protected OnAlarmListener mOnAlarmListener= null;    // the listener (callback) for the alarm events
    protected Handler         mHandler= new Handler();   // handler to the thread's queue, allows us to send (timed) messages to that queue 
    protected Runnable        mMessage= new Runnable() { // The message being posted on the message queue
        @Override public void run() 
        { 
            // Call the listener (when it is set).
            if( mOnAlarmListener!=null ) mOnAlarmListener.OnAlarm(TimerThread.this);


              // Cascade, i.e. post a new delayed message to ourselves.
                // NOTE: The listener could have called stop(), this removes the mMessage message form the queue.
                // However, there is no such message, it has just

 been taken out of the queue and is currently being executed.
            // So check if the timer is still enabled before cascading (posting a new delayed message).  
            if( mEnabled ) mHandler.postDelayed(mMessage, mPeriod); 
        } 
    }; 

    /**
     * Set the period of the timer. The timer must be separately enabled before its starts generating alarm events.     
     * @param ms    the period of the timer in milliseconds
     */
    public void setPeriod( int ms ) {
        if( ms<MinPeriod ) throw new IllegalArgumentException("STimer.setPeriod called with too small period ("+ms+"<"+MinPeriod+")" );
        mPeriod= ms;
    }

    /**
     * Returns the current period of the timer.     
     * @return the current period of the timer in milliseconds
     */
    public int getPeriod( ) {
        return mPeriod;
    }

    /**
     * Enables or disables the timer for generating an alarm event every getPeriod milliseconds.     
     * @param enabled   the new state of the timer
     */
    public void setEnabled( boolean enabled ) {
        if( enabled!=mEnabled ) {
            // The enabled state really changes
            if( enabled ) {
                // Post the first message (which will post the next message and so on)
                mHandler.postDelayed(mMessage, mPeriod);  


           } else {
                // Remove any message that is in the queue
                mHandler.removeCallbacks(mMessage);
            }
            // Record the new state
            mEnabled= enabled;
        }
    }

    /**
     * Returns the current enabled/disabled state of the timer.     
     * @return the current enabled/disabled state of the timer
     */
    public boolean getEnabled() {
        return mEnabled;
    }

    /**
     * Register a callback to be invoked each time the timer period expires ("alarm").     
     * @param l   the listener object that will be called-back.
     */
    public void setOnAlarmListener( OnAlarmListener l ) {
        mOnAlarmListener= l;
    }

   // Starts the timer, i.e. a shorthand for setEnabled(true).   
    public void start( ) {
      setEnabled(true);
    }

     // Stops the timer, i.e. a shorthand for setEnabled(false).    
    public void stop( ) {
      setEnabled(false);
    }

}

и последний мой OnAlarmListener.java

public class OnAlarmListener implements TimerThread.OnAlarmListener {

public void OnAlarm(TimerThread source) {
    // TODO Auto-generated method stub

}

person sara brown    schedule 22.09.2012    source источник


Ответы (1)


Рассмотрите возможность использования CountDownTimer()...

new CountDownTimer(1000, 1000) {

     public void onTick(long millisUntilFinished) {
         mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
     }

     public void onFinish() {
         mTextField.setText("done!");
     }
  }.start();

http://developer.android.com/reference/android/os/CountDownTimer.html

person Bill Mote    schedule 22.09.2012
comment
Что делать, если я не хочу использовать обратный отсчет? Я хочу использовать подсчет. что я должен делать? есть ли лучшие способы? - person sara brown; 22.09.2012
comment
Пример, который я привел, отсчитывает 1 секунду. Итак, когда 1 секунда завершается, вы увеличиваете свою переменную;) Эффективно подсчет, и он использует встроенные биты ОС, поэтому он должен быть лучше в отношении времени автономной работы, чем все, что вы или я могли бы построить. - person Bill Mote; 22.09.2012