Android Camera Program - android

I am new to Android I have written a small program to take pictures and save them in the internal memory disk. My program is successfully launched but when I take pictures no data is written to the memory disk.
Below is my code. What am I missing?
package com.lab2;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import android.os.Environment;
public class Lab2_cameraActivity extends Activity implements SurfaceHolder.Callback {
/** Called when the activity is first created. */
private Camera mCamera;
private SurfaceHolder mHolder;
private SurfaceView mSurfaceView;
private Button mbutton1;
private ShutterCallback shutter;
private PictureCallback raw;
private PictureCallback postview;
AutoFocusCallback AFCallback = new AutoFocusCallback(){
#Override
public void onAutoFocus(boolean success, Camera camera) {
// TODO Auto-generated method stub
if (success){
mCamera.takePicture(shutter, raw, postview, jpeg);//take photo
}else{
Toast.makeText(Lab2_cameraActivity.this, "in else...",Toast.LENGTH_LONG).show();
}
}
};
/*jpeg callback occurs when the compressed image is available*/
PictureCallback jpeg = new PictureCallback(){
#Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
FileOutputStream outStream = null;
File file = new File("/mnt/sdcard/");
try {
outStream = new FileOutputStream(file.toString()+"photo.jpg");
outStream.write(data);
outStream.close();
Toast.makeText(Lab2_cameraActivity.this, "Photo Saved...",Toast.LENGTH_LONG).show();
mCamera.startPreview();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
/*when surface destroyed, stop preview*/
if(mCamera != null){
mCamera.stopPreview();
mCamera.release();//release camera resources
mCamera = null;
}
}
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
mCamera = Camera.open();//open camera
try {
mCamera.setPreviewDisplay(holder);//set surface to display
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
/*when surface changed, reset camera parameters for preview*/
mCamera.getParameters();//get default parameters
Camera.Parameters parameters= mCamera.getParameters();
/*you can set your own parameters in there*/
mCamera.setParameters(parameters);//set parameters if parameters has been changed
mCamera.startPreview();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mbutton1 = (Button)findViewById(R.id.button1);
mSurfaceView = (SurfaceView)findViewById(R.id.surfaceView);
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mbutton1.setOnClickListener(new Button.OnClickListener()
{
#Override
public void onClick(View v) {
mCamera.autoFocus(AFCallback);
}
});
}
}

you should not specify '/mnt/whatever/' path to your sdcard, use getExternalFilesDir() to get the correct path.
your callback is not called, unless you specify it in mCamera.takePicture(null, null, jpeg);
do you really have
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">
in your AndroidManifest.xml file?

Related

Android camera startPreview failed error

I want to simply take a photo in android (actually with an overlay image....but do it later, I am now failing in the first step...), the log catch an error of 'start preview failed'. The following is my code:
package com.example.camera_test;
import java.io.IOException;
import android.app.Activity;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class CameraFilming extends Activity implements SurfaceHolder.Callback{
private Camera camera = null;
private SurfaceView preview;
private SurfaceHolder holder;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.camera);
((Setting)getApplication()).getDeviceDisplaySize();
preview = (SurfaceView)findViewById(R.id.camera_surface);
holder = preview.getHolder();
holder.addCallback(this);
}
private void startCamera(){
camera = Camera.open();
}
#Override
public void onBackPressed(){
super.onBackPressed();
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
try {
startCamera();
camera.setPreviewDisplay(holder);
camera.startPreview();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera.stopPreview();
camera.release();
camera = null;
}
}
I run it on a real device and then it gets no problem...conclusion: don't do camera simulation on an AVD emulator!!!

Android camera app gives error on back and home button

