-1

Here is my code for camera that takes picture every 1 second, problem is that it is slow and that it takes time to save one image and then start counting 1 second and take another, is there better way of doing that, and should I use AsyncTask or background process and how to do that?

import java.io.IOException;
import java.io.OutputStream;
import android.app.Activity;
import android.content.ContentValues;
import android.content.res.Configuration;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore.Images.Media;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class Test extends Activity implements OnClickListener,
    SurfaceHolder.Callback, Camera.PictureCallback {
  SurfaceView cameraView;
  SurfaceHolder surfaceHolder;
  Camera camera;

  Button startStopButton;
  TextView countdownTextView;
  Handler timerUpdateHandler;
  boolean timelapseRunning = false;
  int currentTime = 0;
  final int SECONDS_BETWEEN_PHOTOS = 1; 
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    cameraView = (SurfaceView) this.findViewById(R.id.CameraView);
    surfaceHolder = cameraView.getHolder();
    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    surfaceHolder.addCallback(this);

    countdownTextView = (TextView) findViewById(R.id.CountDownTextView);
    startStopButton = (Button) findViewById(R.id.CountDownButton);
    startStopButton.setOnClickListener(this);
    timerUpdateHandler = new Handler();
  }

  public void onClick(View v) {
    if (!timelapseRunning) {
      startStopButton.setText("Stop");
      timelapseRunning = true;
      timerUpdateHandler.post(timerUpdateTask);
    } else {
      startStopButton.setText("Start");
      timelapseRunning = false;
      timerUpdateHandler.removeCallbacks(timerUpdateTask);
    }
  }

  private Runnable timerUpdateTask = new Runnable() {
    public void run() {
      if (currentTime < SECONDS_BETWEEN_PHOTOS) {
        currentTime++;
      } else {
        camera.takePicture(null, null, null, Test.this);
        currentTime = 0;
      }

      timerUpdateHandler.postDelayed(timerUpdateTask, 1000);
      countdownTextView.setText("" + currentTime);
    }
  };

  public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    camera.startPreview();
  }

  public void surfaceCreated(SurfaceHolder holder) {
    camera = Camera.open();
    try {
      camera.setPreviewDisplay(holder);
      Camera.Parameters parameters = camera.getParameters();
      if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
        parameters.set("orientation", "portrait");
        camera.setDisplayOrientation(90);
      }
      camera.setParameters(parameters);
    } catch (IOException exception) {
      camera.release();
    }
  }

  public void surfaceDestroyed(SurfaceHolder holder) {
    camera.stopPreview();
    camera.release();
  }

  public void onPictureTaken(byte[] data, Camera camera) {
    Uri imageFileUri = getContentResolver().insert(
        Media.EXTERNAL_CONTENT_URI, new ContentValues());
    try {
      OutputStream imageFileOS = getContentResolver().openOutputStream(
          imageFileUri);
      imageFileOS.write(data);
      imageFileOS.flush();
      imageFileOS.close();

      Toast t = Toast.makeText(this, "Saved JPEG!", Toast.LENGTH_SHORT);
      t.show();
    } catch (Exception e) {
      Toast t = Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT);
      t.show();
    }
    camera.startPreview();
  }
}


//layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >    
    <FrameLayout android:id="@+id/FrameLayout01" 
                 android:layout_width="wrap_content" 
                 android:layout_height="wrap_content">
        <SurfaceView android:id="@+id/CameraView" 
                     android:layout_width="fill_parent" 
                     android:layout_height="fill_parent"></SurfaceView>
        <LinearLayout android:id="@+id/LinearLayout01" 
                      android:layout_width="wrap_content" 
                      android:layout_height="wrap_content">
            <TextView android:id="@+id/CountDownTextView" 
                      android:text="10" 
                      android:textSize="100dip" 
                      android:layout_width="fill_parent" 
                      android:layout_height="wrap_content" 
                      android:layout_gravity="center_vertical|center_horizontal|center"></TextView>
            <Button android:layout_width="wrap_content" 
                    android:layout_height="wrap_content" 
                    android:id="@+id/CountDownButton" 
                    android:text="Start Timer"></Button>
        </LinearLayout>
    </FrameLayout>
</LinearLayout>
Alen
  • 949
  • 3
  • 17
  • 37
  • It is not clear what you complain about. If you need 1 image per second, then there is nothing you can do to make it faster. You can improve the precision of your timer, e.g. by offloading the camera callbacks to a background (handler) thread, and using `sleep()` instead of the non-obliging `postDelayed()`. – Alex Cohn Oct 27 '15 at 14:38

1 Answers1

0

To open a camera app in still image mode, use the INTENT_ACTION_STILL_IMAGE_CAMERA action.

public void capturePhoto() {
    Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent);
    }
}

it won't get exit until the user is finished with the activity:

Example intent filter:

<activity ...>
    <intent-filter>
        <action android:name="android.media.action.STILL_IMAGE_CAMERA" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

For getting camera image you should take a look in below link :

Android Camera Intent: how to get full sized photo?

OR

If you want to use your own code then you should use **

Thread

** and make it sleep for 3 to 4 second for saving file and again ready to take picture.

Community
  • 1
  • 1
KishuDroid
  • 5,411
  • 4
  • 30
  • 47