Android API8中的setDisplayOrientation完全没有影响

5
我只处理了视频,没有图片。 注意到setDisplayOrientation只在预览过程中影响正确的显示方向。 但是,如果播放任何横向或纵向拍摄的视频,则始终以横向模式显示。 我在AndroidManifest.xml中设置了“android:screenOrientation = ”portrait“”,但是在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>

展示你的 AndroidManifest.xml 文件?你可能需要在你的布局或者清单文件中指定方向,例如 android:orientation="vertical"... - t0mm13b
已编辑。清单已添加。您需要布局吗? - Oleg Karakoz
2个回答

1

您应该将 android:screenOrientation="landscape" 更改为 android:screenOrientation="portrait"


0

不确定你是否遇到了和我完全相同的问题。

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

希望能有所帮助,祝好运!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接