2017-06-17 48 views
-3

所以我有一個對話,我想要順序顯示正面和背面攝像機預覽,比如延遲2秒後說。問題是,我總是可以設置1個攝像頭視圖到框架,如何自動更改它,自動?無法切換正面和背面攝像機

這裏就是我想改變它的飛行:

public class CameraExample extends AnimatedViewContainer { 

    private final static String TAG = "CameraExample"; 

    private Camera mCamera; 
    private CameraPreview mPreview; 
    private Context mContext; 

    public CameraExample(Context context, int i) { 
     super(context, i); 

     mPreview = null; 
     mContext = context; 

     initCamera(mContext); 

    } 

    // A safe way to get an instance of the Camera object. 
    public static Camera getCameraInstance(int cameraId) { 
     Camera c = null; 
     try { 
      // attempt to get a Camera instance 
      c = Camera.open(cameraId); 
     } catch (Exception e) { 
      // Camera is not available (in use or does not exist) 
      Log.e(TAG, "CameraExample: " + "camera not available (in use or does not exist); " + e.getMessage()); 
     } 
     return c; // returns null if camera is unavailable 
    } 

    private void initCamera(Context context) { 

     // Check if this device has a camera 
     if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) { 
      // no camera on this device 
      Log.e(TAG, "CameraExample: " + "this device has no camera"); 
     } else { 
      // this device has a camera 
      int numCameras = Camera.getNumberOfCameras(); 
      if (numCameras >= 0) { 
       for (int cameraId = 0; cameraId < numCameras; cameraId++) { 
        mCamera = getCameraInstance(cameraId); 
        if (mCamera != null) { 
         CameraInfo cameraInfo = new CameraInfo(); 
         Camera.getCameraInfo(cameraId, cameraInfo); 
         if (cameraInfo.facing == CameraInfo.CAMERA_FACING_FRONT) { 
          try { 
           //Create our Preview view and set it as the content of this LinearLayout View 
           mPreview = new CameraPreview(context, mCamera, cameraId); 
          } catch (RuntimeException e) { 
           Log.e(TAG, "Camera failed to open: " + e.getLocalizedMessage()); 
          } 
         } 
         if (createView() == false) { 
          break; 
         } 
        } 
       } 
      } 
     } 
    } 

    @Override 
    public void onCreateViewContent(LayoutInflater layoutInflater, ViewGroup parentGroup, View[] containerViews, int index) { 
     containerViews[index] = layoutInflater.inflate(R.layout.example_camera, parentGroup, false); 
     FrameLayout previewFrame = (FrameLayout) containerViews[index].findViewById(R.id.preview); 

     // Add preview for inflation 
     previewFrame.addView(mPreview); 

    } 

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

CameraPreview類:

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { 

     private static final String TAG = "CameraPreview"; 

     private Context mContext; 
     private SurfaceHolder mHolder; 
     private Camera mCamera; 
     private int mCameraId; 

    public CameraPreview(Context context, Camera camera, int cameraId) { 
     super(context); 
     mContext = context; 
     mCamera = camera; 
     mCameraId = cameraId; 

     // Install a SurfaceHolder.Callback so we get notified when the 
     // underlying surface is created and destroyed. 
     mHolder = getHolder(); 
     mHolder.addCallback(this); 
    } 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
     // The Surface has been created, now tell the camera where to draw the preview. 
     try { 
      mCamera.setPreviewDisplay(holder); 
      mCamera.startPreview(); 
     } catch (IOException e) { 
      Log.e(TAG, "CameraExample: " + "Error setting camera preview: " + e.getMessage()); 
     } 
    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
     // empty. Take care of releasing the Camera preview in your activity. 
    } 

    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
     // If your preview can change or rotate, take care of those events here. 
     // Make sure to stop the preview before resizing or reformatting it. 

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

     // stop preview before making changes 
     try { 
      mCamera.stopPreview(); 
     } catch (Exception e) { 
      // ignore: tried to stop a non-existent preview 
     } 
    } 
} 

我在這裏把我的觀點:

