Android API8 setDisplayOrientation根本不受影响

时间:2012-08-12 16:15:12

标签: android mediarecorder

我只使用 VIDEO 。没有照片。 注意, setDisplayOrientation 仅在预览期间影响正确的显示方向。 但是,如果要以横向模式或纵向模式播放任何视频,则始终处于横向模式

我在AndroidManifest.xml中设置     

但是用于在4.0.1设备中进行调试。也许这是一个问题。 但是我注意到默认的相机应用程序工作正常并以纵向模式捕捉肖像电影。

我错过了什么?...

** CameraRecorder.java

public class CameraRecorder extends Activity {

private CameraPreview mPreview;
private Camera mCamera;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.camera_surface);

    // Create an instance of Camera
    mCamera = getCameraInstance();
    if (mCamera == null) {
        Log.e(TAG, "Camera is not available");
        finish();
    }

    // Create our Preview view and set it as the content of our activity.
    mPreview = new CameraPreview(this, mCamera);
    FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
    preview.addView(mPreview);

    mPreview.setOnClickListener(startStopListener);
}
private void changeOrientation(int what) {
    if (what != orientation) {
        setRequestedOrientation(orientation = what);
    }
}
OnClickListener startStopListener = new OnClickListener() {

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        if (isRecording) {
                    mMediaRecorder.stop(); // stop the recording
            releaseMediaRecorder(); // release the MediaRecorder object
            mCamera.lock(); // take camera access back from MediaRecorder

            // inform the user that recording has stopped
            setCaptureButtonText("Capture");
            isRecording = false;

        } else {
            // initialize video camera
            if (prepareVideoRecorder()) {
                // Camera is available and unlocked, MediaRecorder is
                // prepared, now you can start recording
                mMediaRecorder.start();

                // inform the user that recording has started
                isRecording = true;
            } else {
                // prepare didn't work, release the camera
                releaseMediaRecorder();
            }
        }

    }
};

File tempFile;

@Override
protected void onPause() {
    super.onPause();
    releaseMediaRecorder(); // if you are using MediaRecorder, release it first
    releaseCamera(); // release the camera immediately on pause event
}

/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance() {
    Camera c = null;
        try {
            c = Camera.open(); // attempt to get a Camera instance

        } catch (Exception e) {
            // Camera is not available (in use or does not exist)

            Log.d(TAG, "Fail to connect to camera service. Is it locked?");
        }
    }
    return c; // returns null if camera is unavailable
}

private boolean prepareVideoRecorder() {
    if (mCamera == null)
        mCamera = getCameraInstance();
    if (mMediaRecorder == null)
        mMediaRecorder = new MediaRecorder();

    Camera.Parameters p = mCamera.getParameters();

    // Step 1: Unlock and set camera to MediaRecorder
    mCamera.unlock();
    mMediaRecorder.setCamera(mCamera);

    // Step 2: Set sources
    mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

    // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
    CamcorderProfile profile = mPreview.getProfile();// CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);

    Size previewSize = mPreview.getPreviewSize();

    if (previewSize != null) {
        profile.videoFrameWidth = previewSize.width;
        profile.videoFrameHeight = previewSize.height;
    }
    mMediaRecorder.setProfile(profile);

    // Step 4: Set output file
    mMediaRecorder.setOutputFile(MediaFile.getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());

    // Step 5: Set the preview output
    mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());

    // Step 6: Prepare configured MediaRecorder
    try {
        mMediaRecorder.prepare();
    } catch (IllegalStateException e) {
        Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
        releaseMediaRecorder();
        return false;
    } catch (IOException e) {
        Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
        releaseMediaRecorder();
        return false;
    }
    return true;
}

private void releaseMediaRecorder() {
    if (mMediaRecorder != null) {
        mMediaRecorder.reset(); // clear recorder configuration
        mMediaRecorder.release(); // release the recorder object
        mMediaRecorder = null;
        mCamera.lock(); // lock camera for later use
    }
}

private void releaseCamera() {
    if (mPreview != null) {
        mPreview.surfaceDestroyed(null);
    }
    if (mCamera != null) {
        mCamera.release(); // release the camera for other applications
        mCamera = null;
        Log.d(TAG, "Camera released");
    }
}
}

CameraPreview.java

/** A basic Camera preview class */
public class CameraPreview extends ViewGroup implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
private SurfaceView mSurfaceView;
private Context mContext;

private final String TAG = "CameraPreview";

public CameraPreview(Context context, Camera camera) {
    super(context);
    mContext = context;

    mCamera = camera;

    setCamera(mCamera);

    mSurfaceView = new SurfaceView(context);
    addView(mSurfaceView, 0);
    mHolder = mSurfaceView.getHolder();
    mHolder.addCallback(this);
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    mHolder.setKeepScreenOn(true);

}

