Android Camera Take Picture and SAVE or send to next activity - android

I’m a beginner and I need help. How do I take photos with camera and save or send to next activity?
I've tried a couple of options, i.e. takepicture with picture callback and surfaceview/take with intent. However, neither works properly on Android 2.3.3. Could someone figure out the issues with my code below?
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sf_foto);
mCamera = getCameraInstance();
mCameraPreview = new SF_CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mCameraPreview);
ImageButton captureButton = (ImageButton) findViewById(R.id.button_capture);
captureButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCamera.takePicture(myShutterCallback, mPicture_RAW, mPicture);
}
});
}
private Camera getCameraInstance() {
Camera camera = null;
try {
camera = Camera.open(0);
camera.setDisplayOrientation(90);
} catch (Exception e) {
// cannot get camera or does not exist
}
return camera;
}
ShutterCallback myShutterCallback = new ShutterCallback(){
#Override
public void onShutter() {}
};
PictureCallback mPicture_RAW = new PictureCallback(){
#Override
public void onPictureTaken(byte[] arg0, Camera arg1) {}
};
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.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Intent i = new Intent(StyloveFoto.this, Filter.class);
startActivity(i);
}
};
protected File getOutputMediaFile() {
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),"KWAlbum");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("KWAlbum", "failed to create directory");
return null;
}
}
// Create a media file name
File mediaFile = new File(mediaStorageDir.getPath() + File.separator + "KW" + ".jpg");
return mediaFile;
}
my surface view:
public class SF_CameraPreview extends SurfaceView implements SurfaceHolder.Callback{
private SurfaceHolder mSurfaceHolder;
private Camera mCamera;
public SF_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.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);
Camera.Parameters parameters = mCamera.getParameters();
parameters.set("orientation", "portrait");
mCamera.setParameters(parameters);
mCamera.startPreview();
} catch (Exception e) {
// intentionally left blank for a test
}
}
}

instead of this line : fos.write(data);
write : fos.write(data,0,data.length);
if you want to pass it to the next activity:
Intent i = new Intent(StyloveFoto.this, Filter.class);
i.putExtra("myImage",data);
startActivity(i);
and then in class filter in the oncreate method
byte[] myImage = getIntent()getIntent().getByteArrayExtra("myImage");

I got the same problem and i just solve it before.
The problem is that mPicture is an object of PictureCallback. You can't set intent directing to Filter.class from StyloveFoto.this, because it is in PictureCallback interface. Try this one:
Intent i = new Intent(getBaseContext() , Filter.class);
startActivity(i);
Such a big trap in java....hope it helps :)