@Override 
    public void onCreateViewContent(LayoutInflater layoutInflater, ViewGroup parentGroup, View[] containerViews, int index) { 
     containerViews[index] = layoutInflater.inflate(R.layout.example_camera, parentGroup, false); 
     FrameLayout previewFrame = (FrameLayout) containerViews[index].findViewById(R.id.preview); 

     previewFrame.addView(mPreview); 

    } 

問題是,我沒有看到我能如何擁有一臺設備通常具有的兩個不同攝像機的兩個實例並將它們改變爲一個自動在一定的秒數之後,以便我的框架在每隔一定的秒數後一個接一個地顯示前後相機預覽。任何解決方案,高度讚賞!我想我必須在surfaceChanged()方法中處理它,但我真的不知道如何!

至於問,這裏是,AnimatedViewContainer類:

public abstract class AnimatedViewContainer extends Example { 

    Context mContext; 
    int mAnimationDuration; 
    int mAnimationDurationShort; 
    LayoutInflater mLayoutInflater; 
    ViewGroup mParentGroup; 
    View[] mContainerViews; 

    boolean hasBeenClicked = false; 

    int mCurrentIndex; 
    int mMaxNumItems; 
    int mIndexVisibleItem; 

    public AnimatedViewContainer(Context context, int maxNumItems) { 
     super(context); 

     mContext = context; 
     mMaxNumItems = maxNumItems; 
     mContainerViews = new View[mMaxNumItems]; 

     // Retrieve and cache the system's default "medium" animation time 
     mAnimationDuration = getResources().getInteger(android.R.integer.config_mediumAnimTime); 
     // and "short" 
     mAnimationDurationShort = getResources().getInteger(android.R.integer.config_shortAnimTime); 

     mCurrentIndex = 0; 

     mLayoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     //TODO: shouldn't be null, should be any ViewGroup with the right LayoutParams 
     mParentGroup = null; 
    } 





    public abstract void onCreateViewContent(LayoutInflater layoutInflater, ViewGroup parentGroup, View[] containerViews, int index); 

    public boolean createView() { 

     if (mCurrentIndex >= mMaxNumItems) { 
      return false; // indicates to terminate the loop 
     } 


     // handle/execute the concrete definition of the view content defined by the child class 
     onCreateViewContent(mLayoutInflater, mParentGroup, mContainerViews, mCurrentIndex); 


     // only the first container view should be visible 
     if (mCurrentIndex == 0) { 
      mContainerViews[mCurrentIndex].setVisibility(View.VISIBLE); 
      mIndexVisibleItem = mCurrentIndex; 
     } else { 
      mContainerViews[mCurrentIndex].setVisibility(View.GONE); 
     } 


     // if you click on the container view, show next container view with a crossfade animation 
     mContainerViews[mCurrentIndex].setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       crossfade(true); 
       hasBeenClicked = true; 
      } 
     }); 


     // add the container view to the FrameLayout 
     addView(mContainerViews[mCurrentIndex]); 


     mCurrentIndex++; 

     return true; 
    } 


    public void crossfade(boolean manuallyClicked) { 
     //only rotate when example is actually shown and at least one content item was created. This may also prevent NPEs due to incompletely loaded views. 
     if(!this.isShown() || mCurrentIndex == 0) 
      return; 

     //when example was previously clicked, don't do anything 
     if(!manuallyClicked && hasBeenClicked){ 
      hasBeenClicked = false; 
      return; 
     } 

     int numTotalItems = mCurrentIndex; 
     final int indexVisibleItem = mIndexVisibleItem; 


     int nextIndex = indexVisibleItem + 1; 

     if (nextIndex >= numTotalItems) { 
      nextIndex = 0; 
     } 

     final boolean hasOnlyOneItem; 
     if (numTotalItems == 1) { 
      hasOnlyOneItem = true; 
     } else { 
      hasOnlyOneItem = false; 
     } 


     if (hasOnlyOneItem) { //there is only one item in the mContainerViews 
      mContainerViews[indexVisibleItem].animate().alpha(0.5f).setDuration(mAnimationDurationShort).setListener(new AnimatorListenerAdapter() { 
       @Override 
       public void onAnimationEnd(Animator animation) { 
        mContainerViews[indexVisibleItem].animate().alpha(1f).setDuration(mAnimationDurationShort).setListener(null); 
       } 
      }); 
     } else { 
      // Set the next view to 0% opacity but visible, so that it is visible (but fully transparent) during the animation. 
      mContainerViews[nextIndex].setAlpha(0f); 
      mContainerViews[nextIndex].setVisibility(View.VISIBLE); 

      // Animate the next view to 100% opacity, and clear any animation 
      // listener set on the view. 
      mContainerViews[nextIndex].animate().alpha(1f).setDuration(mAnimationDuration).setListener(null); 

      // Animate the current view to 0% opacity. After the animation ends, 
      // set its visibility to GONE as an optimization step (it won't participate in layout passes, etc.) 
      mContainerViews[indexVisibleItem].animate().alpha(0f).setDuration(mAnimationDuration).setListener(new AnimatorListenerAdapter() { 
       @Override 
       public void onAnimationEnd(Animator animation) { 
        mContainerViews[indexVisibleItem].setVisibility(View.GONE); 
       } 
      }); 
     } 

     mIndexVisibleItem = nextIndex; 
    } 

    @Override 
    public void cleanup() { 

    } 

} 
+1

