I'm trying to open the camera activity, upon launching the application.
Meaning, when I launch the application, it will capture the image via the front camera.
however, when I launch the application, I've error.
I'm actually trying to run a code that I gotten from github; however, it just force restart the application.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.androidmyway.demo.capturecameraimage, PID: 5697
java.lang.RuntimeException: setParameters failed
at android.hardware.Camera.native_setParameters(Native Method)
at android.hardware.Camera.setParameters(Camera.java:1966)
at com.androidmyway.demo.capturecameraimage.CameraView.surfaceChanged(CameraView.java:140)
at android.view.SurfaceView.updateWindow(SurfaceView.java:634)
at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:161)
at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:944)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2205)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1250)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6311)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:871)
at android.view.Choreographer.doCallbacks(Choreographer.java:683)
at android.view.Choreographer.doFrame(Choreographer.java:619)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:241)
at android.app.ActivityThread.main(ActivityThread.java:6217)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
CameraView.java
public class CameraView extends Activity implements SurfaceHolder.Callback, OnClickListener{
private static final String TAG = "CameraTest";
Camera mCamera;
boolean mPreviewRunning = false;
#SuppressWarnings("deprecation")
public void onCreate(Bundle icicle){
super.onCreate(icicle);
Log.e(TAG, "onCreate");
getWindow().setFormat(PixelFormat.TRANSLUCENT);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.cameraview);
ImageView img = (ImageView) findViewById(R.id.blankImage);
if(CaptureCameraImage.isBlack)
img.setBackgroundResource(android.R.color.black);
else
img.setBackgroundResource(android.R.color.white);
mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera);
mSurfaceView.setOnClickListener(this);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState){
super.onRestoreInstanceState(savedInstanceState);
}
Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
if (data != null){
//Intent mIntent = new Intent();
//mIntent.putExtra("image",imageData);
mCamera.stopPreview();
mPreviewRunning = false;
mCamera.release();
try{
BitmapFactory.Options opts = new BitmapFactory.Options();
Bitmap bitmap= BitmapFactory.decodeByteArray(data, 0, data.length,opts);
bitmap = Bitmap.createScaledBitmap(bitmap, 300, 300, false);
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int newWidth = 300;
int newHeight = 300;
// calculate the scale - in this case = 0.4f
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// createa matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// rotate the Bitmap
matrix.postRotate(-90);
Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
width, height, matrix, true);
CaptureCameraImage.image.setImageBitmap(resizedBitmap);
}catch(Exception e){
e.printStackTrace();
}
//StoreByteImage(mContext, imageData, 50,"ImageName");
//setResult(FOTO_MODE, mIntent);
setResult(585);
finish();
}
}
};
protected void onResume(){
Log.e(TAG, "onResume");
super.onResume();
}
protected void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
}
protected void onStop(){
Log.e(TAG, "onStop");
super.onStop();
}
#TargetApi(9)
public void surfaceCreated(SurfaceHolder holder){
Log.e(TAG, "surfaceCreated");
mCamera = Camera.open(CaptureCameraImage.cameraID);
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Log.e(TAG, "surfaceChanged");
// XXX stopPreview() will crash if preview is not running
if (mPreviewRunning){
mCamera.stopPreview();
}
Camera.Parameters p = mCamera.getParameters();
p.setPreviewSize(300, 300);
if(CaptureCameraImage.cameraID == 0){
String stringFlashMode = p.getFlashMode();
if (stringFlashMode.equals("torch"))
p.setFlashMode("on"); // Light is set off, flash is set to normal 'on' mode
else
p.setFlashMode("torch");
}
mCamera.setParameters(p);
try{
mCamera.setPreviewDisplay(holder);
}catch (Exception e){
// TODO Auto-generated catch block
e.printStackTrace();
}
mCamera.startPreview();
mPreviewRunning = true;
mCamera.takePicture(null, mPictureCallback, mPictureCallback);
}
public void surfaceDestroyed(SurfaceHolder holder) {
Log.e(TAG, "surfaceDestroyed");
//mCamera.stopPreview();
//mPreviewRunning = false;
//mCamera.release();
}
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
public void onClick(View v) {
// TODO Auto-generated method stub
mCamera.takePicture(null, mPictureCallback, mPictureCallback);
}
}
CameraView.java
public class CaptureCameraImage extends Activity {
public static int cameraID = 0;
public static boolean isBlack = true;
public static ImageView image;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activitycapturecameraimage);
image = (ImageView) findViewById(R.id.imgView);
}
public void onFrontClick(View v){
RadioButton rdbBlack = (RadioButton) findViewById(R.id.rdb_black);
if(rdbBlack.isChecked()){
isBlack = true;
}else{
isBlack = false;
}
cameraID = 1;
Intent i = new Intent(CaptureCameraImage.this,CameraView.class);
startActivityForResult(i, 999);
}
public void onBackClick(View v){
RadioButton rdbBlack = (RadioButton) findViewById(R.id.rdb_black);
if(rdbBlack.isChecked()){
isBlack = true;
}else{
isBlack = false;
}
cameraID = 0;
Intent i = new Intent(CaptureCameraImage.this,CameraView.class);
startActivityForResult(i, 999);
}
}
Even thought some devices support arbitory preview sizes some do not. There for you have to do this on your surfaceChanged Method
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Camera.Parameters param = camera.getParameters();
List<Camera.Size> previewSizes = param.getSupportedPreviewSizes();
Camera.Size ps = // .... select a previewSize
param.setPreviewSize(ps.width, ps.height);
camera.setParameters(param);
camera.startPreview();
}
look here
It's happening because may be Flash on Front Camera. try to off flash on front camera using FLASH_MODE_OFF
Camera.Parameters p = mCamera.getParameters();
p.setPreviewSize(300, 300);
if(CaptureCameraImage.cameraID == 0){
String stringFlashMode = p.getFlashMode();
if (stringFlashMode.equals("torch"))
p.setFlashMode("on"); // Light is set off, flash is set to normal 'on' mode
else
p.setFlashMode("torch");
}else{
p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
}
mCamera.setParameters(p);
Related
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
Button facedetect;
GraphicOverlay graphicOverlay;
CameraView cameraView;
AlertDialog alertDialog;
Bitmap captureImage, saveImage;
Bitmap b1,b2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
facedetect = findViewById(R.id.detect_face_btn);
graphicOverlay = findViewById(R.id.graphic_overlay);
cameraView = findViewById(R.id.camera_view);
facedetect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
cameraView.start();
cameraView.captureImage();
graphicOverlay.clear();
}
});
cameraView.addCameraKitListener(new CameraKitEventListenerAdapter() {
#Override
public void onEvent(CameraKitEvent event) {
super.onEvent(event);
}
#Override
public void onError(CameraKitError error) {
super.onError(error);
}
#Override
public void onImage(CameraKitImage image) {
super.onImage(image);
alertDialog.show();
b1 = image.getBitmap();
b1 = Bitmap.createScaledBitmap(b1, cameraView.getWidth(), cameraView.getHeight(), false);
cameraView.stop();
getImageFromLocal();`enter code here`
// if ( compareImages(b1,b2)==true) {
// Toast.makeText(getApplicationContext(),"True",Toast.LENGTH_SHORT).show();
// }
// Toast.makeText(getApplicationContext(),"False",Toast.LENGTH_SHORT).show();
processFaceDetaection(b1);
}
#Override
public void onVideo(CameraKitVideo video) {
super.onVideo(video);
}
});
}
private void processFaceDetaection(Bitmap bitmap) {
FirebaseVisionImage firebaseVisionImage = FirebaseVisionImage.fromBitmap(bitmap);
FirebaseVisionFaceDetectorOptions firebaseVisionFaceDetectorOptions = new FirebaseVisionFaceDetectorOptions.Builder().build();
// High-accuracy landmark detection and face classification
FirebaseVisionFaceDetectorOptions landmarkdetectionfacedetection =
new FirebaseVisionFaceDetectorOptions.Builder()
.setPerformanceMode(FirebaseVisionFaceDetectorOptions.ACCURATE)
.setLandmarkMode(FirebaseVisionFaceDetectorOptions.ALL_LANDMARKS)
.setClassificationMode(FirebaseVisionFaceDetectorOptions.ALL_CLASSIFICATIONS)
.build();
// Real-time contour detection of multiple faces
FirebaseVisionFaceDetectorOptions contourdetectionfacedetection =
new FirebaseVisionFaceDetectorOptions.Builder()
.setContourMode(FirebaseVisionFaceDetectorOptions.ALL_CONTOURS)
.build();
FirebaseVisionFaceDetector firebaseVisionFaceDetector = FirebaseVision.getInstance().getVisionFaceDetector(firebaseVisionFaceDetectorOptions);
// FirebaseVisionFaceDetector firebaseVisionFaceDetector = FirebaseVision.getInstance().getVisionFaceDetector(contourdetectionfacedetection);
firebaseVisionFaceDetector.detectInImage(firebaseVisionImage).addOnSuccessListener(new OnSuccessListener<List<FirebaseVisionFace>>() {
#Override
public void onSuccess(List<FirebaseVisionFace> firebaseVisionFaces) {
getFaceResult(firebaseVisionFaces);
compareFaceFromLocal();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
alertDialog.dismiss();
Toast.makeText(MainActivity.this, "Error : " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
private void compareFaceFromLocal() {
if (compareImages(b1, b2) == true) {
Toast.makeText(getApplicationContext(), "True", Toast.LENGTH_SHORT).show();
}
Toast.makeText(getApplicationContext(), "False", Toast.LENGTH_SHORT).show();
}
private void getFaceResult(List<FirebaseVisionFace> firebaseVisionFaces) {
int counter = 0;
for (FirebaseVisionFace face : firebaseVisionFaces) {
Rect rect = face.getBoundingBox();
ReactOverlay reactOverlay = new ReactOverlay(graphicOverlay, rect);
graphicOverlay.add(reactOverlay);
counter = counter + 1;
}
Toast.makeText(MainActivity.this, "No. of faces detected : " + counter, Toast.LENGTH_SHORT).show();
alertDialog.dismiss();
}
private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
static {
ORIENTATIONS.append(Surface.ROTATION_0, 90);
ORIENTATIONS.append(Surface.ROTATION_90, 0);
ORIENTATIONS.append(Surface.ROTATION_180, 270);
ORIENTATIONS.append(Surface.ROTATION_270, 180);
}
/**
* Get the angle by which an image must be rotated given the device's current
* orientation.
*/
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private int getRotationCompensation(String cameraId, Activity activity, Context context)
throws CameraAccessException {
// Get the device's current rotation relative to its "native" orientation.
// Then, from the ORIENTATIONS table, look up the angle the image must be
// rotated to compensate for the device's rotation.
int deviceRotation = activity.getWindowManager().getDefaultDisplay().getRotation();
int rotationCompensation = ORIENTATIONS.get(deviceRotation);
// On most devices, the sensor orientation is 90 degrees, but for some
// devices it is 270 degrees. For devices with a sensor orientation of
// 270, rotate the image an additional 180 ((270 + 270) % 360) degrees.
CameraManager cameraManager = (CameraManager) context.getSystemService(CAMERA_SERVICE);
int sensorOrientation = cameraManager
.getCameraCharacteristics(cameraId)
.get(CameraCharacteristics.SENSOR_ORIENTATION);
rotationCompensation = (rotationCompensation + sensorOrientation + 270) % 360;
// Return the corresponding FirebaseVisionImageMetadata rotation value.
int result;
switch (rotationCompensation) {
case 0:
result = FirebaseVisionImageMetadata.ROTATION_0;
break;
case 90:
result = FirebaseVisionImageMetadata.ROTATION_90;
break;
case 180:
result = FirebaseVisionImageMetadata.ROTATION_180;
break;
case 270:
result = FirebaseVisionImageMetadata.ROTATION_270;
break;
default:
result = FirebaseVisionImageMetadata.ROTATION_0;
Log.e(TAG, "Bad rotation value: " + rotationCompensation);
}
return result;
}
#Override
protected void onPause() {
super.onPause();
cameraView.stop();
}
#Override
protected void onResume() {
super.onResume();
cameraView.start();
}
private void getImageFromLocal() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, 0);
}
/*Compare two images.
* #param bitmap1
* #param bitmap2
* #return true iff both images have the same dimensions and pixel values.*/
public static boolean compareImages(Bitmap bitmap1, Bitmap bitmap2) {
if (bitmap1.getWidth() != bitmap2.getWidth() ||
bitmap1.getHeight() != bitmap2.getHeight()) {
return false;
}
for (int y = 0; y < bitmap1.getHeight(); y++) {
for (int x = 0; x < bitmap1.getWidth(); x++) {
if (bitmap1.getPixel(x, y) != bitmap2.getPixel(x, y)) {
return false;
}
}
}
return true;
}
public static Uri imageURI;
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == 0) {
if (data != null) {
try {
b2 = MediaStore.Images.Media.getBitmap(getApplicationContext().getContentResolver(), data.getData());
} catch (IOException e) {
e.printStackTrace();
}
}
}
} else {
System.exit(0);
Log.e("result", "BAD");
}
}
}
I'm making a very basic camera app using Google's camera API.
Initially launching the app is fine, but upon leaving and reentering, it crashes. I have found similar answers but I couldn't apply them to my specific code/situation. I have also tried messing around with onPause(), onResume, etc. but to no avail. Why is this happening and how can I fix this?
Below are the relevant methods and error log.
SurfaceView class:
public class ImageSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private Camera camera;
private SurfaceHolder surfaceHolder;
private String TAG = ImageSurfaceView.class.getSimpleName();
public ImageSurfaceView(Context context, Camera camera) {
super(context);
this.camera = camera;
surfaceHolder = getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
this.camera.setPreviewDisplay(holder);
this.camera.startPreview();
this.camera.setDisplayOrientation(90);
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (holder.getSurface() == null){
// preview surface does not exist
return;
}
try {
camera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
try {
Camera.Parameters params = camera.getParameters();
List<Camera.Size> supportedPreviewSizes = params.getSupportedPreviewSizes();
Camera.Size camPreviewSize = getOptimalPreviewSize(supportedPreviewSizes, width , height);
params.setPreviewSize(camPreviewSize.width ,camPreviewSize.height);
camera.setParameters(params);
} catch (RuntimeException e) {
Log.d(TAG, "Error getting camera parameters: " + e.getMessage());
}
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception e){
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.release();
camera = null;
}
private void stopPreviewAndFreeCamera() {
if (camera != null) {
// Call stopPreview() to stop updating the preview surface.
camera.stopPreview();
// Important: Call release() to release the camera for use by other
// applications. Applications should release the camera immediately
// during onPause() and re-open() it during onResume()).
camera.release();
camera = null;
}
}
private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
double targetRatio=(double)h / w;
if (sizes == null) return null;
Camera.Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
for (Camera.Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Camera.Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
}
onPause/onResume
protected void onPause() {
Log.d(TAG, " -> onPause");
if(camera != null){
releaseCamera();
}
super.onPause();
Log.d(TAG, " <- onPause");
}
private void releaseCamera(){
if (camera != null){
camera.release();
camera = null;
}
}
#Override
public void onResume() {
super.onResume();
Log.d(TAG, " -> OnResume");
if (camera == null) {
camera = checkDeviceCamera();
}
Log.d(TAG, " <- OnResume");
}
Camera methods:
private Camera checkDeviceCamera(){
Camera mCamera = null;
try {
mCamera = Camera.open();
} catch (Exception e) {
e.printStackTrace();
}
return mCamera;
}
private void startCamera() {
camera = checkDeviceCamera();
mImageSurfaceView = new ImageSurfaceView(MainActivity.this, camera);
cameraPreviewLayout = (FrameLayout) findViewById(R.id.camera_preview); //the framelayout
cameraPreviewLayout.addView(mImageSurfaceView); //adding surfaceview to framelayout
ImageButton captureButton = (ImageButton)findViewById(R.id.imageButton);
captureButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
camera.takePicture(null, null, pictureCallback);
}
});
}
Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera cam) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
if (camera != null) {
camera.startPreview();
}
}
}, 0);
}
};
Error:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: daniel816.com.danger, PID: 10594
java.lang.RuntimeException: Camera is being used after Camera.release() was called
at android.hardware.Camera.setPreviewSurface(Native Method)
at android.hardware.Camera.setPreviewDisplay(Camera.java:738)
at danielwei816.com.danger.ImageSurfaceView.surfaceCreated(ImageSurfaceView.java:33)
at android.view.SurfaceView.updateWindow(SurfaceView.java:634)
at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:256)
at android.view.View.dispatchWindowVisibilityChanged(View.java:10293)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1289)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1289)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1289)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1289)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1289)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1289)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1289)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1599)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1299)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6558)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:871)
at android.view.Choreographer.doCallbacks(Choreographer.java:683)
at android.view.Choreographer.doFrame(Choreographer.java:619)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6316)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)
You have lifecycle of your activity (onResume, onPause etc.) and lifecycle of your SurfaceView (surfaceChanged, surfaceDestroyed etc.).
You release your camera in onPause, but you stop it in surfaceDestroyed (which is called later). I think this is the problem.
public class CameraActivity extends Activity {
private Camera mCamera;
private CameraPreview mPreview;
private FrameLayout mFramePreview;
private boolean mSafeToTakePicture;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
Bundle bundle = savedInstanceState;
if (savedInstanceState == null) {
bundle = getIntent().getExtras();
}
mFramePreview = (FrameLayout) findViewById(R.id.camera_preview);
mSafeToTakePicture = false;
}
#Override
protected void onResume() {
super.onResume();
// Create an instance of Camera
mCamera = getCameraInstance();
Camera.Parameters params = mCamera.getParameters();
List<Camera.Size> supportedSizes = mCamera.getParameters().getSupportedPictureSizes();
int max = 0;
int index = 0;
for (int i = 0; i < supportedSizes.size(); i++){
Camera.Size s = supportedSizes.get(i);
int size = s.height * s.width;
if (size > max) {
index = i;
max = size;
}
}
params.setPictureSize(supportedSizes.get(index).width, supportedSizes.get(index).height);
mCamera.setParameters(params);
mCamera.getParameters().setPictureSize(supportedSizes.get(index).width, supportedSizes.get(index).height);
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
mFramePreview.addView(mPreview);
mSafeToTakePicture = true;
mFramePreview.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (mSafeToTakePicture) {
takePhoto();
mFramePreview.setOnClickListener(null);
mSafeToTakePicture = false;
}
}
});
}
public void takePhoto() {
mCamera.autoFocus(new Camera.AutoFocusCallback() {
#Override
public void onAutoFocus(boolean b, Camera pCamera) {
mCamera.takePicture(null, null, picture);
}
});
}
final Camera.PictureCallback picture = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
/* save picture... */
}
};
}
An exception sometimes happens when I take a picture.
RuntimeException->"takePicture failed" (#android.hardware.Camera:native_takePicture:-2), (#android.hardware.Camera:takePicture:1833), (#android.hardware.Camera:takePicture:1778), (#fr.selic.thuit.activities.CameraActivity$2:onAutoFocus:213), (#android.hardware.Camera$EventHandler:handleMessage:1283), (#android.os.Handler:dispatchMessage:111), (#android.os.Looper:loop:207), (#android.app.ActivityThread:main:5728), (#java.lang.reflect.Method:invoke:-2), (#com.android.internal.os.ZygoteInit$MethodAndArgsCaller:run:789), (#com.android.internal.os.ZygoteInit:main:679),
I have a Glass application where I am trying to use a Live Card to start a Camera Preview activity from the menu options. The application seems to freeze when I move away from the Live Card (say, to the weather) and back, and then try to bring up the camera through the menu options. Sorry for all of the code, here are the following files:
Service.java
. . .
#Override
public IBinder onBind(Intent intent) { return mBinder; }
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (mLiveCard == null) {
mLiveCard = new LiveCard(this, LIVE_CARD_TAG);
mRemoteViews = new RemoteViews(getPackageName(), R.layout.service_layout);
mLiveCard.setViews(mRemoteViews);
// Display the options menu when the live card is tapped.
Intent menuIntent = new Intent(this, MenuActivity.class);
menuIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TASK);
mLiveCard.setAction(PendingIntent.getActivity(this, 0, menuIntent, 0));
mLiveCard.attach(this);
mLiveCard.publish(PublishMode.REVEAL);
} else {
mLiveCard.navigate();
}
return START_STICKY;
}
#Override
public void onDestroy() {
if (mLiveCard != null && mLiveCard.isPublished()) {
mLiveCard.unpublish();
mLiveCard = null;
}
super.onDestroy();
}
}
MenuActivity.java
public class MenuActivity extends Activity {
#Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
// Open the options menu right away.
openOptionsMenu();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.layout, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_stop:
// Stop the service which will unpublish the live card.
stopService(new Intent(MenuActivity.this, Service.class));
return true;
case R.id.action_camera:
startActivity(new Intent(MenuActivity.this, Camera.class));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onOptionsMenuClosed(Menu menu) { finish(); }
}
Camera.java
public class Camera extends Activity {
private SurfaceView mPreview = null;
private SurfaceHolder mPreviewHolder = null;
private Camera mCamera = null;
private boolean inPreview = false;
private boolean cameraConfigured = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera);
mPreview = (SurfaceView) findViewById(R.id.camera_preview);
mPreviewHolder = mPreview.getHolder();
mPreviewHolder.addCallback(surfaceCallback);
}
#Override
public void onResume() {
super.onResume();
mCamera = Camera.open();
startPreview();
}
#Override
public void onPause() {
super.onPause();
if (inPreview) {
mCamera.stopPreview();
}
mCamera.release();
mCamera = null;
inPreview = false;
}
private Camera.Size getBestPreviewSize(int width, int height,
Camera.Parameters parameters) {
Camera.Size result = null;
for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
if (size.width <= width && size.height <= height) {
if (result == null) {
result = size;
} else {
int resultArea = result.width * result.height;
int newArea = size.width * size.height;
if (newArea > resultArea) {
result = size;
}
}
}
}
return (result);
}
private void initPreview(int width, int height) {
if (mCamera != null && mPreviewHolder.getSurface() != null) {
try {
mCamera.setPreviewDisplay(mPreviewHolder);
} catch (Throwable t) {
Log.e("PreviewDemo-surfaceCallback",
"Exception in setPreviewDisplay()", t);
}
if (!cameraConfigured) {
Camera.Parameters parameters = mCamera.getParameters();
Camera.Size size = getBestPreviewSize(width, height,
parameters);
if (size != null) {
parameters.setPreviewSize(size.width, size.height);
mCamera.setParameters(parameters);
cameraConfigured = true;
}
}
}
}
private void startPreview() {
if (cameraConfigured && mCamera != null) {
mCamera.startPreview();
inPreview = true;
}
}
I can't seem to figure out why the camera preview works initially but doesn't work when navigating away. I feel like there is something simple that I am just missing here. Any help would be greatly appreciated!
I'm not sure if this would fix your problem, but I would start and stop the camera this way:
private Camera getCameraInstance() {
Camera mCamera = null;
try {
/* attempt to get a Camera instance */
mCamera = Camera.open();
} catch (Exception e) {
/* Camera is not available (in use or does not exist) */
Log.e(TAG, "Error getting camera: " + e.getMessage());
// process null error here
// finish();
}
/* returns null if camera is unavailable */
return mCamera;
}
#Override
public void onResume() {
super.onResume();
if (mCamera == null) {
mCamera = getCameraInstance();
if (mCamera != null) {
startPreview();
} else {
// process null error here
}
}
}
#Override
public void onPause() {
super.onPause();
if (mCamera != null) {
/* stop preview */
if (inPreview) {
try {
mCamera.stopPreview();
} catch (Exception e) {
/* ignore: tried to stop a non-existent preview */
}
}
/* release the camera */
mCamera.release();
mCamera = null;
inPreview = false;
}
}
I would also check if mCamera or getSurface is null in initPreview.
private void initPreview(int width, int height) {
if (mCamera != null && mPreviewHolder.getSurface() != null) {
try {
mCamera.setPreviewDisplay(mPreviewHolder);
} catch (Throwable t) {
Log.e("PreviewDemo-surfaceCallback",
"Exception in setPreviewDisplay()", t);
}
if (!cameraConfigured) {
Camera.Parameters parameters = mCamera.getParameters();
Camera.Size size = getBestPreviewSize(width, height,
parameters);
if (size != null) {
parameters.setPreviewSize(size.width, size.height);
mCamera.setParameters(parameters);
cameraConfigured = true;
}
}
} else {
Log.e(TAG, "Camera or getSurface is null");
}
}
I'm trying to do a Qr code reader with Zbar but the app crash after the Qr Code detect (when result != 0)
I'm not getting error message, only a warning:
CHECK surface infomation creating=false formatChanged=false
sizeChanged=false visible=false visibleChanged=true
surfaceChanged=true realSizeChanged=false redrawNeeded=false
left=false top=false
Here is the code which I got the crash
public void onPreviewFrame(byte[] data, Camera camera) {
Camera.Parameters parameters = camera.getParameters();
Camera.Size size = parameters.getPreviewSize();
Image barcode = new Image(size.width, size.height, "Y800");
barcode.setData(data);
int result = mScanner.scanImage(barcode);
if (result != 0) {
mCamera.cancelAutoFocus();
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mPreviewing = false;
SymbolSet syms = mScanner.getResults();
for (Symbol sym : syms) {
String symData = sym.getData();
if (!TextUtils.isEmpty(symData)) {
Intent dataIntent = new Intent();
dataIntent.putExtra(SCAN_RESULT, symData);
dataIntent.putExtra(SCAN_RESULT_TYPE, sym.getType());
setResult(Activity.RESULT_OK, dataIntent);
finish();
break;
}
}
}
}
I did update my code and it works great! thx all!
public void onPreviewFrame(byte[] data, Camera camera) {
Camera.Parameters parameters = camera.getParameters();
Camera.Size size = parameters.getPreviewSize();
Image barcode = new Image(size.width, size.height, "Y800");
barcode.setData(data);
int result = mScanner.scanImage(barcode);
if (result != 0) {
mCamera.cancelAutoFocus();
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mPreviewing = false;
SymbolSet syms = mScanner.getResults();
for (Symbol sym : syms) {
String symData = sym.getData();
Log.i("url qr code",symData);
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(symData));
startActivity(browserIntent);
break;
}
}
}
try this... for Qr Reader....
public class QRCodeActivityTest extends Activity implements
OnQRCodeReadListener {
QRCodeReaderView qrView;
TextView tvQr;
Image_Sql sql;
String Description;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.qrtest_layout);
qrView = (QRCodeReaderView) findViewById(R.id.qRCodeReaderView1);
qrView.setOnQRCodeReadListener(this);
tvQr = (TextView) findViewById(R.id.txtqr);
sql= new Image_Sql(this);
sql.Open();
}
#Override
public void onQRCodeRead(String text, PointF[] points) {
// TODO Auto-generated method stub
Cursor desc = sql.fetchNameFromTitle(text);
while (desc.moveToNext()) {
Description = desc.getString(desc
.getColumnIndexOrThrow(Image_Sql.IMAGE_DESCRIPTION));
}
if(text.equals(""))
{
Dialog d = new Dialog(this);
TextView tv = new TextView(this);
tv.setText("Please Sync Catalogue TO Display QRCode Image Information");
d.setContentView(tv);
d.setTitle("Required Syncing..");
d.show();
}else
{
tvQr.setText(Description);
}
}
#Override
public void cameraNotFound() {
// TODO Auto-generated method stub
}
#Override
public void QRCodeNotFoundOnCamImage() {
// TODO Auto-generated method stub
}
#Override
protected void onResume() {
super.onResume();
qrView.getCameraManager().startPreview();
}
#Override
protected void onPause() {
super.onPause();
qrView.getCameraManager().stopPreview();
}
}