Either you save the picture like this and pass the path to another activity
final File file = new File(Environment.getExternalStorageDirectory() + "/" + System.currentTimeMillis() + "_pic.jpg");
OutputStream output = null;
try {
output = new FileOutputStream(file);
output.write(data);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != output) {
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
OR
Pass data from camera activity :
Intent intent = new Intent(getApplicationContext(), your_class.class);
intent.putExtra("path", path);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Receiving Activity
byte[] data = getIntent().getByteArrayExtra("path");
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
image.setImageBitmap(scaleDownBitmapImage(bitmap, 300, 200));

Related

startActivityForResult for taking photo android

I've implemented 2 methods in my application. The first, dispatchTakePictureIntent calls startActivityForResult. So when my activity it's done i get back in onActivityResult.
My applications uses events, so when i receive a particular event, i start the camera, so i can take a photo. The problem is: how can i take the photo, after i started the activity, without touching the display, and just by receiveing another event from a remote device? It's there any method i can call that take the photo instead of using fingers?
thanks
private void dispatchTakePictureIntent(int actionCode) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
switch(actionCode) {
case ACTION_TAKE_PHOTO_B:
File f = null;
try {
f = setUpPhotoFile();
mCurrentPhotoPath = f.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
} catch (IOException e) {
e.printStackTrace();
f = null;
mCurrentPhotoPath = null;
}
break;
default:
break;
}
startActivityForResult(takePictureIntent, actionCode);
}
So i suppose i have to make the system call onActivityResult ..
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case ACTION_TAKE_PHOTO_B: {
if (resultCode == RESULT_OK) {
handleBigCameraPhoto();
}
break;
}
default:
break;
}
}
did It in my app, used this code:
public void takePictureNoPreview(Context context){
// open back facing camera by default
Camera myCamera=Camera.open();
if(myCamera!=null){
try{
//set camera parameters if you want to
//...
// here, the unused surface view and holder
SurfaceView dummy=new SurfaceView(context)
myCamera.setPreviewDisplay(dummy.getHolder());
myCamera.startPreview();
myCamera.takePicture(null, null, getJpegCallback()):
}finally{
myCamera.close();
}
}else{
//booo, failed!
}
private PictureCallback getJpegCallback(){
PictureCallback jpeg=new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream fos;
try {
fos = new FileOutputStream("test.jpeg");
fos.write(data);
fos.close();
} catch (IOException e) {
//do something about it
}
}
};
}
}
the code is from here I didnt modified it in my app a lot..
I implemented a custom Camera, that receives Intents through BroadcastReceiver.
The class below can be started with an intent and allows to take a photo, save it, switch cameras (Back/Front) or get back to the mainActivity by getting intents.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_preview);
View myView= (View) findViewById(R.id.camera_previeww);
myView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
cameraID= Camera.CameraInfo.CAMERA_FACING_FRONT;
mCamera=openCamera(cameraID);
mCamera.startPreview();
IntentFilter filter = new IntentFilter();
filter.addAction(Tabbed.BROADCAST_ACTION_TABBED);
LocalBroadcastManager bm = LocalBroadcastManager.getInstance(this);
bm.registerReceiver(mBroadcastReceiver, filter);
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) this.findViewById(R.id.camera_previeww);
preview.addView(mPreview);
}
private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d(TAG, "Error creating media file, check storage permissions: ");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
sleep(5000);
camera.startPreview();
}
};
private static File getOutputMediaFile(int type){
File mediaStorageDir = new File(Environment.getExternalStorageDirectory(), "MyCameraApp");
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
}else {
Log.d("MyCameraApp", "mediafile=null");
System.out.println("mediafile=null");
return null;
}
return mediaFile;
}
private static Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
public static final int MEDIA_TYPE_IMAGE = 1;
#Override
protected void onPause() {
super.onPause();
releaseCamera(); // release the camera immediately on pause event
}
private void releaseCamera(){
if (mCamera != null){
mCamera.stopPreview();
mCamera.release(); // release the camera for other applications
mCamera = null;
}
}
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
byte[] data = new byte[3];
if (intent !=null && intent.getAction().equals(Tabbed.BROADCAST_ACTION_TABBED)) {
data = intent.getByteArrayExtra(Tabbed.EXTRA_PARAM_BYTE);
}
if (data[FINGER] == MIDDLE_FINGER && data[TYPE] == SINGLE_TAP) {
switchCamera();
//releaseCamera();
//mCamera=Camera.open();
} else if (data[FINGER] == MIDDLE_FINGER && data[TYPE] == DOUBLE_TAP) {
// HAVE TO GO BACK
onBackPressed();
//onPause();
//finish();
} else if (data[FINGER] == INDEX_FINGER && data[TYPE] == SINGLE_TAP) {
mCamera.takePicture(null, null, mPicture);
}
// kill activity
}
};
/*
#Override
public void onResume(){
super.onResume();
mCamera=openCamera(Camera.CameraInfo.CAMERA_FACING_FRONT);
}
*/
void kill_activity()
{
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
releaseCamera();
finish();
}
public void switchCamera(){
mCamera.stopPreview();
releaseCamera();
if (cameraID==Camera.CameraInfo.CAMERA_FACING_BACK){
cameraID=Camera.CameraInfo.CAMERA_FACING_FRONT;
}else{
cameraID=Camera.CameraInfo.CAMERA_FACING_BACK;
}
mCamera=openCamera(cameraID);
mCamera.startPreview();
CameraPreview mPreview = new CameraPreview(this, mCamera);
preview = (FrameLayout) this.findViewById(R.id.camera_previeww);
preview.removeAllViews();
preview.addView(mPreview);
}
public Camera openCamera(int cameraIDD){
Camera c=null;
try{
c=Camera.open(cameraIDD);
}catch (Exception e){
Log.d("Camera Activity", e.getMessage());
}
return c;
}
}

