Android API8 setDisplayOrientation完全不影响
我只使用了视频。没有照片。 请注意,setDisplayOrientation仅在预览期间影响右显示方向。 但是,如果要播放以横向模式或纵向模式捕获的任何视频,则始终处于横向模式 我在AndroidManifest.xml中设置了 但用于在4.0.1设备中调试。也许这是个问题。 不过我注意到默认的摄像头应用程序工作正常,可以在纵向模式下拍摄纵向电影 我错过了什么 **CameraRecorder.javaAndroid API8 setDisplayOrientation完全不影响,android,mediarecorder,Android,Mediarecorder,我只使用了视频。没有照片。 请注意,setDisplayOrientation仅在预览期间影响右显示方向。 但是,如果要播放以横向模式或纵向模式捕获的任何视频,则始终处于横向模式 我在AndroidManifest.xml中设置了 但用于在4.0.1设备中调试。也许这是个问题。 不过我注意到默认的摄像头应用程序工作正常,可以在纵向模式下拍摄纵向电影 我错过了什么 **CameraRecorder.java public class CameraRecorder extends Activity
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);
}
}
}
/**基本相机预览类*/
公共类CameraPreview扩展视图组实现SurfaceHolder.Callback{
私人地勤人员;
私人摄像机麦卡梅拉;
私人SurfaceView mSurfaceView;
私有上下文;
私有最终字符串标记=“CameraPreview”;
公共摄像机回顾(上下文、摄像机){
超级(上下文);
mContext=上下文;
mCamera=摄像机;
setCamera(mCamera);
mSurfaceView=新的SurfaceView(上下文);
addView(mSurfaceView,0);
mHolder=mSurfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE\u TYPE\u PUSH\u缓冲区);
mHolder.setKeepScreenOn(真);
}
公共SurfaceHolder getHolder(){
返回mSurfaceView.getHolder();
}
私人规模的mPreviewSize;
私有列表msupportedpreviews;
私有列表MSSupportedFlashModes;
公共摄像机{
返回mCamera;
}
私人摄像机公司;
公共摄像机配置文件getProfile(){
返回文件;
}
公共摄像机(摄像机){
mCamera=摄像机;
if(mCamera!=null){
mSupportedPreviewSizes=mCamera.getParameters().getSupportedPreviewSizes();
msSupportedFlashModes=mCamera.getParameters().getSupportedFlashModes();
mProfile=摄像机profile.get(摄像机profile.QUALITY\u HIGH);
//将相机设置为自动闪光模式。
if(mSupportedFlashModes!=null&&mSupportedFlashModes.contains(Camera.Parameters.FLASH\u MODE\u AUTO)){
Camera.Parameters=mCamera.getParameters();
parameters.setFlashMode(相机.参数.闪光模式自动);
mCamera.setParameters(参数);
}
}
requestLayout();
}
@凌驾
已创建的公共空白表面(表面持有人){
//曲面已创建,现在告诉摄影机在何处绘制预览。
试一试{
if(mCamera!=null){
mCamera.setPreviewDisplay(支架);
//mCamera.startPreview();
}
}捕获(IOE异常){
Log.d(标记“错误设置相机预览:”+e.getMessage());
}
}
@凌驾
测量时的保护空隙(内部宽度测量等级、内部高度测量等级){
最终整数宽度=resolveSize(getSuggestedMinimumWidth(),widthMeasureSpec);
最终整数高度=resolveSize(getSuggestedMinimumHeight(),heightMeasureSpec);
if(mSupportedPreviewSizes!=null){
mPreviewSize=getOptimalPreviewSize(MSSupportedPreviewSize,mProfile.videoFrameWidth,mProfile.videoFrameHeight);
}
设置测量尺寸(宽度、高度);
}
@凌驾
仅限受保护的空心布局(布尔值已更改、整数左侧、整数顶部、整数右侧、整数底部){
如果(更改){
最终视图cameraView=getChildAt(0);
最终整数宽度=右-左;
最终内部高度=底部-顶部;
Camera.Parameters p=mCamera.getParameters();
@抑制警告(“未使用”)
int previewWidth=宽度;
@抑制警告(“未使用”)
亮度=高度;
if(mPreviewSize!=null){
Display Display=((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
开关(display.getRotation()){
外壳表面旋转0:
mCamera.setDisplayOrientation(90);
打破
外壳表面旋转90度:
外壳表面旋转180度:
打破
外壳表面。旋转_270:
mCamera.setDisplayOrientation(180);
打破
}
}
cameraView.布局(0,0,宽度,高度);
}
}
public void setSupportedPreviewSizes(列表supportedPreviewSizes){
mSupportedPreviewSizes=supportedPreviewSizes;
}
@凌驾
公共空间表面覆盖(表面覆盖物持有人){
//当我们返回时,曲面将被破坏,因此请停止预览。
//因为CameraDevice对象不是共享资源,所以它非常有用
//当活动暂停时释放它很重要。
试一试{
if(mCamera!=null){
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
//mCamera.release();
mCamera=null;
日志d(标签“预览已销毁”);
}
}捕获(例外e){
Log.e(标签“摄像机释放故障”);
}
}
@凌驾
公共无效表面更改(表面持有人,整数格式,整数w,整数h){
//如果预览可以更改或旋转,请在此处处理这些事件。
//请确保在调整预览大小或重新设置预览格式之前停止预览。
if(mHolder.getSurface()==null){
//预览曲面不存在
返回;
}
//在进行更改之前停止预览
试一试{
mCamera.stopPreview();
}捕获(例外e){
//忽略:尝试停止不存在的预览
}
//设置预览大小并进行任何调整大小、旋转或
//在此处重新格式化更改
Camera.Parameters=mCamera.getParameters();
大小previewSize=getPreviewSize();
如果(previewSize!=null)
parameters.setPreviewSize(previewSize.width、previewSize.height);
mCamera.setParameters(参数);
//使用新设置开始预览
试一试{
预览摄影机();
}捕获(例外e){
Log.d(标记“启动相机预览时出错:”+e.getMessage());
<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>
<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>