需要2秒延時自動做呢?我對嗎 ? – AndroidHacker

+0

@AndroidHacker是的,我完全無法做到!這也是我想這樣做,但失敗:https://stackoverflow.com/questions/44659650/unable-to-generate-camera-preview-view –

+1

好吧..你是不是也願意使用設備原生相機拍攝的形式形象? – AndroidHacker

回答

2

我能找到一個解決方案來改變相機在幾秒鐘(但請記住,亞歷克斯科恩說,因爲,通常需要2秒以上開始預覽你不能改變相機在2秒內,它依賴於該設備)通過改變你的代碼一點點。請使用下面的代碼並檢查。

注意:我沒有實現任何方向更改和拍照功能,我希望您已經開發了這些功能,實際上您只需要在幾秒鐘內自動更換相機。

我用對話片段顯示在對話框中預覽。這裏是CameraExample的代碼

import android.content.Context; 
import android.content.pm.PackageManager; 
import android.hardware.Camera; 
import android.os.Bundle; 
import android.os.CountDownTimer; 
import android.support.v4.app.DialogFragment; 
import android.util.Log; 
import android.view.Gravity; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.FrameLayout; 
import android.widget.LinearLayout; 

/** 
* Created by Admin on 6/26/2017. 
*/ 

public class CameraExample extends DialogFragment { 
    private final static String TAG = "CameraExample"; 

    private Camera mCamera; 
    private CameraPreview mPreview; 
    private Context mContext; 
    private View view; 
    private int mCamId = 0; 

    public CameraExample() { 

     mPreview = null; 
     mContext = getContext(); 

    } 

    // A safe way to get an instance of the Camera object. 
    public static Camera getCameraInstance(int cameraId) { 
     Camera c = null; 
     try { 
      // attempt to get a Camera instance 
      c = Camera.open(cameraId); 
     } catch (Exception e) { 
      // Camera is not available (in use or does not exist) 
      Log.e(TAG, "CameraExample: " + "camera not available (in use or does not exist); " + e.getMessage()); 
     } 
     return c; // returns null if camera is unavailable 
    } 

