Android-Kamera-Vorschau in einem fragment

Bis jetzt habe ich einen voll funktionierenden code, dass Stecker in eine Kamera zu sehen, die Vorschau der Kamera auf der Vorderseite.

Was ich versuche zu tun, ist zu bekommen, dass die Kamera arbeiten in einem Fragment.

Vollständige code:

MainActivity.java

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.fragment_main);

    getFragmentManager().beginTransaction().add(R.id.mainLayout, new CameraExtractionFragment()).commit();
}
}

CameraExtractionFragment.java

public class CameraExtractionFragment extends Fragment {

private CameraExtraction mCameraExtraction;
Camera mCamera;
int mNumberOfCameras;
int cameraId;
int rotation;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mCameraExtraction = new CameraExtraction(
            this.getActivity().getBaseContext(), 
            this.getActivity().getWindowManager().getDefaultDisplay().getRotation()
            );

    //Find the total number of cameras available
    mNumberOfCameras = Camera.getNumberOfCameras();

    //Find the ID of the rear-facing ("default") camera
    CameraInfo cameraInfo = new CameraInfo();
    for (int i = 0; i < mNumberOfCameras; i++) {
        Camera.getCameraInfo(i, cameraInfo);
        if (cameraInfo.facing == CameraInfo.CAMERA_FACING_FRONT) {
            cameraId = i;
        }
    }
}

 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)               {
     return mCameraExtraction;
 }

 @Override
public void onResume() {
    super.onResume();

    //Use mCurrentCamera to select the camera desired to safely restore
    //the fragment after the camera has been changed
    mCamera = Camera.open(cameraId);
    mCameraExtraction.setCamera(mCamera);
}

@Override
public void onPause() {
    super.onPause();

    if (mCamera != null)
    {
        mCamera.release();
    }
}


//Modo en el que se pinta la cámara: encajada por dentro o saliendo los bordes por fuera.
public enum CameraViewMode {

    /**
     * Inner mode
     */
    Inner,
    /**
     * Outer mode 
     */
    Outer
}
}

CameraExtraction.java

public class CameraExtraction extends ViewGroup implements SurfaceHolder.Callback {

 private final String TAG = "CameraExtraction";

Camera mCamera;
SurfaceHolder mHolder;
SurfaceView mSurfaceView;
int mNumberOfCameras;
int cameraId;
Rect desiredSize;
CameraViewMode cameraViewMode;
boolean mSurfaceCreated = false;
List<Size> mSupportedPreviewSizes;
int rotation;
Size mPreviewSize;

public CameraExtraction(Context context, int rotation) {
    super(context);

    this.rotation = rotation;

    mSurfaceView = new SurfaceView(context);

    addView(mSurfaceView);

    //Install a SurfaceHolder.Callback so we get notified when the
    mHolder = mSurfaceView.getHolder();
    mHolder.addCallback(this);
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    cameraViewMode = CameraViewMode.Inner;
}

public void setCamera(Camera camera) {
    mCamera = camera;
    if (mCamera != null) {
        mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
        if (mSurfaceCreated) requestLayout();
    }
}

public void switchCamera(Camera camera) {
    setCamera(camera);
    try {
        camera.setPreviewDisplay(mHolder);
    } catch (IOException exception) {
        Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
    }
}

@SuppressLint("DrawAllocation")
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    if (mSurfaceView == null ||mSurfaceView.getHolder() == null) return;

    if (mSurfaceView.getHolder().getSurface() == null) {
        //preview surface does not exist
        return;
    }

    final int width = resolveSize(getSuggestedMinimumWidth(),
            widthMeasureSpec);
    final int height = resolveSize(getSuggestedMinimumHeight(),
            heightMeasureSpec);
    setMeasuredDimension(width, height);

    if (mSupportedPreviewSizes != null) {

        mPreviewSize = getNearestPreviewSize(mCamera.new Size(widthMeasureSpec,heightMeasureSpec));
    }

    if (mCamera != null) {
      Camera.Parameters parameters = mCamera.getParameters();
      parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);