Tried capturing multiple photos in Android but didn't work

I'm a newbie in Android and I've been trying to make an Android camera application that is supposed to be able to capture 5 images when we click the camera button. But the code I'm working on doesn't seem to work. Is there anyone that can help please? So far, this is the code:
public class CameraDemo extends Activity {
private static final String TAG = "CameraDemo";
Camera camera;
Preview preview;
Button buttonClick;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
preview = new Preview(this);
((FrameLayout) findViewById(R.id.preview)).addView(preview);
buttonClick = (Button) findViewById(R.id.buttonClick);
buttonClick.setOnClickListener( new OnClickListener() {
public void onClick(View v) {
int count = 0;
while(count < 5){
preview.camera.takePicture(shutterCallback, rawCallback, jpegCallback);
count++;
try {
wait(1000);
} catch (InterruptedException exception) {
exception.printStackTrace();
}
}
}
});
Log.d(TAG, "onCreate'd");
}
ShutterCallback shutterCallback = new ShutterCallback() {
public void onShutter() {
Log.d(TAG, "onShutter'd");
}
};
/** Handles data for raw picture */
PictureCallback rawCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
Log.d(TAG, "onPictureTaken - raw");
}
};
/** Handles data for jpeg picture */
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream outStream = null;
try {
// write to local sandbox file system
// outStream = CameraDemo.this.openFileOutput(String.format("%d.jpg", System.currentTimeMillis()), 0);
// Or write to sdcard
outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis()));
outStream.write(data);
outStream.close();
Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
Log.d(TAG, "onPictureTaken - jpeg");
}
};
}
And this is the other class named Preview:
class Preview extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = "Preview";
SurfaceHolder mHolder;
public Camera camera;
Preview(Context context) {
super(context);
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, acquire the camera and tell it where
// to draw.
camera = Camera.open();
try {
camera.setPreviewDisplay(holder);
camera.setPreviewCallback(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera arg1) {
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis()));
outStream.write(data);
outStream.close();
Log.d(TAG, "onPreviewFrame - wrote bytes: " + data.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
Preview.this.invalidate();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
// Because the CameraDevice object is not a shared resource, it's very
// important to release it when the activity is paused.
camera.stopPreview();
camera = null;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(w, h);
camera.setParameters(parameters);
camera.startPreview();
}
#Override
public void draw(Canvas canvas) {
super.draw(canvas);
Paint p= new Paint(Color.RED);
Log.d(TAG,"draw");
canvas.drawText("PREVIEW", canvas.getWidth()/2, canvas.getHeight()/2, p );
}
}

Android Camera takePicture function does not call Callback function