My Application gives error "Unfortunately PhotoComment has stopped" when I am pressing back or home button. But when I am reopening app from task manager it works.
this is my mainactivity.java
package com.cameratag;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Date;
import java.text.SimpleDateFormat;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Environment;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
public class MainActivity extends Activity{
private CameraSurfaceView cameraView;
private ImageView imageResult;
private ImageView imageResult2;
private FrameLayout framenew;
private TextView snapPhoto;
private boolean takePicture = true;
private Bitmap image = null;
private String lastPreviewImgPath = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupcamera();
}
public void setupcamera(){
cameraView = new CameraSurfaceView(getApplicationContext());
imageResult = new ImageView(getApplicationContext());
imageResult.setBackgroundColor(Color.GRAY);
framenew = (FrameLayout) findViewById(R.id.frame);
snapPhoto = (TextView) findViewById(R.id.textView1);
framenew.addView(imageResult);
framenew.addView(cameraView);
}
public void captureHandler(View view){
if(takePicture){
cameraView.capture(jpegHandler);
}
else{
takePicture = true;
cameraView.preview();
framenew.bringChildToFront(cameraView);
imageResult.setImageBitmap(null);
snapPhoto.setText("Capture");
}
}
public void zoomMinusHandler(View view){
cameraView.zoomMinus();
}
public void zoomPilusHandler(View view){
cameraView.zoomPilus();
}
public Camera.PictureCallback jpegHandler = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
image = BitmapFactory.decodeByteArray(data, 0, data.length);
imageResult.setImageBitmap(image);
imageResult2 = imageResult;
LayoutParams params = imageResult.getLayoutParams();
params.width = framenew.getWidth();
params.height = framenew.getHeight();
imageResult2.setLayoutParams(params);
//framenew.bringChildToFront(imageResult);
//snapPhoto.setText("Take Picture");
//takePicture = false;
File directory = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "NNCam");
if (!directory.exists()) {
if (!directory.mkdirs()) {
//Log.e(TAG, "Failed to create storage directory.");
}
}
String timeStamp = new SimpleDateFormat("yyyMMdd_HHmmss").format(new Date(System.currentTimeMillis()));
String filename = "/IMG_" + timeStamp + ".jpg";
if(image!=null){
saveImage(directory.getPath(),filename,image);
cameraView.preview();
}
}
};
public void saveImage(String path, String imgname, Bitmap image){
try{
FileOutputStream fos = new FileOutputStream(path+imgname);
BufferedOutputStream stream = new BufferedOutputStream(fos);
image.compress(CompressFormat.JPEG, 100, stream);
stream.flush();
stream.close();
}
catch(FileNotFoundException e){
}
catch(IOException e){
}
lastPreviewImgPath = path+imgname;
Bitmap bitmap = BitmapFactory.decodeFile(lastPreviewImgPath);
ImageView myImageView = (ImageView)findViewById(R.id.lastPreview);
myImageView.setImageBitmap(bitmap);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
cameraView.release();
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
cameraView.reconnect();
}
#Override
public void onPause() {
super.onPause();
cameraView.release();
}
}
and this is surfaceview class
package com.cameratag;
import java.io.IOException;
import java.util.List;
import android.content.Context;
import android.content.res.Configuration;
import android.hardware.Camera;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback{
private Context context;
private SurfaceHolder mHolder;
public Camera camera = null;
public int zoomValue = 0;
public CameraSurfaceView(Context context) {
super(context);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// TODO Auto-generated constructor stub
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
Camera.Parameters parameters = camera.getParameters();
List<Camera.Size> sizes = parameters.getSupportedPictureSizes();
Camera.Size cs = sizes.get(0);
List<Camera.Size> sizes2 = parameters.getSupportedPreviewSizes();
Camera.Size cs2 = sizes2.get(0);
parameters.setPreviewSize(cs2.width, cs2.height);
parameters.setPictureSize(cs.width, cs.height);
camera.setParameters(parameters);
camera.startPreview();
}
#Override
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub
camera = Camera.open();
try {
camera.setPreviewDisplay(mHolder);
} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
int rrr = 0;
Display display = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int rotation = display.getRotation();
if(rotation==0)rrr=90;
else if(rotation==1)rrr=0;
else if(rotation==3)rrr=180;
else rrr=270;
camera.setDisplayOrientation(rrr);
}
#Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
camera.stopPreview();
camera = null;
}
public void capture(Camera.PictureCallback jpegHandler){
camera.takePicture(null, null, jpegHandler);
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
int rrr = 0;
Display display = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int rotation = display.getRotation();
if(rotation==0)rrr=90;
else if(rotation==1)rrr=0;
else if(rotation==3)rrr=180;
else rrr=270;
//camera.stopPreview();
camera.setDisplayOrientation(rrr);
//camera.startPreview();
}
public void preview(){
camera.startPreview();
}
public void reconnect(){
try {
camera.reconnect();
} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
}
public void zoomMinus() {
Camera.Parameters parameters = camera.getParameters();
// TODO Auto-generated method stub
if(parameters.isZoomSupported()){
if(zoomValue>0){
zoomValue-=2;
parameters.setZoom(zoomValue);
if(parameters.isSmoothZoomSupported()){
camera.startSmoothZoom(zoomValue);
}
else{
camera.setParameters(parameters);
}
}
}
}
public void zoomPilus() {
Camera.Parameters parameters = camera.getParameters();
// TODO Auto-generated method stub
if(parameters.isZoomSupported()){
if(zoomValue<parameters.getMaxZoom()){
zoomValue+=2;
parameters.setZoom(zoomValue);
if(parameters.isSmoothZoomSupported()){
camera.startSmoothZoom(zoomValue);
}
else{
camera.setParameters(parameters);
}
}
}
}
public void release() {
// TODO Auto-generated method stub
camera.setPreviewCallback(null);
camera.stopPreview();
camera.release();
}
}
Please help.
#Override
protected void onPause() {
super.onPause();
// if (inPreview) {
// mCamera.stopPreview();
// }
// mCamera.release();
// mCamera = null;
// inPreview = false;
mCamera.setPreviewCallback(null);
super.onPause();
// mCamera.stopPreview();
}
I was having a similar issue, the trick is to also setup the camera inside of onResume().
The issue was that the app does not call onCreate() every time you go to an activity with the back button, sometimes it simply pauses the activity. onResume() is called whenever the activity returns to the foreground and is a more reliable place to set up the camera.
#Override
protected void onResume()
{
super.onResume();
if( camera == null )
{
camera = Camera.open();
}
}
try to put your release code in try catch block
try{
if (camera != null){
camera.setPreviewCallback(null);
camera.stopPreview();
camera.release();
}
}
I have found the solution for my own. You only need to change surfaceDestroyed method to this.
#Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
try{
camera.stopPreview();
camera.release();
camera = null;
}
catch(NullPointerException e){
//e.printStackTrace();
}
}
and on onRestoreInstanceState to this.
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
cameraView = null;
setupcamera();
//cameraView.reconnect();
}

