2012-02-02 34 views
11

Khi cuộc gọi được thực hiện với Camera.takePicture(), bản xem trước của tôi sẽ ngừng cập nhật như được mô tả trong tài liệu. Cách tốt nhất để phát hiện ra rằng quá trình chụp ảnh đã hoàn thành và gọi startPreview() để làm cho nó bắt đầu cập nhật lại là gì?Cách tốt nhất để gọi StartPreview() sau khi chụp ảnh là gì?

Cuộc gọi không thể được đặt trong bất kỳ cuộc gọi lại nào được chuyển đến takePicture, theo các tài liệu, vì tất cả chúng đều phải trả lại trước khi tôi gọi nó.

Dự đoán tốt nhất hiện tại của tôi là tạo Trình xử lý và gửi Runnable bị trì hoãn đến nó từ cuộc gọi lại JPEG (hoặc bất kỳ lần gọi lại được xác định cuối cùng nào để trả về).

Trả lời

6

Bạn nên khởi động mCamera.takePicture từ bên trong AsyncTask (hoặc chuỗi) tuy nhiên AsyncTaks là tùy chọn dễ dàng hơn.

Một thực hiện thực sự đơn giản (trong đó tất nhiên có thể được sửa đổi) là:

Phương pháp kêu gọi để chụp ảnh

/** 
* Execute the AsyncTask that will handle the preview of the captured photo. 
*/ 
public void takePicture() { 
    TakePictureTask takePictureTask = new TakePictureTask(); 
    takePictureTask.execute(); 
} 

Các AsyncTask lớp con

/** 
* A pretty basic example of an AsyncTask that takes the photo and 
* then sleeps for a defined period of time before finishing. Upon 
* finishing, it will restart the preview - Camera.startPreview(). 
*/ 

private class TakePictureTask extends AsyncTask<Void, Void, Void> { 

    @Override 
    protected void onPostExecute(Void result) { 
     // This returns the preview back to the live camera feed 
     mCamera.startPreview(); 
    } 

    @Override 
    protected Void doInBackground(Void... params) { 
     mCamera.takePicture(null, null, mPictureCallback); 

     // Sleep for however long, you could store this in a variable and 
     // have it updated by a menu item which the user selects. 
     try { 
      Thread.sleep(3000); // 3 second preview 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     return null; 
    } 

} 

Trường PictureCallback

private PictureCallback mPictureCallback = new PictureCallback() { 

    @Override 
    public void onPictureTaken(byte[] data, Camera camera) { 
     File file = null; 

     // Check whether the media is mounted with read/write permission. 
     if (Environment.MEDIA_MOUNTED.equals(
       Environment.getExternalStorageState())) { 
      file = getOutputMediaFile(); 
     } 

     if (file == null) { 
      Log.d(TAG, "Error creating media file, check storage persmissions!"); 
      return; 
     } 

     try { 
      FileOutputStream fileOutputStream = new FileOutputStream(file); 
      fileOutputStream.write(data); 
      fileOutputStream.close(); 
     } catch (FileNotFoundException e) { 
      Log.d(TAG, "File not found: " + e.getMessage()); 
     } catch (IOException e) { 
      Log.d(TAG, "Error accessing file: " + e.getMessage()); 
     } 
    } 
}; 
+0

Vì vậy, những gì họ đang làm trong hướng dẫn này chỉ là sai? http://developer.android.com/training/camera/cameradirect.html Tôi thực sự không hiểu làm thế nào để họ khởi động lại bản xem trước ở đó, nhưng có vẻ như không có gì như AsyncTask hay bất cứ điều gì ... – Headcrab

12

Vì PictureCallback được bắt đầu trong một chuỗi riêng biệt (nó sẽ không khóa giao diện người dùng), bạn không cần sử dụng AsyncTask để gọi chụp.

Có hai cách để làm những gì bạn muốn làm, dễ nhất là như sau:

mCamera.startPreview(); //preview has to be started before you can take a picture 
mCamera.takePicture(null, null, mPictureCallback); //take a picture 

private PictureCallback mPictureCallback = new PictureCallback() { 
    @Override 
    public void onPictureTaken(byte[] data, Camera camera) { 
     camera.startPreview(); //once your camera has successfully finished 
           //its capture it's safe to restart the preview 
     ... //anything else you want to do to process that image 
    } 
} 

Thứ hai sẽ sử dụng một chức năng ẩn danh, ví dụ:

mCamera.takePicture(null, null, new PictureCallback(){ 
    ... 
}); 

Cả có sử dụng của họ, tùy thuộc vào nhu cầu của bạn.

+0

Để 'PictureCallback' hoạt động trên chủ đề nền, máy ảnh sẽ được mở trong chuỗi sự kiện riêng biệt, xem [ví dụ mã] (http://stackoverflow.com/a/19154438/192373). –

+0

@Alex Sự hiểu biết của tôi là PictureCallback() và PreviewCallback() (mà bạn đã tham chiếu trong bài đăng của mình) hoạt động khác nhau. Nếu bạn muốn thực hiện bất kỳ công việc nào trên ảnh kết quả từ PictureCallback(), hãy sử dụng một chuỗi cho điều đó. Vui lòng cho tôi biết nếu tôi không chính xác trong sự hiểu biết của tôi. – wblaschko

+0

Thật dễ dàng để kiểm tra, nhưng tôi không biết câu trả lời tắt tay –

Các vấn đề liên quan