      mCamera.setParameters(parameters);
    }
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    if (getChildCount() > 0) {
        final View child = getChildAt(0);

        final int width = r - l;
        final int height = b - t;

        int previewWidth = width;
        int previewHeight = height;
        if (mPreviewSize != null) {
            previewWidth = mPreviewSize.width;
            previewHeight = mPreviewSize.height;
        }

        //Center the child SurfaceView within the parent.
        if (width * previewHeight > height * previewWidth) {
            final int scaledChildWidth = previewWidth * height
                    / previewHeight;
            child.layout((width - scaledChildWidth) / 2, 0,
                    (width + scaledChildWidth) / 2, height);
        } else {
            final int scaledChildHeight = previewHeight * width
                    / previewWidth;
            child.layout(0, (height - scaledChildHeight) / 2, width,
                    (height + scaledChildHeight) / 2);
        }
    }       
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    mCamera = Camera.open(cameraId);        
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
    if (mSurfaceView == null || mSurfaceView.getHolder() == null) return;

            if (mSurfaceView.getHolder().getSurface() == null) {
                //preview surface does not exist
                return;
            }

            //set preview size and make any resize, rotate or
            //reformatting changes here
            Camera.Parameters param = mCamera.getParameters();
            Point previewSize = new Point(640,480);

            Camera.Size size = getNearestPreviewSize(mCamera.new Size(previewSize.x,previewSize.y));
            param.setPreviewSize(size.width, size.height);
            mCamera.setParameters(param);
            rotation = setCameraDisplayOrientation(cameraId, mCamera);

            //start preview with new settings
            try {
                mCamera.setPreviewCallback(new Camera.PreviewCallback() {

                    @Override
                    public void onPreviewFrame(byte[] data, Camera camera) {
                        //TODO Auto-generated method stub

                    }
                });
                mCamera.setPreviewDisplay(mSurfaceView.getHolder());
                mCamera.startPreview();

            } catch (Exception e) {
                Log.d("AndroidControlSurfaceView",
                        "Error starting camera preview: " + e.getMessage());
            }       
}

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


protected Rect getCameraViewSizeCompensated(Camera.Size cameraPreviewSize, Point hostViewSize) {
    Rect toReturn=null;

    float ratioWidth = hostViewSize.x / (float)cameraPreviewSize.width;
    float ratioHeight = hostViewSize.y / (float)cameraPreviewSize.height;

    switch (cameraViewMode){
    case Inner:
        if (ratioWidth < ratioHeight) {
            int newHeight = (int)(cameraPreviewSize.height*ratioWidth);
            int y = (hostViewSize.y - newHeight) / 2;
            toReturn = new Rect(0, y, hostViewSize.x, y+newHeight);
        } else {
            int newWidth = (int)(cameraPreviewSize.width*ratioHeight);
            int x = (hostViewSize.x - newWidth) / 2;
            toReturn = new Rect(x, 0, x+newWidth,hostViewSize.y);
        }
        break;
    case Outer:
        if (ratioWidth < ratioHeight) {
            int newWidth = (int)(cameraPreviewSize.width*ratioHeight);
            int x = (hostViewSize.x - newWidth) / 2;
            toReturn = new Rect(x, 0, x+newWidth,hostViewSize.y);
        } else {
            int newHeight = (int)(cameraPreviewSize.height*ratioWidth);
            int y = (hostViewSize.y - newHeight) / 2;
            toReturn = new Rect(0, y, hostViewSize.x, y+newHeight);
        }
        break;
    }
    return toReturn;
}

private Camera.Size getNearestPreviewSize(Camera.Size size) {
  List<Camera.Size> availableSizes =  mCamera.getParameters().getSupportedPreviewSizes();
  if (availableSizes == null || availableSizes.size() <= 0) return null;

  Camera.Size toReturn = availableSizes.get(0);
  int distance = Math.abs(size.width*size.height - toReturn.width*toReturn.height);
  for (int a=1; a<availableSizes.size(); a++) {
      int temp = Math.abs(size.width*size.height - availableSizes.get(a).width*availableSizes.get(a).height);
      if (temp < distance) {
          distance = temp;
          toReturn = availableSizes.get(a);
      }
  }
  return toReturn;
 }


public int setCameraDisplayOrientation(int cameraId, android.hardware.Camera camera) {

     CameraInfo info = new Camera.CameraInfo();
     Camera.getCameraInfo(cameraId, info);
     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);
     return result/90;
 }

}

Aber wenn Sie die Anwendung ausführen, kein Bild wird gezeigt in meiner device. Nur einen weißen Bildschirm. Beachten Sie, dass, wie ich bereits erwähnt , dass die Kamera in einer Tätigkeit, die nicht mit Fragmenten.

So, , warum die Haupt-Aktivität ist dargestellt mit einem weißen Bildschirm?

PS: Hier können Sie download mein code und testen Sie es.

Können Sie bitte poste dein code hier? Ihr link ist tot und funktioniert nicht.

InformationsquelleAutor Sonhja | 2014-09-01

Schreibe einen Kommentar