android - 相机在摩托罗拉 Razr 上崩溃 - 内存不足

标签 android android-camera out-of-memory motorola-droid

我的应用程序要求我拍照,而我运行时遇到问题的唯一设备是摩托罗拉 Razr。我已经在 Nexus One、Droid X、Droid 2、Sensation 和其他一些设备上尝试过。这是我正在使用的代码:

public class CameraView extends Activity {
    private static final String TAG = "CameraView";

  private SurfaceView preview=null;
  private SurfaceHolder previewHolder=null;
  public Camera camera=null;
  private boolean inPreview=false;
  private ImageView takePicture;

  private Uri uriTarget;


  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.cameraview);

    takePicture = (ImageView)findViewById(R.id.take_picture);

    preview=(SurfaceView)findViewById(R.id.preview);
    previewHolder=preview.getHolder();
    previewHolder.addCallback(surfaceCallback);
    previewHolder
        .setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);


    if (savedInstanceState != null)
    {
        uriTarget = savedInstanceState.getParcelable("uriTarget");
    }

    preview.setOnClickListener(new OnClickListener(){

        @Override
        public void onClick(View arg0) {
            takePicture.setEnabled(false);
            camera.autoFocus(myAutoFocusCallback);

        }

    });


    takePicture.setOnClickListener(new OnClickListener(){

        @Override
        public void onClick(View arg0) {

            //camera.takePicture(null, null, photoCallback);
            camera.takePicture(myShutterCallback, 
                    myPictureCallback_RAW, myPictureCallback_JPG);
            inPreview=false;    
        }

    });


  }

  @Override
  public void onResume() {
    super.onResume();
    try{
        if (camera==null) {
          camera=Camera.open();
          camera.setDisplayOrientation(90);
          Camera.Parameters params = camera.getParameters(); 
          params.set("rotation", 90); 
          params.setJpegQuality(60);
          //params.setPictureSize(32, 32);
          camera.setParameters(params);

        }
    }catch (Exception e){
        finish();
    }
  }

  @Override
  public void onPause() {
    if (inPreview) {
      camera.stopPreview();
    }
    if(camera != null)
        camera.release();
    camera=null;
    inPreview=false;

    super.onPause();
  }

  SurfaceHolder.Callback surfaceCallback=new SurfaceHolder.Callback() {
    public void surfaceCreated(SurfaceHolder holder) {
      try {
        camera.setPreviewDisplay(previewHolder);
      }
      catch (Throwable t) {
        Log.e("PictureDemo-surfaceCallback",
            "Exception in setPreviewDisplay()", t);
        Toast.makeText(CameraView.this, t.getMessage(),
            Toast.LENGTH_LONG).show();
      }
    }

    public void surfaceChanged(SurfaceHolder holder,
        int format, int width, int height) {
        Camera.Parameters parameters=camera.getParameters();
        parameters.setPictureFormat(PixelFormat.JPEG);
        parameters.setJpegQuality(60);
        parameters.set("rotation", 90);
        camera.setParameters(parameters);
        camera.startPreview();

        inPreview=true;
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
      // no-op
    }
  };


  ShutterCallback myShutterCallback = new ShutterCallback(){

        @Override
        public void onShutter() {

        }};


  PictureCallback myPictureCallback_RAW = new PictureCallback(){

        @Override
        public void onPictureTaken(byte[] arg0, Camera arg1) {

        }};

    PictureCallback myPictureCallback_JPG = new PictureCallback(){

        @Override
        public void onPictureTaken(byte[] data, Camera camera1) {


            Constants.car_image = BitmapFactory.decodeByteArray(data, 0, data.length);  
            Constants.showImage = true;

            FileOutputStream outStream = null;
            try {


                File esd = Environment.getExternalStorageDirectory();


                File newDirectory = new File(esd.getAbsolutePath() + "/DCIM/statefair/");
                if(!newDirectory.exists())
                    newDirectory.mkdirs();
                outStream = new FileOutputStream(esd.getAbsolutePath() + String.format(
                        "/DCIM/statefair/%d.jpg", System.currentTimeMillis()));

                outStream.write(data);
                outStream.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();

            } catch (IOException e) {
                e.printStackTrace();

                  System.out.println("IO exception");
            } finally {
                  System.out.println("Finally");
                  camera.release();
            }

            finish();

        }
        };
        AutoFocusCallback myAutoFocusCallback = new AutoFocusCallback(){

           @Override
           public void onAutoFocus(boolean arg0, Camera arg1) {
            // TODO Auto-generated method stub
            takePicture.setEnabled(true);
            }
         };
       protected void onSaveInstanceState(Bundle outState)
        {
            outState.putParcelable("uriTarget", uriTarget);
        }
}

我在这一行遇到内存不足错误:

Constants.car_image = BitmapFactory.decodeByteArray(data, 0, data.length);

即使我将 JPEG 质量设置为 10。还有其他人遇到过这个问题吗?

最佳答案

检查这个BitmapFactory.Options

全尺寸图像占用大量内存,您应该重新调整尺寸。只是为了快速测试,试试这个:

Options opts = new Options();
opts.inSampleSize = 4;        
Constants.car_image = BitmapFactory.decodeByteArray(data, 0, data.length, opts);

关于android - 相机在摩托罗拉 Razr 上崩溃 - 内存不足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11887260/

相关文章:

c# - 打开大型 C# 文件时,Visual Studio 内存不足

c++ - ADsOpenObject() 返回 -2147024882 (0x8007000E) -> OUT_OF_MEMORY

android - 在 OpenGL ES 2.0 中写入深度缓冲区/深度值的解决方法

android - 使用手机屏幕尺寸的合适方法是什么?

Android:Camera Crop intent Lollipop 及以上给出 toast 消息,因为此图像不支持编辑

android - Android中显示定制视频的高效路径

java - 调用 onClick 时为 "OutOfMemoryError"(崩溃报告)

android - 合并 spannable 对象时出错

android - 以编程方式修改 Android 主题

android - 使用我的 Android 应用程序将文本标签发送到 Instagram