2015-04-21 103 views
0

我在android中使用自定義相機類。我想拍一張照片(只有一張),完成活動並返回這張照片,如果我用位圖或字節陣列來做這件事並不重要。我正在使用Intent來返回圖片。Android:使用自定義相機活動拍照並返回它

我已經測試了2種方法,但是在一種方式中,攝像機在拍攝照片後(無一例外)被阻止,而在另一種方式中,在活動結果中,我無法使用picutre(位圖或字節陣列)我已經在意圖(因爲它是空的)

這裏2類,MainActivity和GGCameraActivity(運行相機並拍攝照片的活動)。

主要活動:

public class MainActivity extends ActionBarActivity{ 

private static final int CAMERA_ACTIVITY_ID = 98; 

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

    Button b1 = (Button)findViewById(R.id.b_empezar); 
    b1.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      startButtonClick(); 
     } 
    }); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.main, menu); 
    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    // Handle action bar item clicks here. The action bar will 
    // automatically handle clicks on the Home/Up button, so long 
    // as you specify a parent activity in AndroidManifest.xml. 
    int id = item.getItemId(); 
    if (id == R.id.action_configuracion) { 
     return true; 
    } 
    return super.onOptionsItemSelected(item); 
} 

@Override 
protected void onActivityResult(int reqCode, int resCode, Intent handler){ 
    switch(reqCode){ 
    case CAMERA_ACTIVITY_ID: 
     if(resCode == RESULT_OK){ 
      //get the byte array 
      byte[] b = handler.getExtras().getByteArray(GGCameraActivity.PARAM_PHOTO); 
      //'b' is null. 
     } 
     break; 
    } 
} 

private void startButtonClick(){ 
    Intent i = new Intent(this, GGCameraActivity.class); 
    startActivityForResult(i, CAMERA_ACTIVITY_ID); 
} 

}

攝像頭活動:

public class GGCameraActivity extends Activity { 

private Activity context; 
private GGCameraPreview preview; 
private Camera camera; 
private ImageView fotoButton; 


public static final String PARAM_PHOTO = "bmp"; 

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

    context = this; 

    fotoButton = (ImageView) findViewById(R.id.photo_button); 
    fotoButton.setOnClickListener(photoButtonClick); 

    preview = new GGCameraPreview(this,(SurfaceView) findViewById(R.id.ggcameraFragment)); 
    FrameLayout frame = (FrameLayout) findViewById(R.id.ggcameraPreview); 
    frame.addView(preview); 

    preview.setKeepScreenOn(true); 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
    if (camera == null) { 
     camera = Camera.open(); 
     camera.startPreview(); 
     camera.setErrorCallback(new ErrorCallback() { 

      @Override 
      public void onError(int error, Camera mcamera) { 
       camera.release(); 
       camera = Camera.open(); 
       Log.d("Camera died", "error camera"); 
      } 

     }); 
    } 
    if (camera != null) { 
     if (Build.VERSION.SDK_INT >= 14) 
      setCameraDisplayOrientation(context, 
        CameraInfo.CAMERA_FACING_BACK, camera); 
     preview.setCamera(camera); 
    } 
} 

@Override 
protected void onPause() { 
    if (camera != null) { 
     camera.stopPreview(); 
     preview.setCamera(null); 
     camera.release(); 
     camera = null; 
    } 
    super.onPause(); 
} 

private void setCameraDisplayOrientation(Activity activity, int cameraId, 
     android.hardware.Camera camera) { 
    android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); 
    android.hardware.Camera.getCameraInfo(cameraId, info); 
    int rotation = activity.getWindowManager().getDefaultDisplay() 
      .getRotation(); 
    int degrees = 0; 
    switch (rotation) { 
    case Surface.ROTATION_0: 
     degrees = 0; 
     break; 
    case Surface.ROTATION_90: 
     degrees = 90; 
     break; 
    case Surface.ROTATION_180: 
     degrees = 180; 
     break; 
    case Surface.ROTATION_270: 
     degrees = 270; 
     break; 
    } 

    int result; 
    if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 
     result = (info.orientation + degrees) % 360; 
     result = (360 - result) % 360; // compensate the mirror 
    } else { // back-facing 
     result = (info.orientation - degrees + 360) % 360; 
    } 
    camera.setDisplayOrientation(result); 
} 