I am working on a custom Camera activity for my application.
I was following the instruction from the Android Developers site here:
http://developer.android.com/guide/topics/media/camera.html
Everything seems to works fine, except the Callback function is not called and the picture is not saved. Here is my code:
public class CameraActivity extends Activity {
private Camera mCamera;
private CameraPreview mPreview;
private static final String TAG = "CameraActivity";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera);
// Create an instance of Camera
mCamera = getCameraInstance();
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
Button captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.v(TAG, "will now take picture");
mCamera.takePicture(null, null, mPicture);
Log.v(TAG, "will now release camera");
mCamera.release();
Log.v(TAG, "will now call finish()");
finish();
}
});
}
private PictureCallback mPicture = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.v(TAG, "Getting output media file");
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
Log.v(TAG, "Error creating output file");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.v(TAG, e.getMessage());
} catch (IOException e) {
Log.v(TAG, e.getMessage());
}
}
};
private static File getOutputMediaFile() {
String state = Environment.getExternalStorageState();
if (!state.equals(Environment.MEDIA_MOUNTED)) {
return null;
}
else {
File folder_gui = new File(Environment.getExternalStorageDirectory() + File.separator + "GUI");
if (!folder_gui.exists()) {
Log.v(TAG, "Creating folder: " + folder_gui.getAbsolutePath());
folder_gui.mkdirs();
}
File outFile = new File(folder_gui, "temp.jpg");
Log.v(TAG, "Returnng file: " + outFile.getAbsolutePath());
return outFile;
}
}
After clicking the Button, I get logs: "will now take picture", "will now release camera" and "will now call finish". The activity finishes succesfully, but the Callback function was not called during the
mCamera.takePicture(null, null, mPicture);
function (There were no logs from the mPicture callback or getMediaOutputFile functions) and there is no file in the location that was specified.
Any ideas? :)
Much thanks!
The call to mCamera.takePicture() is asynchronous. That means that the call completes immediately, but the actual picture taking and processing happens sometime later. However, you do this immediately upon return from the call to mCamera.takePicture():
Log.v(TAG, "will now release camera");
mCamera.release();
Log.v(TAG, "will now call finish()");
finish();
That means that you have released the camera resources and finished the Activity before the camera gets a chance to actually take the picture and call you back.
You need to move that code into the callback method onPictureTaken() so that you release the resources and finish the Activity after the callback occurs.
Do it like this for taking multiple images on single Click Using SurfaceView Custom Camera
clickbtn.setOnClickListener(new OnClickListener() {
#SuppressWarnings("deprecation")
#Override
public void onClick(View v) {
for (int i = 0; i < 5; i++) {
mcamera = mPreview.getCamera();
getimage(mcamera);
Toast.makeText(getApplicationContext(),
"multiple image count=" + i, 1000).show();
}
if (mPreview == null) {
mPreview = new CamLayer(MainActivity.this);
}
}
});
and
public static void getimage(Camera mcamera) {
PictureCallback mPicture = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
pictureFile = getOutputMediaFile();
Log.e("path file 11111111", ""+pictureFile);
if (pictureFile == null) {
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
} catch (Exception e) {
}
}
};
try {
mcamera.startPreview();
mcamera.takePicture(null, null, mPicture);
Thread.sleep(2000);
} catch (Exception exception) {
exception.printStackTrace();
}
}
private static File getOutputMediaFile() {
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"Sunil3");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
return null;
}
}
File mediaFile = new File(String.format(mediaStorageDir+File.separator+"%d.jpg", System.currentTimeMillis()));
return mediaFile;
}

Rotating picture taken by Camera in Android

