GetCameraDisplayOrientation始终返回0

时间:2013-10-09 15:31:06

标签: android android-camera screen-orientation android-video-player

我正在尝试在Android中以正确的方向录制视频。我已经构建了我的Activity,它工作正常,唯一的事情是录制后保存的视频是旋转的。相机预览正常,所以我无法理解原因。要修复轮播,我使用此代码(我在Google Developers上找到的方法):

mMediaRecorder.setOrientationHint(getCameraDisplayOrientation());    

private int getCameraDisplayOrientation()
    {
        android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
        android.hardware.Camera.getCameraInfo(CameraInfo.CAMERA_FACING_BACK,
                info);
        int rotation = getWindowManager().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;

活动在清单中定义如下:

    <activity android:name="pages.CameraPage"
      android:label="@string/app_name"
      android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
      android:screenOrientation="landscape"
      >
    </activity>

问题是getCameraDisplayOrientation总是返回0度,无论我如何定位屏幕。

我在记录开始之前调用该方法,所以如果我能够根据默认格局获得屏幕旋转,我就可以了。

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

最后,我能够成功构建自己的相机应用,没有任何方向问题。关键是看着surfaceView进行旋转。我认为这可能有助于将所有代码发布在此处,只需复制并启动活动!

CameraPage.java

package pages;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URI;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;

import model.CameraView;

import com.controller.R;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Base64;
import android.util.Log;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.view.animation.AlphaAnimation;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.Toast;




public class CameraPage extends Activity
{
    private Camera mCamera;
    private CameraView mPreview;
    private MediaRecorder mMediaRecorder;
    private FrameLayout preview;
    private ImageButton buttonRecordStop;
    private boolean isRecording = false;
    private String fileName;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        Log.d("CameraPage-onCreate", "Called onCreate()");

        setContentView(R.layout.camera_surface);

        buttonRecordStop = (ImageButton) findViewById(R.id.camera_surface_buttonRecordStop);

        buttonRecordStop.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event)
            {
                if (event.getAction() == MotionEvent.ACTION_DOWN
                        || event.getAction() == MotionEvent.ACTION_MOVE)
                {
                    AlphaAnimation alpha = new AlphaAnimation(1.0F, 0.3F);
                    alpha.setDuration(100);
                    alpha.setFillAfter(true); // Tell it to persist after the animation ends
                    buttonRecordStop.startAnimation(alpha);
                } else if (event.getAction() == MotionEvent.ACTION_UP
                        || event.getAction() == MotionEvent.ACTION_CANCEL)
                {
                    AlphaAnimation alpha = new AlphaAnimation(0.3F, 1.0F);
                    alpha.setDuration(100);
                    alpha.setFillAfter(true); // Tell it to persist after the animation ends
                    buttonRecordStop.startAnimation(alpha);
                }
                return false;
            }
        });

        buttonRecordStop.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v)
            {
                if (!isRecording)
                {
                    Log.d("CameraPage-buttonRecordStop-onClick", "Start Record");

                    getWindow().addFlags(
                            WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

                    // initialize video camera
                    if (prepareVideoRecorder())
                    {
                        v.setVisibility(View.GONE);
                        ((ImageButton) v)
                                .setImageResource(R.drawable.iconapause);
                        v.setVisibility(View.VISIBLE);
                        isRecording = true;

                        // Camera is available and unlocked, MediaRecorder is prepared,
                        // now you can start recording
                        mMediaRecorder.start();

                    } else
                    {
                        // prepare didn't work, release the camera
                        releaseMediaRecorder();
                        // inform user
                    }

                } else
                {
                    Log.d("CameraPage-buttonRecordStop-onClick", "Stop Record");

                    getWindow().clearFlags(
                            WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

                    v.setVisibility(View.GONE);
                    ((ImageButton) v).setImageResource(R.drawable.iconarecord);
                    v.setVisibility(View.VISIBLE);
                    isRecording = false;

                    stopRecording();

                    sendBroadcast(new Intent(
                            Intent.ACTION_MEDIA_MOUNTED,
                            Uri.parse("file://"
                                    + Environment.getExternalStorageDirectory())));


                }

            }// end onClick
        });

        mCamera = getCameraInstance();
        preview = (FrameLayout) findViewById(R.id.camera_preview);

    }// end onCreate


    @Override
    protected void onResume()
    {
        super.onResume();
        Log.d("CameraPage-onResume",
                "Chiamato onResume ripristino le risorse se necessario");

        if (mCamera == null)
        {
            // Create an instance of Camera
            mCamera = getCameraInstance();

        }

        if (mPreview == null)
        {
            mPreview = new CameraView(getApplicationContext(), mCamera, this);
            preview.addView(mPreview);
        }

    }

    @Override
    protected void onPause()
    {
        super.onPause();
        Log.d("CameraPage-onPause", "Vado in onPause e rilascio le risorse");

        releaseMediaRecorder(); // if you are using MediaRecorder, release it first
        releaseCamera(); // release the camera immediately on pause event

        preview.removeView(mPreview);
        mPreview = null;
    }

    private void stopRecording()
    {
        mMediaRecorder.stop();
        releaseMediaRecorder();

        // Restarto la preview della camera
        mCamera.startPreview();
        // mCamera.lock();
    }

    private boolean prepareVideoRecorder()
    {

        // mCamera = getCameraInstance();
        mMediaRecorder = new MediaRecorder();

        // Stop preview because I have to start the preview for the video
        mCamera.stopPreview();

        // 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)
        mMediaRecorder.setProfile(CamcorderProfile
                .get(CamcorderProfile.QUALITY_HIGH));

        // Step 4: Set output file
        setOutputFile();
        mMediaRecorder.setOutputFile(getOutputFile());

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

        mMediaRecorder.setOrientationHint(CameraPage
                .getCameraDisplayOrientation(this,
                        Camera.CameraInfo.CAMERA_FACING_BACK, mCamera));

        // Step 6: Prepare configured MediaRecorder
        try
        {
            mMediaRecorder.prepare();
        } catch (IllegalStateException e)
        {
            Log.d("CameraPage-prepareVideoRecorder",
                    "IllegalStateException preparing MediaRecorder: "
                            + e.getMessage());
            releaseMediaRecorder();
            return false;
        } catch (IOException e)
        {
            Log.d("CameraPage-prepareVideoRecorder",
                    "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 (mCamera != null)
        {
            mCamera.release(); // release the camera for other applications
            mCamera = null;
        }

        if (mPreview != null)
            mPreview.getHolder().removeCallback(mPreview);
    }

    /** A safe way to get an instance of the Camera object. */
    private Camera getCameraInstance()
    {
        Camera c = null;
        try
        {
            Log.d("CameraPage-getCameraInstance", "Prendo istanza camera");
            c = Camera.open(); // attempt to get a Camera instance
        } catch (Exception e)
        {
            // Camera is not available (in use or does not exist)
            Log.d("CameraPage-getCameraInstance",
                    "Eccezione durante retrieve istanza camera " + e);
        }
        return c; // returns null if camera is unavailable
    }

    @SuppressLint("SimpleDateFormat")
    private void setOutputFile()
    {
        String folderPath = Environment.getExternalStorageDirectory().getPath();
        File vims = new File(folderPath + "/ViMS");

        if (!vims.exists())
            vims.mkdir();

        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd---HH-mm-ss");
        Date date = new Date();
        String timestamp = "/" + dateFormat.format(date) + ".mp4";

        Log.d("CameraPage-getOutputFile", Environment
                .getExternalStorageDirectory().getPath());

        fileName = vims.getPath() + timestamp;

    }

    private String getOutputFile()
    {
        return fileName;
    }

    public static void setCameraDisplayOrientation(Activity activity,
            int cameraId, android.hardware.Camera camera)
    {

        int result = CameraPage.getCameraDisplayOrientation(activity, cameraId,
                camera);

        if (android.os.Build.VERSION.SDK_INT <= 14)
        {
            camera.stopPreview();
            camera.setDisplayOrientation(result);
            camera.startPreview();
        } else
        {
            camera.setDisplayOrientation(result);
        }

    }// end setCameraDisplayOrientation

    public static int getCameraDisplayOrientation(Activity activity,
            int cameraId, android.hardware.Camera camera)
    {
        android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
        android.hardware.Camera.getCameraInfo(cameraId, info);
        int rotation = activity.getWindowManager().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;
    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();

        Log.d("CameraPage-onDestroy", "Called onDestroy");

    }

}// end CameraPage

CameraView.java

package model;

import java.io.IOException;

import pages.CameraPage;

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




/** A basic Camera preview class */
public class CameraView extends SurfaceView implements SurfaceHolder.Callback
{
    private SurfaceHolder mHolder;
    private Camera mCamera;
    private Activity activity;

    public CameraView(Context context)
    {
        super(context);
        Log.d("CameraView-default constructor",
                "Chiamato uno dei due default constructors");
    }

    public CameraView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        Log.d("CameraView-default constructor",
                "Chiamato uno dei due default constructors");
    }

    public CameraView(Context context, Camera camera, Activity activity)
    {
        super(context);
        Log.d("CameraView-constructor",
                "Inizializzo la classe con la camera e il context");

        this.activity = activity;

        mCamera = camera;

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.addCallback(this);
        // deprecated setting, but required on Android versions prior to 3.0
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder)
    {
        Log.d("CameraView-surfaceCreated",
                "La superfice è stata creata, setto la preview della camera sulla superficie");

        // The Surface has been created, now tell the camera where to draw the preview.
        try
        {
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e)
        {
            Log.d("CameraView-surfaceCreated", "Error setting camera preview: "
                    + e.getMessage());
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder)
    {
        Log.d("CameraView-surfaceDestroyed",
                "Distrutta superficie della preview");
        // Take care of releasing the Camera preview in your activity.
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
    {
        Log.d("CameraView-surfaceChanged",
                "Gestisco i cambiamenti nella superficie che ospita la camera");
        // 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
            Log.d("CameraView-surfaceChanged", "Preview surface doesn't exist");
            return;
        }

        try
        {
            CameraPage.setCameraDisplayOrientation(activity,
                    Camera.CameraInfo.CAMERA_FACING_BACK, mCamera);
        } catch (Exception e)
        {
            Log.d("CameraView-surfaceChanged",
                    "Exception reorienting the camera " + e);
        }

    }// end surfaceChanged
}// end CameraView

camera_surface.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

    <FrameLayout
        android:id="@+id/camera_preview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >

    </FrameLayout>

    <ImageButton
        android:id="@+id/camera_surface_buttonRecordStop"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="10dp"
        android:adjustViewBounds="true"
        android:background="@null"
        android:contentDescription="@string/action"
        android:scaleType="fitCenter"
        android:src="@drawable/iconarecord" />

</RelativeLayout>

活动已经过Android 2.3.6到4.3的测试。如果您发现任何问题或有任何建议,请告诉我们!

答案 1 :(得分:0)

如果您的问题与轮换变量相关联,您可以考虑查看this link。离开该链接的主要区别是创建了WindowManager对象,然后用于获取旋转。这个看似很小的差异是我的代码工作和不工作之间的差异。

您可以简单地说Camera.CameraInfo info = new Camera.CameraInfo();Camera.getCameraInfo(...);

我很好奇您在CameraInfo.CAMERA_FACING_BACK中指定android.hardware.Camera.getCameraInfo(CameraInfo.CAMERA_FACING_BACK, info);的原因我觉得您可以致电info.facing来取代int

我希望在链接和我的建议/查询之间找到正确的答案!