    private void initCamera(Context context, int cameraId) { 
     // Check if this device has a camera 
     if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) { 
      // no camera on this device 
      Log.e(TAG, "CameraExample: " + "this device has no camera"); 
     } else { 
      // this device has a camera 
      int numCameras = Camera.getNumberOfCameras(); 
      if (numCameras >= 0) { 
       mCamera = getCameraInstance(cameraId); 
       if (mCamera != null) { 
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); 
        Camera.getCameraInfo(cameraId, cameraInfo); 
        try { 
         //Create our Preview view and set it as the content of this LinearLayout View 
         mPreview = new CameraPreview(context, mCamera, cameraId); 
         LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); 
         mPreview.setLayoutParams(layoutParams); 
        } catch (RuntimeException e) { 
         Log.e(TAG, "Camera failed to open: " + e.getLocalizedMessage()); 
        } 
       } 
      } 
     } 
    } 

    private CountDownTimer countDownTimer; 

    private void switchCam() { 
     //10 seconds 
     countDownTimer = new CountDownTimer(10000, 1000) { 

      @Override 
      public void onTick(long l) { 
       System.out.println(l + " left"); 
      } 

      @Override 
      public void onFinish() { 
       cleanup(); 
       startCam(); 
      } 
     }.start(); 

    } 


    private void startCam() { 

     initCamera(getContext(), mCamId); 
     FrameLayout previewFrame = (FrameLayout) view.findViewById(R.id.preview); 
     previewFrame.removeAllViews(); 
     // Add preview for inflation 
     previewFrame.addView(mPreview); 

     mCamId = mCamId == 0 ? 1 : 0; 

     switchCam(); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     super.onCreateView(inflater, container, savedInstanceState); 
     getDialog().getWindow().setGravity(Gravity.CENTER); 
//  getDialog().getWindow().setBackgroundDrawableResource(android.R.color.transparent); 


     view = inflater.inflate(R.layout.camera_fragment, container, false); 
     startCam(); 
     return view; 
    } 

    @Override 
    public void onPause() { 
     super.onPause(); 
     cleanup(); 
     if (countDownTimer != null) 
      countDownTimer.cancel(); 
    } 

    @Override 
    public void onStart() { 
     super.onStart(); 
     getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); 
    } 

    public void cleanup() { 
     if (mCamera != null) { 
      mCamera.stopPreview(); 
      mCamera.release(); 
      mCamera = null; 
     } 
    } 
} 

而且我也必須改變你的預覽類。請參閱下面的代碼。

import android.content.Context; 
import android.hardware.Camera; 
import android.util.Log; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 

import java.io.IOException; 

/** 
* Created by Admin on 6/26/2017. 
*/ 

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { 

    private static final String TAG = "CameraPreview"; 

    private Context mContext; 
    private SurfaceHolder mHolder; 
    private Camera mCamera; 
    private int mCameraId; 

    public CameraPreview(Context context, Camera camera, int cameraId) { 
     super(context); 
     mContext = context; 
     mCamera = camera; 
     mCameraId = cameraId; 

     // Install a SurfaceHolder.Callback so we get notified when the 
     // underlying surface is created and destroyed. 
     mHolder = getHolder(); 
     mHolder.addCallback(this); 
    } 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
     // The Surface has been created, now tell the camera where to draw the preview. 
     try { 
      mCamera.setPreviewDisplay(holder); 
      mCamera.startPreview(); 
     } catch (IOException e) { 
      Log.e(TAG, "CameraExample: " + "Error setting camera preview: " + e.getMessage()); 
     } 
    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
     // empty. Take care of releasing the Camera preview in your activity. 
     // stop preview before making changes 
     try { 
      mCamera.stopPreview(); 
     } catch (Exception e) { 
      // ignore: tried to stop a non-existent preview 
     } 
    } 

    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
     // If your preview can change or rotate, take care of those events here. 
     // Make sure to stop the preview before resizing or reformatting it. 

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


    } 
} 
+0

它適合我。 – Chathurka

+0

謝謝!我得到這個錯誤:'連接到相機時發生錯誤:2,未能連接到服務' 這是我最終改變使用您的代碼:https://pastebin.com/PdcqRfUb –

+0

@ Jeet.Deir你可以發送請給我錯誤日誌?你也可以告訴我們這個AnimatedViewContainer類是什麼? – TdSoft

0

你必須停止攝像機,切換面,然後重新啓動它:

使用定時器和定期調用switchFacing()每2秒。

但要注意的:

This class was deprecated in API level 21. We recommend using the new android.hardware.camera2 API for new applications.

EDIT2:下面是完整的類準備使用。

//This class uses Camera1 API to be backwards compatible. 

private static String TAG = "CameraManager"; 

private Context mContext = null; 
private SurfaceView mPreview = null; 
private SurfaceHolder mHolder = null; 
private Camera mCamera = null; 
private int mFrontFaceID = -1; 
private int mBackFaceID = -1; 
private int mActualFacingID = -1; 

public CameraManager(Context context, SurfaceView preview) { 
    mContext = context; 
    mPreview = preview; 
    mHolder = mPreview.getHolder(); 
    mHolder.addCallback(this); 
} 

