Ok this has been happening to me a few times over the past few weeks and I can't figure out how to fix it. Basically my app uses the camera but every so often after a few goes with the camera on the app it then force closes sometimes and cannot be used even with other apps or the default camera on the phone.
I found the only way to fix this is to restart the phone.
From what I have read so far I understand I need to call
camera.release();
camera = null;
But I still get the error of force close sometimes, is it possible for someone just to take a look through maybe I am missing a camera.release(); somewhere.
public class AndroidCamera extends Activity implements SurfaceHolder.Callback{
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean previewing = false;
LayoutInflater controlInflater = null;
final int RESULT_SAVEIMAGE = 0;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView)findViewById(R.id.camerapreview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
controlInflater = LayoutInflater.from(getBaseContext());
View viewControl = controlInflater.inflate(R.layout.control, null);
LayoutParams layoutParamsControl
= new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT);
this.addContentView(viewControl, layoutParamsControl);
Button buttonTakePicture = (Button)findViewById(R.id.takepicture);
buttonTakePicture.setOnClickListener(new Button.OnClickListener(){
public void onClick(View arg0) {
// TODO Auto-generated method stub
camera.takePicture(myShutterCallback,
myPictureCallback_RAW, myPictureCallback_JPG);
}});
}
ShutterCallback myShutterCallback = new ShutterCallback(){
public void onShutter() {
// TODO Auto-generated method stub
}};
PictureCallback myPictureCallback_RAW = new PictureCallback(){
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
}};
PictureCallback myPictureCallback_JPG = new PictureCallback(){
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
/*Bitmap bitmapPicture
= BitmapFactory.decodeByteArray(arg0, 0, arg0.length); */
int imageNum = 0;
Intent imageIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File imagesFolder = new File(Environment.getExternalStorageDirectory(), "Punch");
imagesFolder.mkdirs(); // <----
String fileName = "image_" + String.valueOf(imageNum) + ".jpg";
File output = new File(imagesFolder, fileName);
while (output.exists()){
imageNum++;
fileName = "image_" + String.valueOf(imageNum) + ".jpg";
output = new File(imagesFolder, fileName);
}
Uri uriSavedImage = Uri.fromFile(output);
imageIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
OutputStream imageFileOS;
try {
imageFileOS = getContentResolver().openOutputStream(uriSavedImage);
imageFileOS.write(arg0);
imageFileOS.flush();
imageFileOS.close();
Toast.makeText(AndroidCamera.this,
"Image saved",
Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Intent intent = new Intent(getBaseContext(), Punch.class);
intent.putExtra("filepath",uriSavedImage.toString());
//just using a request code of zero
int request=0;
startActivityForResult(intent,request);
}};
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if(previewing){
camera.stopPreview();
previewing = false;
}
if (camera != null){
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
camera.release();
e.printStackTrace();
}
}
}
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera = Camera.open();
try {
Camera.Parameters parameters = camera.getParameters();
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
// This is an undocumented although widely known feature
parameters.set("orientation", "portrait");
// For Android 2.2 and above
camera.setDisplayOrientation(90);
// Uncomment for Android 2.0 and above
parameters.setRotation(90);
} else {
// This is an undocumented although widely known feature
parameters.set("orientation", "landscape");
// For Android 2.2 and above
camera.setDisplayOrientation(0);
// Uncomment for Android 2.0 and above
parameters.setRotation(0);
}
camera.setParameters(parameters);
camera.setPreviewDisplay(holder);
} catch (IOException exception) {
camera.release();
}
camera.startPreview();
}
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
if(previewing && camera != null) {
if(camera!=null) {
camera.stopPreview();
camera.release();
camera = null;
}
previewing = false;
}
}
}
The logcat gave me (there is more but I think its because the camera force closes on me so the rest of the app doesn't run.
01-03 14:59:17.835: D/AndroidRuntime(16531): Shutting down VM
01-03 14:59:17.835: W/dalvikvm(16531): threadid=1: thread exiting with uncaught exception (group=0x4001d5a0)
01-03 14:59:17.845: E/AndroidRuntime(16531): FATAL EXCEPTION: main
01-03 14:59:17.845: E/AndroidRuntime(16531): java.lang.RuntimeException: Fail to connect to camera service
I solved the same problem with closing camera in onPause() event
#Override
protected void onPause()
{
super.onPause();
if (camera != null) {
camera.stopPreview();
camera.release();
camera = null;
}
}
Related
In my code all is going well but clicked Image is being saved in Landscape Mode in given Directory. I have tried my best. Please help and suggest me to resolve this issue.
The complete Code is given below with Print screen.
or download from here
https://www.dropbox.com/sh/vp6ohly4zb5vmvq/AACOyS8PvsRxFGBP9zjlVWhza?dl=0
Image saved in SDcard even captured in portrait it appear in landscape
public class AndroidCamera extends Activity implements SurfaceHolder.Callback{
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean previewing = false;
LayoutInflater controlInflater = null;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//camera.enableShutterSound(true);
getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView)findViewById(R.id.camerapreview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
controlInflater = LayoutInflater.from(getBaseContext());
View viewControl = controlInflater.inflate(R.layout.control, null);
LayoutParams layoutParamsControl
= new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT);
this.addContentView(viewControl, layoutParamsControl);
Button buttonTakePicture = (Button)findViewById(R.id.takepicture);
buttonTakePicture.setOnClickListener(new Button.OnClickListener(){
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
camera.takePicture(myShutterCallback,
myPictureCallback_RAW, myPictureCallback_JPG);
}});
}
ShutterCallback myShutterCallback = new ShutterCallback(){
#Override
public void onShutter() {
// TODO Auto-generated method stub
}};
PictureCallback myPictureCallback_RAW = new PictureCallback(){
#Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
}};
PictureCallback myPictureCallback_JPG = new PictureCallback(){
#Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
Bitmap bitmapPicture
= BitmapFactory.decodeByteArray(arg0, 0, arg0.length);
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/cam_Api");
myDir.mkdirs();
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream(String.format("/sdcard/cam_Api/cam_Ap1_%d.jpg", System.currentTimeMillis()));
outStream.write(arg0);
outStream.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
finally {
}
Toast.makeText(getApplicationContext(), "Picture Saved", Toast.LENGTH_LONG).show();
refreshCamera();
// File file = new File(Environment.getExternalStorageDirectory(),"/cam_Api/MyPhoto2.jpg");
}};
public void refreshCamera() {
if (surfaceHolder.getSurface() == null) {
return;
}
try {
camera.stopPreview();
}
catch (Exception e) {
}
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
}
catch (Exception e) {
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if(previewing){
camera.stopPreview();
previewing = false;
}
if (camera != null){
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera = Camera.open();
camera.setDisplayOrientation(90);
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}
}
It seems you are calling:
camera.setDisplayOrientation(90);
which would probably cause the landscape image you are seeing when your application is in portrait mode.
You should use:
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
to get the rotation of your display and then set:
caemra.setDisplayOrientation(rotation);
or just call camera.setDisplayOrientation(0) and set screenOrientation in your android manifest as so:
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
to prevent the orientation changing.
you need to rotate the image and then save it.
public static Bitmap rotateImage(Bitmap bitmapSrc) {
Matrix matrix = new Matrix();
matrix.postRotate(CameraConfigurationUtils.previewRotation);
return Bitmap.createBitmap(bitmapSrc, 0, 0,
bitmapSrc.getWidth(), bitmapSrc.getHeight(), matrix, true);
}
To get the rotation:
private static int setCameraDisplayOrientation(Context mContext, android.hardware.Camera.CameraInfo info) {
int rotation = ((CameraActivity) mContext).getWindowManager().getDefaultDisplay()
.getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0:
degrees = 0;
break;
case Surface.ROTATION_90:
degrees = 90;
break;
case Surface.ROTATION_180:
degrees = 180;
break;
case Surface.ROTATION_270:
degrees = 270;
break;
}
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
previewRotation = (info.orientation + degrees) % 360;
previewRotation = (360 - previewRotation) % 360; // compensate the mirror
} else { // back-facing
previewRotation = (info.orientation - degrees + 360) % 360;
}
return previewRotation;
}
I am making an android camera app that can show the preview and taking photo. There are 2 buttons implemented in this activity: Start the preview and stop the preview. When users click on the stop preview button, the app would capture a photo. However, when I was testing my app, the code associated with the stop preview seems to be skipped and not executed. Below is my code:
SuppressWarnings("deprecation")
public class CameraOpened extends Activity implements SurfaceHolder.Callback{
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean previewing = false;
static final int REQUEST_IMAGE_CAPTURE = 1;
int count;
PictureCallback rawCallback;
ShutterCallback shutterCallback;
PictureCallback jpegCallback;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera_opened);
Button buttonStartCameraPreview = (Button)findViewById(R.id.startcamerapreview);
Button buttonStopCameraPreview = (Button)findViewById(R.id.stopcamerapreview);
getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView)findViewById(R.id.surfaceview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
shutterCallback = new ShutterCallback() {
public void onShutter() {
Log.i("Log", "onShutter'd");
}
};
rawCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
Log.d("Log", "onPictureTaken - raw");
}
};
jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream outStream = null;
try {
String dir;
dir = Environment.getExternalStorageDirectory().toString() + "/DCIM/";
File newdir = new File(dir);
newdir.mkdirs();
File imageFileName = new File(newdir, "crop_"+ ".jpg");
outStream = new FileOutputStream(imageFileName);
outStream.write(data);
outStream.close();
Log.d("Log", "onPictureTaken - wrote bytes: " + data.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
Log.d("Log", "onPictureTaken - jpeg");
}
};
buttonStartCameraPreview.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v) {
// TODO Auto-generated method stub
if(!previewing){
camera = Camera.open();
camera.setDisplayOrientation(90);
if (camera != null){
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}});
buttonStopCameraPreview.setOnClickListener(new Button.OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(camera != null && previewing){
camera.takePicture(shutterCallback, rawCallback, jpegCallback);
previewing = false;
camera.stopPreview();
camera.release();
camera = null;
}
}});
}
public void savePhoto(Bitmap bmp)
{
String dir;
dir = Environment.getExternalStorageDirectory().toString() + "/DCIM/";
File newdir = new File(dir);
newdir.mkdirs();
FileOutputStream out = null;
//file name
Calendar c = Calendar.getInstance();
String date = fromInt(c.get(Calendar.MONTH))
+ fromInt(c.get(Calendar.DAY_OF_MONTH))
+ fromInt(c.get(Calendar.YEAR))
+ fromInt(c.get(Calendar.HOUR_OF_DAY))
+ fromInt(c.get(Calendar.MINUTE))
+ fromInt(c.get(Calendar.SECOND));
File imageFileName = new File(newdir, "crop_"+ ".jpg");
try
{
out = new FileOutputStream(imageFileName);
bmp.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
out = null;
} catch (Exception e)
{
e.printStackTrace();
}
}
public String fromInt(int val)
{
return String.valueOf(val);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.camera_opened, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
private void captureImage() {
// TODO Auto-generated method stub
//camera.takePicture(shutterCallback, rawCallback, jpegCallback);
}
}
And below is my LogCat:
10-22 20:28:38.218: D/Camera(14375): [CTA] Camera open urrentpackagename = com.camera
10-22 20:28:38.218: D/Camera(14375): [CTA] Camera open application != null
10-22 20:28:38.218: D/Camera(14375): [CTA] check CTA permisson mAllowUsing = true
10-22 20:28:39.258: I/Choreographer(14375): Skipped 61 frames! The application may be doing too much work on its main thread.
10-22 20:28:49.318: D/Camera(14375): [CTA] Camera open urrentpackagename = com.camera
10-22 20:28:49.318: D/Camera(14375): [CTA] Camera open application != null
10-22 20:28:49.318: D/Camera(14375): [CTA] check CTA permisson mAllowUsing = true
10-22 20:28:53.028: I/Choreographer(14375): Skipped 77 frames! The application may be doing too much work on its main thread.
Any idea on how to solve this problem?
Use Background Thread for camera operations i am hopeful it will helpful
ref# AsyncTask Android Guide
I need to use camera without preview and take more than one shots.
I have written my code and I am able to take one shot, it works properly.
But I could not handle to do more than once. Because the logic of Camera Service i tried a method CreateCameraTakeShot, still no success.
Could you please help me with that?
Here is my code;
public class ContinuingCallActivity extends Activity implements SurfaceHolder.Callback{
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
FileOutputStream outStream;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_continuingcall);
//getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView)findViewById(R.id.surfaceView1);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// for(int i=0;i<10;i++)
//{
mHandler.postDelayed(mLaunchTask, 1000);
//}
}
Handler mHandler = new Handler();
private Runnable mLaunchTask = new Runnable() {
#Override
public void run() {
camera.takePicture(null,myPictureCallback_RAW, myPictureCallback_JPG);
//createCameraTakeShot();
}
};
ShutterCallback myShutterCallback = new ShutterCallback(){
#Override
public void onShutter() {
// TODO Auto-generated method stub
}};
PictureCallback myPictureCallback_RAW = new PictureCallback(){
#Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
}};
PictureCallback myPictureCallback_JPG = new PictureCallback(){
#Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
Bitmap bitmapPicture
= BitmapFactory.decodeByteArray(arg0, 0, arg0.length);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmapPicture.compress(Bitmap.CompressFormat.JPEG, 40, bytes);
final String dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/MySight/";
File newdir = new File(dir);
newdir.mkdirs();
Date d = new Date();
CharSequence dateOfShot = DateFormat.format("dd-MM-yy hh:mm:ss", d.getTime());
String file = dir+dateOfShot+".jpg";
File newfile = new File(file);
try {
newfile.createNewFile();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
outStream = new FileOutputStream(newfile);
outStream.write(bytes.toByteArray());
outStream.close();
Log.d("Log", "onPictureTaken - wrote bytes: " + arg0.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}};
public void createCameraTakeShot()
{
camera = Camera.open();
if (camera != null)
{
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
camera.takePicture(null,myPictureCallback_RAW, myPictureCallback_JPG);
camera.stopPreview();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if(previewing){
camera.stopPreview();
previewing = false;
}
if (camera != null){
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera = Camera.open();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera.stopPreview();
//camera.release();
//camera = null;
previewing = false;
}
}
you can use timer task insted of handler to take picture prodically
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
surfaceView = (SurfaceView)findViewById(R.id.surfaceView1);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
MyTimerTask myTask = new MyTimerTask();
Timer myTimer = new Timer();
myTimer.schedule(myTask, 1000, 1000);
}
class MyTimerTask extends TimerTask {
public void run() {
// ERROR
camera.takePicture(null,myPictureCallback_RAW, myPictureCallback_JPG);
}
}
ShutterCallback myShutterCallback = new ShutterCallback(){
#Override
public void onShutter() {
// TODO Auto-generated method stub
}};
PictureCallback myPictureCallback_RAW = new PictureCallback(){
#Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
}};
PictureCallback myPictureCallback_JPG = new PictureCallback(){
#Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
Bitmap bitmapPicture
= BitmapFactory.decodeByteArray(arg0, 0, arg0.length);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmapPicture.compress(Bitmap.CompressFormat.JPEG, 40, bytes);
final String dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/MySight/";
File newdir = new File(dir);
newdir.mkdirs();
Date d = new Date();
CharSequence dateOfShot = DateFormat.format("dd-MM-yy hh:mm:ss", d.getTime());
String file = dir+dateOfShot+".jpg";
File newfile = new File(file);
try {
newfile.createNewFile();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
outStream = new FileOutputStream(newfile);
outStream.write(bytes.toByteArray());
outStream.close();
Log.d("Log", "onPictureTaken - wrote bytes: " + arg0.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}};
public void createCameraTakeShot()
{
camera = Camera.open();
if (camera != null)
{
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
camera.takePicture(null,myPictureCallback_RAW, myPictureCallback_JPG);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if(previewing){
camera.stopPreview();
previewing = false;
}
if (camera != null){
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera = Camera.open();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera.stopPreview();
//camera.release();
//camera = null;
previewing = false;
}
}
UPDATE
Added
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
to the manifest all works ok now.
Ok so I have a app I have started to create which in the end I want to be able to take a picture, which then takes you to another screen which lets you be able to "Use" or "Retake" the picture.
When the image is took it needs to be saved into a new folder on the SD Card, (if the folder is not there then it needs to create it). I had all this working a couple of weeks ago but after i did some editing and shut down eclipse I cant seem to get it back working?
The section for this is after int imageNum = 0; i have added imagesFolder.mkdirs(); which i belive is correct to create a new folder but even this seems not to be working now.
Now the image just gets took and neither the new folder gets created or the image gets saved.
public class AndroidCamera extends Activity implements SurfaceHolder.Callback {
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean previewing = false;
LayoutInflater controlInflater = null;
final int RESULT_SAVEIMAGE = 0;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView) findViewById(R.id.camerapreview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
controlInflater = LayoutInflater.from(getBaseContext());
View viewControl = controlInflater.inflate(R.layout.control, null);
LayoutParams layoutParamsControl = new LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
this.addContentView(viewControl, layoutParamsControl);
Button buttonTakePicture = (Button) findViewById(R.id.takepicture);
buttonTakePicture.setOnClickListener(new Button.OnClickListener() {
public void onClick(View arg0) {
// TODO Auto-generated method stub
camera.takePicture(myShutterCallback, myPictureCallback_RAW,
myPictureCallback_JPG);
}
});
}
ShutterCallback myShutterCallback = new ShutterCallback() {
public void onShutter() {
// TODO Auto-generated method stub
}
};
PictureCallback myPictureCallback_RAW = new PictureCallback() {
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
}
};
PictureCallback myPictureCallback_JPG = new PictureCallback(){
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
/*Bitmap bitmapPicture
= BitmapFactory.decodeByteArray(arg0, 0, arg0.length); */
int imageNum = 0;
Intent imageIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File imagesFolder = new File(Environment.getExternalStorageDirectory(), "BeatEmUp");
imagesFolder.mkdirs();
String fileName = "image_" + String.valueOf(imageNum) + ".jpg";
File output = new File(imagesFolder, fileName);
while (output.exists()){
imageNum++;
fileName = "image_" + String.valueOf(imageNum) + ".jpg";
output = new File(imagesFolder, fileName);
}
Uri uriSavedImage = Uri.fromFile(output);
imageIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
OutputStream imageFileOS;
try {
imageFileOS = getContentResolver().openOutputStream(uriSavedImage);
imageFileOS.write(arg0);
imageFileOS.flush();
imageFileOS.close();
Toast.makeText(AndroidCamera.this,
"Image saved: ",
Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
camera.startPreview();
}};
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if (previewing) {
camera.stopPreview();
previewing = false;
}
if (camera != null) {
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera = Camera.open();
try {
Camera.Parameters parameters = camera.getParameters();
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
// This is an undocumented although widely known feature
parameters.set("orientation", "portrait");
// For Android 2.2 and above
camera.setDisplayOrientation(90);
// Uncomment for Android 2.0 and above
parameters.setRotation(90);
} else {
// This is an undocumented although widely known feature
parameters.set("orientation", "landscape");
// For Android 2.2 and above
camera.setDisplayOrientation(0);
// Uncomment for Android 2.0 and above
parameters.setRotation(0);
}
camera.setParameters(parameters);
camera.setPreviewDisplay(holder);
} catch (IOException exception) {
camera.release();
}
camera.startPreview();
}
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}
}
You should make sure the manifest lists the permission to write to the SD card:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I have a app which at the moment takes a image using the camera, at the moment once the image is took it saves to a folder on the SD Card and then the same screen stays on so another picture can be took.
I am wanting it so when the image has been took and saved a new screen opens with the picture on the new screen.
I have made a new xml file punch.xml and java Punch.java and registerd them in the manifest I just cant figure out how to set the app to open a new screen with the picture that has just been took.
Im guessing it is something to do with opening a new Intent once the image has been saved.
Update
Ok so all working now execpt getting the image to show on the next screen?
Punch.java
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.punch);
String myRef = this.getIntent().getStringExtra("filepath");
}
AndroidCamera.java UPDATED TO REFLECT CODE CHANGES
public class AndroidCamera extends Activity implements SurfaceHolder.Callback{
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean previewing = false;
LayoutInflater controlInflater = null;
final int RESULT_SAVEIMAGE = 0;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView)findViewById(R.id.camerapreview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
controlInflater = LayoutInflater.from(getBaseContext());
View viewControl = controlInflater.inflate(R.layout.control, null);
LayoutParams layoutParamsControl
= new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT);
this.addContentView(viewControl, layoutParamsControl);
Button buttonTakePicture = (Button)findViewById(R.id.takepicture);
buttonTakePicture.setOnClickListener(new Button.OnClickListener(){
public void onClick(View arg0) {
// TODO Auto-generated method stub
camera.takePicture(myShutterCallback,
myPictureCallback_RAW, myPictureCallback_JPG);
}});
}
ShutterCallback myShutterCallback = new ShutterCallback(){
public void onShutter() {
// TODO Auto-generated method stub
}};
PictureCallback myPictureCallback_RAW = new PictureCallback(){
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
}};
PictureCallback myPictureCallback_JPG = new PictureCallback(){
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
/*Bitmap bitmapPicture
= BitmapFactory.decodeByteArray(arg0, 0, arg0.length); */
int imageNum = 0;
Intent imageIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File imagesFolder = new File(Environment.getExternalStorageDirectory(), "Punch");
imagesFolder.mkdirs(); // <----
String fileName = "image_" + String.valueOf(imageNum) + ".jpg";
File output = new File(imagesFolder, fileName);
while (output.exists()){
imageNum++;
fileName = "image_" + String.valueOf(imageNum) + ".jpg";
output = new File(imagesFolder, fileName);
}
Uri uriSavedImage = Uri.fromFile(output);
imageIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
OutputStream imageFileOS;
try {
imageFileOS = getContentResolver().openOutputStream(uriSavedImage);
imageFileOS.write(arg0);
imageFileOS.flush();
imageFileOS.close();
Toast.makeText(AndroidCamera.this,
"Image saved",
Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Intent intent = new Intent(getBaseContext(), Punch.class);
intent.putExtra("filepath",uriSavedImage);
//just using a request code of zero
int request=0;
startActivityForResult(intent,request);
}};
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if(previewing){
camera.stopPreview();
previewing = false;
}
if (camera != null){
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera = Camera.open();
try {
Camera.Parameters parameters = camera.getParameters();
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
// This is an undocumented although widely known feature
parameters.set("orientation", "portrait");
// For Android 2.2 and above
camera.setDisplayOrientation(90);
// Uncomment for Android 2.0 and above
parameters.setRotation(90);
} else {
// This is an undocumented although widely known feature
parameters.set("orientation", "landscape");
// For Android 2.2 and above
camera.setDisplayOrientation(0);
// Uncomment for Android 2.0 and above
parameters.setRotation(0);
}
camera.setParameters(parameters);
camera.setPreviewDisplay(holder);
} catch (IOException exception) {
camera.release();
}
camera.startPreview();
}
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}
}
UPDATE
Looking at the suggestion to use putExtra() how do I set and retrieve this value?
The problem here is that you are calling
camera.startPreview();
in your pictureTaken callback.
You replace it with your code from onClick and change it startActivityForResult():
Intent intent = new Intent(getBaseContext(), Punch.class);
intent.putExtra("filepath",uriSavedImage);
//just using a request code of zero
int request=0;
startActivityForResult(intent,request);
Then you can implement onActivityResult and call camera.StartPreview() from there.
Don't forget to setResult in your Punch activity
You could save a reference to the location of where the image is saved, put that in an intent to open a new activity. Start the new activity and show the image, allow the user to delete etc.
Intent intent = new Intent(getBaseContext(), target.class);
intent.putExtra("ImageReference", reference);
startActivity(intent);
Whereas target.class is the name of your activity class.
So in your code above you seem to be going about setting the intent fine. This will run immediately after taking a picture.
Obviously you will need to reference where you saved the file. Then in the new activity class you call Punch.class, you will need to do something like:-
String myRef = this.getIntent().getStringExtra("ImageReference");
This will mean that you passed the String file path from the main activity to the new Punch.class that you created. Here you can use the file path to open the image.