2015-10-16 133 views
0

我必须创建一个android应用程序,捕获背景图片。我有代码,但它始终崩溃在一个点上。此代码在HTC android手机上运行良好。我在摩托罗拉,联系和它总是崩溃尝试它。需要帮助修复“java.lang.RuntimeException:takePicture失败”

这是崩溃:

Process: com.capturepicture, PID: 13016 
    java.lang.RuntimeException: takePicture failed 
      at android.hardware.Camera.native_takePicture(Native Method) 
      at android.hardware.Camera.takePicture(Camera.java:1436) 
      at android.hardware.Camera.takePicture(Camera.java:1381) 
      at com.trimble.applanix.flightplanning.FlightPlanner.takepic(FlightPlanner.java:142) 
      at com.trimble.applanix.flightplanning.FlightPlanner$2.onClick(FlightPlanner.java:96) 
      at android.view.View.performClick(View.java:4761) 
      at android.view.View$PerformClick.run(View.java:19767) 
      at android.os.Handler.handleCallback(Handler.java:739) 
      at android.os.Handler.dispatchMessage(Handler.java:95) 
      at android.os.Looper.loop(Looper.java:135) 
      at android.app.ActivityThread.main(ActivityThread.java:5312) 
      at java.lang.reflect.Method.invoke(Native Method) 
      at java.lang.reflect.Method.invoke(Method.java:372) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696) 

这是已触发相机的代码清单文件

public class Planner extends Activity { 

    private Button btnStart; 
    private Button btnStop; 
    protected static Handler mHandler = null; 
    protected String mHttpResponse = ""; 
    private int mHandlerWhatMessage; 
    Camera camera; 
    SurfaceView preview; 
    SurfaceHolder previewHolder; 
    ImageButton takePic; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_flight_planner); 

     btnStart = (Button) findViewById(R.id.btn_start); 
     btnStop = (Button) findViewById(R.id.btn_stop); 
     preview = (SurfaceView) findViewById(R.id.surfaceView); 
     previewHolder = preview.getHolder(); 
     previewHolder.addCallback(surfaceCallback); 
     previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 


     btnStart.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

       takepic(); 



      } 
     }); 

     btnStop.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 


      } 
     }); 

    } 


    public void takepic(){ 
     if (camera == null) 
      camera = Camera.open(); 
     camera.cancelAutoFocus(); 
     camera.startPreview(); 

     System.gc(); 
     camera.setPreviewCallback(null); 
     camera.takePicture(null, null, photoCallback); 
     camera.startPreview(); 
     //camera.takePicture(ShutterCallback, rawCallback, photoCallback); 
    } 
    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); 
    } 

    SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() { 

     @Override 
     public void surfaceCreated(SurfaceHolder holder) { 
      camera = Camera.open(); 

      try { 
       camera.setPreviewDisplay(previewHolder); 
      } catch (Throwable t) { 
       Toast toast = Toast.makeText(FlightPlanner.this, 
         "Exception in setPreviewDisplay", Toast.LENGTH_LONG); 
       toast.show(); 
      } 
     } 

     @Override 
     public void surfaceChanged(SurfaceHolder holder, int format, int width, 
            int height) { 
      Camera.Parameters parameters = camera.getParameters(); 

      Camera.Size bestSize = getBestPreviewSize(width, height, parameters); 
      parameters.setPreviewSize(bestSize.width, bestSize.height); 

      parameters.setPictureFormat(PixelFormat.JPEG); 
      camera.setParameters(parameters); 
      camera.startPreview(); 
     } 

     @Override 
     public void surfaceDestroyed(SurfaceHolder holder) { 
      camera.stopPreview(); 
      camera.release(); 
      camera = null; 
     } 

    }; 

     /* 
     Camera.ShutterCallback ShutterCallback = new Camera.ShutterCallback() { 
      public void onShutter() { 
      } 
     }; 

     PictureCallback rawCallback = new PictureCallback() { 
      public void onPictureTaken(byte[] data, Camera camera) { 
      } 
     }; 
     */ 

    Camera.PictureCallback photoCallback = new Camera.PictureCallback() { 
     public void onPictureTaken(byte[] data, Camera camera) { 
      // Save the image JPEG data to the SD card 
      FileOutputStream outStream = null; 
      try { 

       SimpleDateFormat formatter = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss"); 
       Date now = new Date(); 
       String fileName = formatter.format(now) +".jpg"; 
       //String currentDateTimeString = DateFormat.getDateTimeInstance().format(new Date()); 
       String root = Environment.getExternalStorageDirectory().toString(); 
       File myDir = new File(root + "/FLIGHTPLANNER"); 
       myDir.mkdirs(); 
       File file = new File (myDir, fileName); 
       if (file.exists()) file.delete(); 

       outStream = new FileOutputStream(file); 
       outStream.write(data); 
       outStream.close(); 
      } catch (FileNotFoundException e) { 
       Log.d("CAMERA", e.getMessage()); 
      } catch (IOException e) { 
       Log.d("CAMERA", e.getMessage()); 
      } 
      camera.startPreview(); 
       /*new SavePhotoTask().execute(data); 
       camera.startPreview();*/ 
     } 
    }; 
} 

我已经添加了所需摄像机的权限我的活动文件。

回答

1

您必须先调用startPreview(),然后才可以调用takePicture()。但在调用startPreview()之后立即调用takePicture()是不正确的。它可能适用于某些设备,但不适用于其他设备。

一旦相机打开(当SurfaceView由布局管理器创建时),最好的解决方案就会开始预览。

但如果是不适合你接受,

preview.postDelayed(…, 300) 

将是足够的(见有类似的例子on GitHub