tutorial intent example best app android camera

example - intent camera android



takepicture se cuelga en Android 2.3.3 (5)

El problema radica en el hecho de que los códigos a continuación están escritos.

  1. Hay una PreviewCallback definida,

    PreviewCallback mPreviewCallback = new PreviewCallback() { @Override public void onPreviewFrame(byte[] data, Camera camera) { //Log.i(TAG+".mPreviewCallback.onPreviewFrame", "being called!"); } };

  2. mCamera.setPreviewCallback (mPreviewCallback);

  3. mCamera.takePicture ()

Eso funciona en 2.1 / 2.2, pero no en 2.3.

No estoy seguro de si el equipo de Android admitió esta forma de usar la cámara. Si se espera el flujo anterior, el equipo de Android debería solucionar este problema.

Tengo algunos códigos para tomar fotos que funcionan en Android 2.1 y 2.2. Pero estos códigos se rompieron en Android 2.3. Después de pasar el tiempo para solucionar este problema que fue en vano, me gustaría pedir ayuda aquí.

Mi flujo de código para tomar una foto es así:

crear una clase Camlayer extiende SurfaceView

public class CamLayer extends SurfaceView implements SurfaceHolder.Callback { private void init(Context 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); mCamera = Camera.open(); } public CamLayer(Context context) { super(context); init(context); } public CamLayer(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { Log.i(TAG+".surfaceChanged", "being called!"); Log.i(TAG+".surfaceChanged", "w="+w); Log.i(TAG+".surfaceChanged", "h="+h); if (isPreviewRunning) { mCamera.stopPreview(); } try { mCamera.setPreviewDisplay(holder); mCamera.setPreviewCallback(mPreviewCallback); } catch (IOException e) { Log.e(TAG+".surfaceCreated", "mCamera.setPreviewDisplay(holder);"); } Camera.Parameters p = mCamera.getParameters(); setOptimalSize(p, w, h, SIZEOFPREVIEW); setOptimalSize(p, w, h, SIZEOFPICTURE); mCamera.setParameters(p); mCamera.startPreview(); isPreviewRunning = true; } public void takePicture(){ Log.i(TAG+".takePicture", "being called!"); mCamera.takePicture(null, null, mPictureCallback); Log.i(TAG+".takePicture", "call ended!"); } }

CamLayer.takePicture() será llamado por clases externas para comenzar.

El problema es que en Android 2.3.3, takePicture se bloqueará, por lo que se encuentra un problema de ANR. En /data/anr/traces.txt , a continuación se encuentran. Como puede ver, la native_takePicture nunca regresa.

HILOS DALVIK:

(mutexes: tll=0 tsl=0 tscl=0 ghl=0 hwl=0 hwll=0) "main" prio=5 tid=1 NATIVE | group="main" sCount=1 dsCount=0 obj=0x40022170 self=0xce68 | sysTid=2411 nice=0 sched=0/0 cgrp=default handle=-1345006464 at android.hardware.Camera.native_takePicture(Native Method) at android.hardware.Camera.takePicture(Camera.java:746) at android.hardware.Camera.takePicture(Camera.java:710) at oms.cj.tube.camera.CamLayer.takePicture(CamLayer.java:256) at oms.cj.tube.camera.DefineColor.takePicture(DefineColor.java:61) at oms.cj.tube.camera.DefineColor.onKeyUp(DefineColor.java:71) at android.view.KeyEvent.dispatch(KeyEvent.java:1280) at android.app.Activity.dispatchKeyEvent(Activity.java:2078) at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:16 66) at android.view.ViewRoot.deliverKeyEventToViewHierarchy(ViewRoot.java:2571) at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2546) at android.view.ViewRoot.handleMessage(ViewRoot.java:1878) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:123) at android.app.ActivityThread.main(ActivityThread.java:3691) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:507) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599) at dalvik.system.NativeStart.main(Native Method)

¿Alguien tiene el mismo problema? ¿Y sabes cómo solucionarlo?


Tuve exactamente el mismo problema hoy cuando probamos nuestra aplicación en un Samsung Exhibit 4G con Android 2.3.3 y lo solucionamos usando una solución alternativa.

Ya no llamo a la toma de fotografías, pero utilizo la última devolución de vista previa como la imagen.

El problema es que la devolución de llamada previa envía el búfer de datos utilizando el formato NV21.

Así que debe convertir la imagen usando este proceso: NV21 -> RGB -> Cargar el mapa de bits -> Comprimir a JPEG

Nuestro código ahora se ve así:

camera.setPreviewCallback(new PreviewCallback() { @Override public synchronized void onPreviewFrame(byte[] data, Camera arg1) { if (!mTakePicture) { CameraPreview.this.invalidate(); } else { if (mTakePictureCallback != null && !mPictureTaken) { int rgb[] = new int[previewSize.width*previewSize.height]; decodeYUV420SP(rgb, data, previewSize.width, previewSize.height); Bitmap memoryImage = Bitmap.createBitmap(rgb, previewSize.width, previewSize.height, Bitmap.Config.ARGB_8888); ByteArrayOutputStream baos = new ByteArrayOutputStream(); memoryImage.compress(CompressFormat.JPEG, 100, baos); shutterSound(); setBackgroundDrawable(new BitmapDrawable(getContext().getResources(), memoryImage)); mTakePictureCallback.onPictureTaken(baos.toByteArray(), arg1); } mPictureTaken = true; camera.stopPreview(); } } });

El código de decodeYUV420SP está aquí http://www.41post.com/3470/programming/android-retrieving-the-camera-preview-as-a-pixel-array que lo encontró en Ketai http://code.google. com / p / ketai /

Cuando toma una foto, simplemente configure la variable mTakePicture en true

Estoy trabajando en una mejor versión, pero esto debería ayudarte.


También observé mCamera.takePicture (null, null, handler) para congelar. Intenté borrar el controlador de vista previa: mCamera.setPreviewCallback (null) antes de llamar a takePicture (), y funciona ahora.


No estoy seguro de qué método setOptimalSize utilizó en su código, pero asegúrese de haber configurado el parámetro de la cámara

mCamera.setPictureSize(captureSize.width, captureSize.height); mCamera.setPictureFormat(ImageFormat.JPEG);


Me encontré con este problema con teléfonos GB, y para mí, resultó ser porque estaba llamando a camera.startPreview () justo después de llamar a camera.takePicture (), y esto estaba causando un bloqueo de hilo en Android. La solución consistía en mover camera.startPreview () a la devolución de llamada pasada a camera.takePicture (), de modo que solo recibiera una llamada una vez que los datos de la imagen estaban en (código de ejemplo a continuación). Por supuesto, esto solo es relevante si está interesado en reiniciar la vista previa después de tomar la fotografía.

// BAD BAD DON''T DO THIS! public void myTakePicture(Camera.PictureCallback callback) { mCamera.takePicture(null, null, null, callback); mCamera.startPreview(); } // ... // The way that worked for me public void myTakePicture(final Camera.PictureCallback callback) { mCamera.takePicture(null, null, null, new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] pictureData, Camera camera) { callback.onPictureTaken(pictureData, camera); mCamera.takePicture(); } }); }

Esto no solo hizo que el ANR desapareciera al llamar a takePicture, sino que también arregló un bloqueo nativo en startPreview que estaba sucediendo en algunos teléfonos de gama superior (particularmente a> = 4,3 Nexus 5). ¡Espero eso ayude!