Camera code works in android version below API level 14

My sample camera code which works in android API levels below 14
When I tried in API level 14 or above, it throws null pointer exception.
please can you tell me where I am going wrong.
protected void onStart() {
super.onStart();
cam= Camera.open();
Log.e("msg", cam+"");
mp=new MyPreview(getApplicationContext(), cam);
frame1.addView(mp);
Toast.makeText(getApplicationContext(), "Camera open", 5).show();
}
Mypreview is a class which extends SurfaceView and implements SurfaceHolder.CallBack
code is:
import java.io.IOException;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class MyPreview extends SurfaceView implements SurfaceHolder.Callback {
private Camera _cam;
private SurfaceHolder sh;
#SuppressWarnings("deprecation")
public MyPreview(Context context, Camera _cam) {
super(context);
this._cam = _cam;
sh=getHolder();
sh.addCallback(this);
sh.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
Camera.Parameters cp = _cam.getParameters();
cp.setPreviewSize(width, height);
cp.setFlashMode(Parameters.FLASH_MODE_AUTO);
_cam.setParameters(cp);
_cam.setDisplayOrientation(90);
_cam.startPreview();
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
_cam.setPreviewDisplay(holder);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
_cam.stopPreview();
}
}

Unable to set HIGH_QUALITY profile for front camera