I am trying to do an application that takes a picture with the front facing camera without a UI and i have been successful doing that but the only problem is the picture is always taken in landscape mode, is there any ways to force it to portrait mode?
public class TakePicture extends Activity implements SurfaceHolder.Callback
{
private ImageView iv_image;
private SurfaceView sv;
private Bitmap bmp;
private SurfaceHolder sHolder;
private Camera mCamera;
private int cameraId = 1;
private Parameters parameters;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
iv_image = (ImageView) findViewById(R.id.imageView);
sv = (SurfaceView) findViewById(R.id.surfaceView);
sHolder = sv.getHolder();
sHolder.addCallback(this);
sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3)
{
parameters = mCamera.getParameters();
mCamera.setParameters(parameters);
mCamera.startPreview();
//mCamera.setDisplayOrientation(90);
//sets what code should be executed after the picture is taken
Camera.PictureCallback mCall = new Camera.PictureCallback()
{
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFileDir = getDir();
if (!pictureFileDir.exists() && !pictureFileDir.mkdirs()) {
Log.d("DEBUG", "Can't create directory to save image.");
Toast.makeText(TakePicture.this, "Can't create directory to save image.",
Toast.LENGTH_LONG).show();
return;
}
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyymmddhhmmss");
String date = dateFormat.format(new Date());
String photoFile = "Picture_" + date + ".jpg";
String filename = pictureFileDir.getPath() + File.separator + photoFile;
File pictureFile = new File(filename);
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
Toast.makeText(TakePicture.this, "New Image saved:" + photoFile,
Toast.LENGTH_LONG).show();
finish();
} catch (Exception error) {
Log.d("DEBUG", "File" + filename + "not saved: "
+ error.getMessage());
Toast.makeText(TakePicture.this, "Image could not be saved.",
Toast.LENGTH_LONG).show();
}
}
};
mCamera.takePicture(null, null, mCall);
}
public void surfaceCreated(SurfaceHolder holder)
{
// The Surface has been created, acquire the camera and tell it where
// to draw the preview.
//mCamera = Camera.open();
mCamera = Camera.open(cameraId);
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException exception) {
mCamera.release();
mCamera = null;
}
}
public void surfaceDestroyed(SurfaceHolder holder)
{
//stop the preview
mCamera.stopPreview();
//release the camera
mCamera.release();
//unbind the camera from this object
mCamera = null;
}
private File getDir() {
File sdDir = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
return new File(sdDir, "Camera!");
}
}
As far as I remember when trying to do this, it was a bit tricky.
One approach I found was:
public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera.open();
Parameters params = mCamera.getParameters();
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
params.set("orientation", "portrait");
try {
//not sure if this block of code had an OR relationship with the previous line params.set("orientation", "portrait");
Method rotateSet = Camera.Parameters.class.getMethod("setRotation", new Class[] { Integer.TYPE });
Object arguments[] = new Object[] { new Integer(90) };
rotateSet.invoke(params, arguments);
} catch (Exception e) {
e.printStackTrace();
}
}
mCamera.setParameters(params);
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException exception) {
mCamera.release();
mCamera = null;
}
}
But it didn't work for me (althought I was using Android version higher than 2.0, where this was supposed to work).
I also found a hack using reflection, and that worked:
public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera.open();
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {}
setDisplayOrientation(mCamera, 90);
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException exception) {
mCamera.release();
mCamera = null;
}
}
Where setDisplayOrientation is:
protected void setDisplayOrientation(Camera camera, int angle){
Method setDisplayOrientationMethod;
try {
setDisplayOrientationMethod = camera.getClass().getMethod("setDisplayOrientation", new Class[] { int.class });
if (setDisplayOrientationMethod != null) {
setDisplayOrientationMethod.invoke(camera, new Object[] {angle});
}
} catch (Exception e1) {}
}

camera freezes after picture taken on galaxy 7inch tab but not 10inch