//called in onCreate 
public void init() { 
    Camera.CameraInfo info = new Camera.CameraInfo(); 
    for (int i = 0; i < Camera.getNumberOfCameras(); i++) { 
     Camera.getCameraInfo(i, info); 
     if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 
      mFrontFaceID = i; 
     } 
     if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) { 
      mBackFaceID = i; 
     } 
    } 
    if (mActualFacingID == -1) { 
     if (mFrontFaceID != -1) { 
      mActualFacingID = mFrontFaceID; 
     } else { 
      mActualFacingID = mBackFaceID; 
     } 
    } 
    //At least one one camera will be available because of manifest declaration 
} 

//called first on surface created 
public void start() { 
    Log.i(TAG, "startCamera()"); 
    if (mCamera == null) { 
     mCamera = getCameraInstance(mActualFacingID); 
    } 
    if (mCamera == null) { 
     Log.i(TAG, "can't get camera instance"); 
     return; 
    } 
    try { 
     mCamera.setPreviewDisplay(mHolder); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    setCameraDisplayOrientation(); 
    setBestSupportedSizes(); 
    mCamera.startPreview(); 
} 

public void stop() { 
    Log.i(TAG, "stopCamera()"); 
    if (mCamera != null) { 
     mCamera.stopPreview(); 
     mCamera.release(); 
     mCamera = null; 
    } 
} 

public void switchFacing() { 
    if (mFrontFaceID == -1 || mBackFaceID == -1) { 
     return; 
    } 
    stop(); 
    if (mActualFacingID == mFrontFaceID) { 
     mActualFacingID = mBackFaceID; 
    } else { 
     mActualFacingID = mFrontFaceID; 
    } 
    start(); 
} 

public Camera getCameraInstance(int cameraID) { 
    Camera c = null; 
    if (cameraID != -1) { 
     try { 
      c = Camera.open(cameraID); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      Log.i(TAG, "error opening camera: " + cameraID); 
     } 
    } 
    return c; 
} 

@Override 
public void surfaceCreated(SurfaceHolder holder) { 
    Log.i(TAG, "surfaceCreated()"); 
    start(); 
} 

@Override 
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
    Log.i(TAG, "surfaceChanged()"); 
} 

@Override 
public void surfaceDestroyed(SurfaceHolder holder) { 
    Log.i(TAG, "surfaceDestroyed()"); 
    stop(); 
} 

private void setBestSupportedSizes() { 
    if (mCamera == null) { 
     return; 
    } 
    Camera.Parameters parameters = mCamera.getParameters(); 
    List<Point> pictureSizes=getSortedSizes(parameters.getSupportedPictureSizes()); 

    List<Point> previewSizes=getSortedSizes(parameters.getSupportedPreviewSizes()); 

    Point previewResult=null; 
    for (Point size:previewSizes){ 
     float ratio = (float) size.y/size.x; 
     if(Math.abs(ratio-4/(float)3)<0.05){ //Aspect ratio of 4/3 because otherwise the image scales to much. 
      previewResult=size; 
      break; 
     } 
    } 
    Log.i(TAG,"preview: "+previewResult.x+"x"+previewResult.y); 
    Point pictureResult=null; 
    if(previewResult!=null){ 
     float previewRatio=(float)previewResult.y/previewResult.x; 
     for (Point size:pictureSizes){ 
      float ratio = (float) size.y/size.x; 
      if(Math.abs(previewRatio-ratio)<0.05){ 
       pictureResult=size; 
       break; 
      } 
     } 
    } 
    Log.i(TAG,"preview: "+pictureResult.x+"x"+pictureResult.y); 

    if(previewResult!=null && pictureResult!=null){ 
     Log.i(TAG,"best preview: "+previewResult.x+"x"+previewResult.y); 
     Log.i(TAG, "best picture: " + pictureResult.x + "x" + pictureResult.y); 
     parameters.setPreviewSize(previewResult.y, previewResult.x); 
     parameters.setPictureSize(pictureResult.y, pictureResult.x); 
     mCamera.setParameters(parameters); 
     mPreview.setBackgroundColor(Color.TRANSPARENT); //in the case of errors needed 
    }else{ 
     mCamera.stopPreview(); 
     mPreview.setBackgroundColor(Color.BLACK); 
    } 
} 