There must be something I'm missing witht this CamcorderProfile as I keep getting "11-15 01:00:53.185: E/MediaRecorder(976): setOutputFormat called in an invalid state: 1
" on "recorder.setProfile(profile);"
package com.apress.proandroidmedia.ch1.cameraintent;
import java.io.IOException;
import android.app.Activity;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class JustRecord extends Activity implements SurfaceHolder.Callback{
SurfaceView cameraView;
SurfaceHolder surfaceHolder;
Camera camera;
MediaRecorder recorder;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main1);
cameraView = (SurfaceView) findViewById(R.id.CameraView);
surfaceHolder = cameraView.getHolder();
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
surfaceHolder.addCallback(this);
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
try{
camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
camera.setDisplayOrientation(90);
}
catch (Exception exception){
camera.release();
exception.printStackTrace();
}
recorder = new MediaRecorder();
recorder.setCamera(camera);
CamcorderProfile profile = CamcorderProfile.get(Camera.CameraInfo.CAMERA_FACING_FRONT, CamcorderProfile.QUALITY_HIGH);
if(profile != null) {
recorder.setProfile(profile);
}else {
//default to basic H263 and AMR_NB if profile not found
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
}
recorder.setOutputFile("/sdcard/videocapture_example.mp4");
recorder.setMaxDuration(5000); // 50 seconds
prepareRecorder();
recorder.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
//camera.stopPreview();
recorder.stop();
recorder.release();
camera.release();
}
private void prepareRecorder() {
recorder.setPreviewDisplay(surfaceHolder.getSurface());
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
finish();
} catch (IOException e) {
e.printStackTrace();
finish();
}
}
}
Any ideas?
Thanks!
EDIT: I might as well add that the code works just fine if I type in the codecs and such. It's just that I cant determine the best quality for some reason.
I managed to solve that one by actually starting to think for a change...
When you look at the MediaRecorder flow chart the first thing you see is the AudioSource and VideoSource defined. Moreover, those 2 are obviously NOT defined when using a CamcorderProfile. Yet after defining those 2 lines MediaRecorder still refused to start. What was missing here is "camera.unlock()" as my camera was "taken" sort of speak on previous tests.

Unable start camera Preview on button click

I'm a newbie programmer for Android I was trying to start camera preview in Android on click of button. I'm trying directly to access camera hardware rather than using default camera application. Here is the code I've written
import android.app.Activity;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class CameraHandler extends Activity {
private SurfaceView sv = null;
private SurfaceHolder previewHolder = null;
private Button btnStop;
private Button btnStart;
private Camera camera = null;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cameraview);
// Get the surface view from main layout
sv = (SurfaceView) findViewById(R.id.cameraSurface);
// Get the buttons from XML
btnStart = (Button) findViewById(R.id.startButton);
btnStop = (Button) findViewById(R.id.stopButton);
btnStart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
SurfaceHolder.Callback surfaceCallBack = new SurfaceHolder.Callback() {
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera.release();
camera = null;
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera = Camera.open();
try {
camera.setPreviewDisplay(previewHolder);
} catch (Throwable t) {
// TODO Auto-generated catch block
Log.e("PreviewDemo-surfaceCallback",
"Exception in setPreviewDisplay()", t);
Toast.makeText(CameraHandler.this, t.getMessage(),
Toast.LENGTH_LONG).show();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder,
int format, int width, int height) {
// TODO Auto-generated method stub
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(width, height);
camera.setParameters(parameters);
camera.startPreview();
}
};
// Get the surface holder from the surface view
previewHolder = sv.getHolder();
// Now add these call backs
previewHolder.addCallback(surfaceCallBack);
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
});
btnStop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
camera.stopPreview();
}
});
}
}
As you can see I'm getting surface holder from the SurfaceView in XML adding it a call back when start button is clicked. For some reason SufraceHolder callback is not getting called. But If i place this entire code directly in onCreate function it works fine i.e camera preview starts as activity is launched. Am I missing something here?
Thanks in Advance
The SurfaceView is already created by the time the button is clicked. Hence, surfaceCreated() probably will not be called.

Categories

Resources