在Android 2.3.3上的图片挂起

我有一些在Android 2.1和2.2下工作的图片代码。 但是这些代码在Android 2.3上打破了。 花了时间解决这个白白化的问题后,我想在这里寻求帮助。

我的代码stream图像是这样的:

创build一个类Camlayer扩展了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()将被外部类调用来启动。

问题是,在Android 2.3.3, takePicture将挂起,所以find一个ANR问题。 在/data/anr/traces.txt ,find下面的内容。 正如你所看到的, native_takePicture永远不会返回。

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) 

有没有人有同样的问题? 并知道如何解决它?

  • 使用Android相机进行image processing
  • Android 4.0.3。 USB主机 - 与相机通信
  • 发布Android相机无需重新启动?
  • 获取相机的当前图片文件夹
  • Android相机takePicture函数不调用callback函数
  • 将相机中的图像存储到私人应用程序caching目录
  • 如何捕捉图像并将其与原生Android Camera一起存储
  • Android:takePicture()不发声
  • 我也观察到mCamera.takePicture(null,null,handler)冻结。 我试图清除预览处理程序:mCamera.setPreviewCallback(null)在调用takePicture()之前,它现在工作。

    我今天在使用Android 2.3.3在Samsung Exhibit 4G上testing我们的应用程序时遇到了完全相同的问题,并使用解决方法解决了这个问题。

    我不再打电话给takepicture ,而是使用最后一个预览callback作为图片。

    问题是预览callback使用NV21格式发送数据缓冲区。

    所以你必须使用这个过程来转换图像:NV21 – > RGB – >加载位图 – >压缩到JPEG

    我们的代码现在看起来像这样:

      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(); } } }); 

    decodeYUV420SP的代码在这里http://www.41post.com/3470/programming/android-retrieving-the-camera-preview-as-a-pixel-array谁发现它在Ketai http://code.google。 COM / p /科泰/

    拍摄照片时,只需将mTakePicturevariables设置为true即可

    我正在做一个更好的版本,但这应该让你去。

    我不确定代码中使用了setOptimalSize方法,但确保已设置相机参数

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

    问题在于下面的代码是写的。

    1. 有一个PreviewCallback定义,

       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()

    这在2.1 / 2.2,但不在2.3。

    不知道Android团队是否支持这种使用相机的方式。 如果上面的stream程是预期的,那么Android团队应该解决这个问题。

    我遇到了这个问题与GB手机,对我来说,原来是因为我调用camera.takePicture()后调用camera.startPreview(),这是在Android中导致一些线程locking。 解决方法是将camera.startPreview() 移入传入camera.takePicture()的callback函数中,以便只有在图片数据处于启用状态时才会调用camera.startPreview()(示例代码如下)。 这当然只有在拍摄照片后重新开始预览时才有意义。

     // 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(); } }); } 

    这不仅使ANR在调用takePicture的时候消失,而且还修复了一些高端手机(特别是> = 4.3 Nexus 5)上的startPreview本地崩溃问题。 希望能帮助到你!