private List<Point> getSortedSizes(List<Camera.Size> sizes) { 
    ArrayList<Point> list = new ArrayList<>(); 

    for (Camera.Size size : sizes) { 
     int height; 
     int width; 
     if (size.width > size.height) { 
      height = size.width; 
      width = size.height; 
     } else { 
      height = size.height; 
      width = size.width; 
     } 
     list.add(new Point(width, height)); 

    } 

    Collections.sort(list, new Comparator<Point>() { 
     @Override 
     public int compare(Point lhs, Point rhs) { 
      long lhsCount = lhs.x * (long) lhs.y; 
      long rhsCount = rhs.x * (long) rhs.y; 
      if (lhsCount < rhsCount) { 
       return 1; 
      } 
      if (lhsCount > rhsCount) { 
       return -1; 
      } 
      return 0; 
     } 
    }); 
    return list; 
} 

//TAKE PICTURE 
public void takePhoto() { 
    if (mCamera != null) { 
     mCamera.takePicture(null, null, this); 
    } 
} 

@Override 
public void onPictureTaken(byte[] data, Camera camera) { 
    //do something with your picture 
} 

//ROTATION 
private void setCameraDisplayOrientation() { 
    if (mCamera != null) { 
     mCamera.setDisplayOrientation(getRotation()); 
    } 
} 

public int getRotation() { 
    Camera.CameraInfo info = new Camera.CameraInfo(); 
    Camera.getCameraInfo(mActualFacingID, info); 
    int rotation = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).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; 
    } 
    return result; 
} 

在一些一流的呼叫:

SurfaceView preview = (SurfaceView) findViewById(R.id.surfaceView); 
CameraManager mgr = new CameraManager(MainActivity.this, MainActivity.this, preview); 
mgr.init(); 
... 
mgr.takePhoto(); //surface must already be created 
mgr.switchFacing(); 
mgr.takePhoto(); 

此代碼應支持幾乎所有設備。最受支持的寬高比是4:3,代碼處理這一點。

EDIT3:本surface view must be in the xml of course

<SurfaceView 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:id="@+id/surfaceView" /> 
+0

您可以參考我發佈的實際代碼而不是您提供的通用答案來顯示此內容嗎? –

+0

只需將此代碼添加到您的CameraPreview類 – Appyx

+0

只需按原樣添加即可?如何在MainClass中創建開關?再次感謝! –

-1

我想這是你在找什麼:

