Takepicture зависает на Android 2.3.3

У меня есть некоторые коды для съемки, которые работают в Android 2.1 и 2.2. Но эти коды сломались на Android 2.3. Проведя время, чтобы исправить эту проблему, которая прошла напрасно, я хотел бы попросить о помощи здесь.

Мой поток кода для съемки выглядит следующим образом:

Создать класс 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 будет зависать, поэтому проблема ANR найдена. В /data/anr/traces.txt ниже. Как вы можете видеть, native_takePicture никогда не возвращается.

DALVIK THREADS:

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

Есть ли у кого-то такая же проблема? И знаете, как это исправить?

Solutions Collecting From Web of "Takepicture зависает на Android 2.3.3"

Я также заметил, что mCamera.takePicture (null, null, обработчик) замерзает. Я попытался очистить обработчик предварительного просмотра: mCamera.setPreviewCallback (null) перед вызовом takePicture (), и теперь он работает.

У меня была такая же проблема сегодня, когда мы тестировали наше приложение на Samsung Exhibit 4G с Android 2.3.3 и решили его с помощью обходного пути.

Я больше не называю takepicture , но использую последний обратный вызов предварительного просмотра в качестве изображения.

Проблема в том, что обратный вызов предварительного просмотра отправляет буфер данных с использованием формата 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. ком / р / Ketai /

Когда вы делаете снимок, просто установите для переменной mTakePicture значение 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 команды этот способ использования камеры. Если ожидаемый поток ожидается, команда Android должна исправить эту проблему.

Я столкнулся с этой проблемой с телефонами GB, и для меня это оказалось потому, что я вызывал camera.startPreview () сразу после вызова camera.takePicture (), и это вызывало некоторую блокировку потока в Android. Исправление заключалось в том, чтобы переместить camera.startPreview () в обратный вызов, переданный в camera.takePicture (), так что он получил вызов только после того, как были представлены данные изображения (пример кода ниже). Это, конечно, актуально только в том случае, если вы заинтересованы в перезапуске предварительного просмотра после того, как снимок сделан.

 // 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, но и зафиксировало родной сбой на startPreview, который происходил на некоторых более поздних телефонах (в частности,> = 4.3 Nexus 5). Надеюсь, поможет!