private OnClickListener photoButtonClick = new OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     fotoButton.setClickable(false); 
     camera.autoFocus(mAutoFocusCallback); 
    } 
}; 

Camera.AutoFocusCallback mAutoFocusCallback = new Camera.AutoFocusCallback() { 
    @Override 
    public void onAutoFocus(boolean success, Camera camera) { 
     camera.takePicture(null, null, jpegCallback); 
    } 
}; 

private PictureCallback jpegCallback = new PictureCallback() { 
    @Override 
    public void onPictureTaken(byte[] data, Camera camera) { 
     Intent resultIntent = new Intent(); 
     resultIntent.putExtra(PARAM_PHOTO, data); 
     context.setResult(RESULT_OK, resultIntent); 
     context.finish(); 
    } 
}; 

}

注:

我沒有錯誤異常(我的意思是,應用程序不會停止引發異常),但我已經多次調試類,並且始終認爲引發了異常,但在「Camera.class」(由Camera.class提供的某個位置(但不是由我)機器人)。我認爲這是因爲我總是輸入一個代碼片段(在Camera.class中),這會引發異常。下面這個代碼片段:

if (msgType!= CAMERA_MSG_PREVIEW_FRAME && 
    msgType != CAMERA_MSG_RAW_IMAGE){ 
    throw new IllegalArgumentException("Unsopported message type: "+ msgType); 
} 

此代碼段是在Camera.class,我總是進入它,但如果我不調試應用程序,只要運行它(不考慮從MainActivity所拍攝的照片)的所有作品那麼,該應用程序不會崩潰。

編輯1: 我需要一個自定義的相機活動,Intent(MediaStore.ACTION_IMAGE_CAPTURE);是不是我需要的東西。

編輯2:我測試過返回一個簡單的整數。我有同樣的錯誤,照相機在按下拍照按鈕後會阻止,並且永遠不會返回到主要活動。 Debuggin我可以再次看到上面提到的IllegalArgumentException(),但是應用程序不會崩潰。 這裏的代碼(僅改變在回調和onActivityResult爲TKE整數代替字節[]):

takePicture的回調:

private PictureCallback jpegCallback = new PictureCallback() { 
    @Override 
    public void onPictureTaken(byte[] data, Camera camera) { 
     Intent resultIntent = new Intent(); 
     resultIntent.putExtra("int", 5); 
     setResult(RESULT_OK, resultIntent); 
     finish(); 
    } 
}; 

onActivityResult在MainActivity

[...] 

case CAMERA_ACTIVITY_ID: 
    if(resCode == RESULT_OK){ 
     int n = handler.getExtras().getInt("int"); 
    } 
    break; 

[...] 

EDIT 3:雖然調試,我已經步入完成方法。我發現這個異常提出了:

throw new UnsupportedOperationException(
      "startNextMatchingActivity can only be called from a top-level activity"); 

但是,應用程序不會崩潰。

回答

1

我發現了這個問題。我已經讀過Intent對於處理大型物體不太好。我已經測試過只能放置20個組件的字節[],並且沒有問題。但是,隨着圖像字節[](400k大小或多或少)應用程序保持阻塞。我已經快速閱讀了這些內容,我不確定它是否正確100%。

我也讀過,爲了在活動之間分享大對象,最好的想法是使用靜態變量(或Parcelables也許?)。

然後當我拍照時,我把它放在課堂上用靜態變化,我從其他活動中拿走它。

我想我在調試器中看到的異常(但沒有拋出)是由於在Intent中放置了一個太大的數組並且返回結果(setResult()),但我不確定在所有。

相關問題