所以我有一个简单的相机管理器课程,我想在对话框中生成相机预览。除了相机预览未在对话框中显示的部分外,一切都有效!这是调用相机的类
经理级别:
public class CameraExample extends AnimatedViewContainer {
private final static String TAG = "CameraExample";
private Context mContext;
private SurfaceView mPreview;
public CameraExample(Context context, int i) {
super(context, i);
mContext = context;
}
@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);
//this have been line moved here from constructor
mPreview = (SurfaceView) findViewById(R.id.surfaceView);
CameraPreview mgr = new CameraPreview(mContext, mPreview);
mgr.init();
// Add preview for inflation
previewFrame.addView(mPreview);
}
}
以下是Camera Manager课程:
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
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 CameraPreview(Context context, SurfaceView preview) {
super(context);
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;
}
public void onPictureTaken(byte[] data, Camera camera) {
//do something with your picture
}
//ROTATION
private void setCameraDisplayOrientation() {
if (mCamera != null) {
mCamera.setDisplayOrientation((int) getRotation());
}
}
@Override
public float 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;
}
}
最后这里是XML
:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<FrameLayout
android:id="@+id/preview"
android:layout_width="match_parent"
android:layout_height="@dimen/photo_example_height">
<SurfaceView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/surfaceView" />
</FrameLayout>
</LinearLayout>
我确实拥有所有必需的permissions
,问题是编译或运行时没有错误!我的错误是全能的否认我在对话框中的预览?
答案 0 :(得分:1)
我想问题就在这一行:
mPreview = (SurfaceView) findViewById(R.id.surfaceView);
您正试图从您的活动中获取它,但它并不存在。 Surfaceview实际上是在Container中。试试这个:
用以下代码替换上面的代码:
mPreview = (SurfaceView) containerViews[index].findViewById(R.id.surfaceView);
希望它能奏效!