Reputation: 301
Using the camera API, i am able to successfully take a picture and save it to a folder. Here is the code that i am using:
Main.xml:
<FrameLayout
android:id="@+id/camera_preview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1" />
<Button
android:id="@+id/button_capture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Capture" />
A helper class:
import java.io.IOException;
import android.content.Context;
import android.hardware.Camera;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class CameraPreview extends SurfaceView implements
SurfaceHolder.Callback {
private SurfaceHolder mSurfaceHolder;
private Camera mCamera;
// Constructor that obtains context and camera
@SuppressWarnings("deprecation")
public CameraPreview(Context context, Camera camera) {
super(context);
this.mCamera = camera;
this.mSurfaceHolder = this.getHolder();
this.mSurfaceHolder.addCallback(this);
this.mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.setDisplayOrientation(90);
mCamera.startPreview();
} catch (IOException e) {
// left blank for now
}
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
mCamera.stopPreview();
mCamera.release();
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int format,
int width, int height) {
// start preview with new settings
try {
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
} catch (Exception e) {
// intentionally left blank for a test
}
}
}
Activity Class:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
public class MyCamera extends Activity {
private Camera mCamera;
private CameraPreview mCameraPreview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mCamera = getCameraInstance();
mCameraPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mCameraPreview);
Button captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCamera.takePicture(null, null, mPicture);
}
});
}
/**
* Helper method to access the camera returns null if it cannot get the
* camera or does not exist
*
* @return
*/
private Camera getCameraInstance() {
Camera camera = null;
try {
camera = Camera.open();
} catch (Exception e) {
// cannot get camera or does not exist
}
return camera;
}
PictureCallback mPicture = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
}
};
private static File getOutputMediaFile() {
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"MyCameraApp");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + timeStamp + ".jpg");
return mediaFile;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.my_camera, menu);
return true;
}
}
I have also added to the manifest file the following:
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I have the following problems:
I want to do the following:
After pressing the capture button, i want the camera to automatically continue capturing pictures every 5 sec, by using a count down timer. So i have added the following :
while(true){
new CountDownTimer(5000,1000){
@Override
public void onFinish() {
mCamera.takePicture(null, null, mPicture);
}
@Override
public void onTick(long millisUntilFinished) {
}
}.start();
}
However, I am no longer getting a picture. I added the while(true) to make the code repeat by its not. I have tried it without the while(true) and as expected the image capturing is delayed for 5 second
Second thing is: How can I change the quality of the captured pictures?
Any help will be greatly appreciated.
Upvotes: 8
Views: 16323
Reputation: 11
while (true) {
new CountDownTimer(5000, 1000) {
@Override
public void onFinish() {
releaseCamera();
}
@Override
public void onTick(long millisUntilFinished) {
mCamera.takePicture(null, null, mPicture);
}
}.start();
}
You need to capture image when onTick
is called, not when onFinish
is called. onTick
will be called every time after 10 seconds (i.e. the interval specified), whereas onFinish
will be called once countDownTimer
finishes. This is the reason you are getting only one image.
Upvotes: 0
Reputation: 14847
Remove the while(true)
, you don't need it and will create unlimited countdown timers.
Change your Countdown start to this
new CountDownTimer(5000,1000){
@Override
public void onFinish() {
}
@Override
public void onTick(long millisUntilFinished) {
mCamera.startPreview();
mCamera.takePicture(null, null, mPicture);
}
}.start();
onTick
is called every 1000 ms in this case, and onFinish
is called when the Timer countdown is finished.
If you want to repeat something every 5 seconds i don't think a CountDownTimer
fits your needs... a Timer
would be better.
Timer timer = new Timer();
timer.schedule(new TimerTask()
{
@Override
public void run()
{
mCamera.startPreview();
mCamera.takePicture(null, null, mPicture);
}
}, 0, 1000);
Remeber to save Timer
instace to stop it!
Upvotes: 4