public SurfaceHolder getHolder() {
    return mSurfaceView.getHolder();
}

private Size mPreviewSize;
private List<Size> mSupportedPreviewSizes;
private List<String> mSupportedFlashModes;

public Camera getCamera() {
    return mCamera;
}

private CamcorderProfile mProfile;

public CamcorderProfile getProfile() {
    return mProfile;
}

public void setCamera(Camera camera) {
    mCamera = camera;
    if (mCamera != null) {
        mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
        mSupportedFlashModes = mCamera.getParameters().getSupportedFlashModes();

                mProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);

        // Set the camera to Auto Flash mode.
        if (mSupportedFlashModes != null && mSupportedFlashModes.contains(Camera.Parameters.FLASH_MODE_AUTO)) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
            mCamera.setParameters(parameters);
        }
    }
    requestLayout();
}

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

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
    final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);

    if (mSupportedPreviewSizes != null) {
        mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, mProfile.videoFrameWidth, mProfile.videoFrameHeight);
    }
    setMeasuredDimension(width, height);
}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    if (changed) {
        final View cameraView = getChildAt(0);

        final int width = right - left;
        final int height = bottom - top;

        Camera.Parameters p = mCamera.getParameters();

        @SuppressWarnings("unused")
        int previewWidth = width;
        @SuppressWarnings("unused")
        int previewHeight = height;
        if (mPreviewSize != null) {
            Display display = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();

            switch (display.getRotation()) {
            case Surface.ROTATION_0:
                mCamera.setDisplayOrientation(90);
                break;
            case Surface.ROTATION_90:
            case Surface.ROTATION_180:
                break;
            case Surface.ROTATION_270:
                mCamera.setDisplayOrientation(180);
                break;
            }
        }

        cameraView.layout(0, 0, width, height);

    }
}

public void setSupportedPreviewSizes(List<Size> supportedPreviewSizes) {
    mSupportedPreviewSizes = supportedPreviewSizes;
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    // Surface will be destroyed when we return, so stop the preview.
    // Because the CameraDevice object is not a shared resource, it's very
    // important to release it when the activity is paused.
    try {
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.setPreviewCallback(null);
            // mCamera.release();
            mCamera = null;

            Log.d(TAG, "Preview destroyed");
        }
    } catch (Exception e) {
        Log.e(TAG, "Camera release failure.");
    }

}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    // 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
    }

    // set preview size and make any resize, rotate or
    // reformatting changes here

    Camera.Parameters parameters = mCamera.getParameters();
    Size previewSize = getPreviewSize();
    if (previewSize != null)
        parameters.setPreviewSize(previewSize.width, previewSize.height);

    mCamera.setParameters(parameters);

    // start preview with new settings
    try {
        previewCamera();

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

public Size getPreviewSize() {
    return mPreviewSize;
}

public static Size getOptimalPreviewSize(List<Size> sizes, int width, int height) {
    double aspectTolerance = 0.05;
    double targetRatio = (double) width / height;
    if (sizes == null) {
        return null;
    }
    Size optimalSize = null;
    double minDiff = Double.MAX_VALUE;
    int targetHeight = height;
    // Try to find an size match aspect ratio and size
    for (Size size : sizes) {
        double ratio = (double) size.width / size.height;
        if (Math.abs(ratio - targetRatio) > aspectTolerance)
            continue;
        if (Math.abs(size.height - targetHeight) < minDiff) {
            optimalSize = size;
            minDiff = Math.abs(size.height - targetHeight);
        }
    }
    // Cannot find the one match the aspect ratio, ignore the requirement
    if (optimalSize == null) {
        minDiff = Double.MAX_VALUE;
        for (Size size : sizes) {
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
    }
    return optimalSize;

}

public void previewCamera() {
    try {
        mCamera.setPreviewDisplay(mHolder);
        mCamera.startPreview();
    } catch (Exception e) {
        Log.d(TAG, "Cannot start preview.", e);
    }
}

}

的Manifest.xml

<uses-sdk android:minSdkVersion="8" />

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

<application
    android:name=".client.andi"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
    <activity
        android:name=".activity.CameraRecorder"
        android:label="@string/title_activity_main"
        android:screenOrientation="landscape"
        android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

** layout.xml **

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/RelativeLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="bottom"
android:orientation="vertical" >

<FrameLayout
    android:id="@+id/camera_preview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true" >
</FrameLayout>

</RelativeLayout>

2 个答案:

答案 0 :(得分:1)

你应该将android:screenOrientation =“landscape”改为android:screenOrientation =“portrait”

答案 1 :(得分:0)

不确定您是否遇到与我完全相同的问题。

我之前也遇到过这个问题。我发现你可以使用函数setOrientationHint(API 9)。在调用MediaRecorder.prepare()之前调用此函数。您可以设置输出视频的方向度。

希望它有所帮助,祝你好运!