ImageButton useOtherCamera = (ImageButton) findViewById(R.id.useOtherCamera); 
//if phone has only one camera, hide "switch camera" button 
if(Camera.getNumberOfCameras() == 1){ 
useOtherCamera.setVisibility(View.INVISIBLE); 
} 
else { 
useOtherCamera.setOnClickListener(new View.OnClickListener() { 
@Override 
public void onClick(View v) { 
if (inPreview) { 
    camera.stopPreview(); 
} 
//NB: if you don't release the current camera before switching, you app will crash 
camera.release(); 

//swap the id of the camera to be used 
if(currentCameraId == Camera.CameraInfo.CAMERA_FACING_BACK){ 
    currentCameraId = Camera.CameraInfo.CAMERA_FACING_FRONT; 
} 
else { 
    currentCameraId = Camera.CameraInfo.CAMERA_FACING_BACK; 
} 
camera = Camera.open(currentCameraId); 
//Code snippet for this method from somewhere on android developers, i forget where 
setCameraDisplayOrientation(CameraActivity.this, currentCameraId, camera); 
try { 
    //this step is critical or preview on new camera will no know where to render to 
    camera.setPreviewDisplay(previewHolder); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 
camera.startPreview(); 
} 

這是一個示例代碼,我很正面和背面攝像頭之間的即時切換。希望它會有所幫助。

+1

請注意,用於Camera.open()的相機ID不是爲Camera.CameraInfo定義的值之一。您應該使用[Camera.CameraInfo.facing()](https://developer.android.com/reference/android/hardware/Camera.CameraInfo.html#facing)方法來檢查範圍** 0 ... [getNumberOfCameras()](https://developer.android.com/reference/android/hardware/Camera.html#getNumberOfCameras())-1 ** –

+0

您能否定義使用Camera Id的任何缺點?這樣我可以防止使用它。因爲它在Camera Id中工作正常。 –

+0

一個例子是谷歌Nexus平板電腦(2012),它有一個前置攝像頭。它的ID是0. –

0

無法快速切換相機。所花費的時間停止相機,關閉它,打開另一個攝像頭,並開始預覽取決於設備,但在很多情況下(有時是在強大的現代化設備),這將是你把作爲你的目標2秒以上。

在另一方面,一些Android設備支持的兩個攝像頭同時工作,看Is it possible to use front and back Camera at same time in AndroidAndroid, Open Front and Back Cameras Simultaneously。因此,在一些基於Snapdragon 801的設備上,您可以保持兩臺攝像機「準備就緒」,並將視頻流量每秒切換30次。

+0

我很好,2秒鐘,但它怎麼回答這個問題呢? –

+0

讓我更好地理解你的要求:你想在屏幕上看到2秒的前置攝像頭預覽;黑屏,而相機切換到後向;後部預覽2秒;等等。?或者,在前一張照片後不遲於4秒重新獲得前置照片很重要,後置照片也一樣? –

0

我認爲你應該使用這個

mCamera = Camera.open(cameraId);

0 CAMERA_FACING_BACK

1 CAMERA_FACING_FRONT

這更多的參考流程: -

https://developer.android.com/reference/android/hardware/Camera.html#open(int)

https://developer.android.com/reference/android/hardware/Camera.CameraInfo.html#CAMERA_FACING_BACK

+0

請注意,用於Camera.open()的相機ID不是爲Camera.CameraInfo定義的值之一。您應該使用[Camera.CameraInfo.facing()](https://developer.android.com/reference/android/hardware/Camera.CameraInfo.html#facing)方法來檢查範圍** 0 ... [getNumberOfCameras()](https://developer.android.com/reference/android/hardware/Camera.html#getNumberOfCameras())-1 ** –

0

我們可以使用線程來保持一個攝像頭活躍,讓它停留一段時間。交換相機並重新進行相同的無限時間。

private boolean isActive; 

public void onStart(){ 
    super.onStart(); 
    isActive = true; 
    continuousCameraChange(your_camera) 
} 

public void onResume(){ 
    super.onResume(); 
    isActive = true; 
    continuousCameraChange(your_camera) 
} 

public void onPause(){ 
    super.onPause(); 
    isActive = false; 
} 


public void onDestroy(){ 
    super.onDestroy(); 
    isActive = false; 
} 


public void onStop(){ 
    super.onStop(); 
    isActive = false; 
} 

private void continuousCameraChange(Camera camera){ 
    do{ 
     switchCamera(camera); 
    }while(isActive); 
} 

private void switchCamera(Camera camera){ 
    if (Camera.CameraInfo.facing == CAMERA_FACING_BACK){ 
     try{ 
      Thread.sleep(2000); 
      camera.open(Camera.CameraInfo.CAMERA_FACING_BACK); 
     }catch(InterruptedException ex){ 
      Thread.currentThread().interrupt(); 
     } 
     //change your camera 
     Camera.CameraInfo.facing == CAMERA_FACING_FRONT; 
    }else{ 
     try{//change 2000 to change the time for which your camera stays available 
      Thread.sleep(2000); 
      camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT); 
     }catch(InterruptedException ex){ 
      Thread.currentThread().interrupt(); 
     } 
     //change your camera 
     Camera.CameraInfo.facing == CAMERA_FACING_BACK; 
    } 
} 
1

在你的課堂上有一個雙重初始化錯誤。我可以有它運行,並且看到攝像機開關從0到1和背部,10秒後,下面的修復後:

我從CameraExample構造除去調用initCamera()。相反,我把那裏打電話給CreateView()。另外,您也可以致電CreateView的(),這是一個公共方法,從地方,你創建新CameraExample(背景下,我)

注意,這指的是代碼dropbox,沒有什麼是張貼在的問題。

+0

太棒了!謝謝! –

相關問題