I am developing a custom camera application and testing on two galaxy tablets.. one 7inch and one 10inch.. the 10 inch works great but on the 7inch, when i take a picture, it freezes the camera preview and the logCat stops at CAMERA SNAP, CLICKED log in my btn_snap_pic on click in my customcamera class with no error. the app doesn't crash just hangs.. and if i back out of it and open the app again i get a "fail to connect to camera" i assume that this error is because when my app froze and i backed out, the camera never got released.. anyway, below is my both my CustomCamera class and my CamLayer which is my preview..
public class CustomCamera extends Activity{
String camFace ="back";
FrameLayout frame;
RelativeLayout rel;
CamLayer camPreview;
ImageView btn_snap_pic;
ImageView btn_switch_cam;
String TAG = "custom cam";
public void onCreate(Bundle savedInstanceState)
{
Bitmap btnSwitch = BitmapFactory.decodeResource(this.getResources(),
R.drawable.btn_switch_camera);
Bitmap btnSnap = BitmapFactory.decodeResource(this.getResources(),
R.drawable.btn_take_picture);
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
//Set Screen Orientation
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
RelativeLayout.LayoutParams buttonS = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
RelativeLayout.LayoutParams buttonT = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
RelativeLayout.LayoutParams cam = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
cam.addRule(RelativeLayout.BELOW);
buttonS.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
buttonT.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
buttonT.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
try{
//Create Intance of Camera
camPreview = new CamLayer(this.getApplicationContext(),camFace);
//Relative view for everything
rel = new RelativeLayout(this);
// set as main view
setContentView(rel);
//FrameLayOut for camera
frame = new FrameLayout(this);
// add Camera to view
frame.setLayoutParams(cam);
frame.addView(camPreview);
rel.addView(frame);
btn_switch_cam = new ImageView (this);
btn_switch_cam.setImageBitmap(btnSwitch);
btn_switch_cam.setLayoutParams(buttonS);
buttonS.rightMargin = 25;
buttonS.topMargin = 25;
rel.addView(btn_switch_cam);
btn_switch_cam.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Log.v("CAMERA Switch", "CLICKED");
//frame.removeView(camPreview);
if(camFace.equals("front")){
camFace = "back";
}else{
camFace = "front";
}
//camPreview.stopCamera();
frame.removeView(camPreview);
restartCam();
//camPreview.switchCam(camFace);
}
});
btn_snap_pic = new ImageView(this);
btn_snap_pic.setImageBitmap(btnSnap);
btn_snap_pic.setLayoutParams(buttonT);
buttonT.rightMargin = 25;
buttonT.bottomMargin = 25;
rel.addView(btn_snap_pic);
btn_snap_pic.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Log.v("CAMERA Snap", "CLICKED");
camPreview.camera.takePicture(shutterCallback, rawCallback,
jpegCallback);
}
});
} catch(Exception e){}
}
public void restartCam(){
camPreview = new CamLayer(this.getApplicationContext(),camFace);
frame.addView(camPreview);
}
ShutterCallback shutterCallback = new ShutterCallback() {
public void onShutter() {
Log.d(TAG, "onShutter'd");
}
};
/** Handles data for raw picture */
PictureCallback rawCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, android.hardware.Camera camera) {
Log.d(TAG, "onPictureTaken - raw");
}
};
/** Handles data for jpeg picture */
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, android.hardware.Camera camera) {
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream(String.format(
"/sdcard/LC/images/%d.jpg", System.currentTimeMillis()));
outStream.write(data);
outStream.close();
Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
Log.d(TAG, "onPictureTaken - jpeg");
}
};
}
AND THE CAMLAYER:
public class CamLayer extends SurfaceView implements SurfaceHolder.Callback {
Camera camera;
SurfaceHolder previewHolder;
String camID;
private static final String TAG = "Cam Preview";
public CamLayer(Context context, String facing)
{
super(context);
camID = facing;
previewHolder = this.getHolder();
previewHolder.addCallback(this);
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
startCamera();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
Parameters params = camera.getParameters();
//params.setPreviewSize(width, height);
//params.setPictureFormat(PixelFormat.JPEG);
camera.setParameters(params);
camera.startPreview();
}
public void surfaceDestroyed(SurfaceHolder arg0)
{
//camera.stopPreview();
//camera.release();
stopCamera();
}
public void onResume() {
//camera.startPreview();
startCamera();
}
public void onPause() {
// TODO Auto-generated method stub
//camera.stopPreview();
stopCamera();
}
public void switchCam(String newCamId) {
/*camera.stopPreview();
//camera.release();
if(camID.equals("front")){
camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
}else{
camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
}*/
//camera.startPreview();
//camera=Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
stopCamera();
camID = newCamId;
startCamera();
}
public void stopCamera(){
System.out.println("stopCamera method");
if (camera != null){
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera = null;
previewHolder.removeCallback(this);
previewHolder = null;
}
}
private void startCamera(){
if(camID.equals("front")){
camera=Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
}else{
camera=Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
}
try {
camera.setPreviewDisplay(previewHolder);
camera.setPreviewCallback(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera arg1) {
//FileOutputStream outStream = null;
/*try {
//outStream = new FileOutputStream(String.format(
//"/sdcard/%d.jpg", System.currentTimeMillis()));
//outStream.write(data);
//outStream.close();
Log.d(TAG, "onPreviewFrame - wrote bytes: "
+ data.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}*/
//CamLayer.this.invalidate();
}
});
}
catch (Throwable e){ Log.w("TAG,", "failed create surface !?!?"); }
}
public void draw(Canvas canvas) {
super.draw(canvas);
Paint p = new Paint(Color.RED);
Log.d(TAG, "draw");
canvas.drawText("PREVIEW", canvas.getWidth() / 2,
canvas.getHeight() / 2, p);
}
}
This thread says raw is not supported
https://groups.google.com/forum/?fromgroups#!topic/android-developers/D43AdrbP9oE
A raw image would consume too much memory is my guess. Other than that, I'm also disappointed its not supported.

Categories

Resources