如何为前置摄像头添加开关按钮?

Posted

技术标签:

【中文标题】如何为前置摄像头添加开关按钮?【英文标题】:Adding a Switch Button for Front Camera how? 【发布时间】:2014-06-16 02:25:06 【问题描述】:

在添加按钮或 ImageView 方面需要帮助,以便我可以切换到前置摄像头,请帮助!!! 任何人都可以帮助我并快速尝试添加它,但我一直在切换相机上收到错误。我尝试实现一个独立于前置摄像头的类的意图,但是当切换回后置摄像头时,屏幕将保持黑色。如果有人可以提供帮助,我想以正确的方式实现前置摄像头,谢谢。如果可以的话,请将前置摄像头源代码添加到我的项目中,谢谢。

ImageView cameraFront;

private int width, height;

private int sdkVersion;

private int timeCount = 0;

private int PORTRAIT = 0;

private int PORTRAIT_REV = 1;

private int LANDSCAPE_RIGHT = 2;

private int LANDSCAPE_LEFT = 3;

private SurfaceView surface;

private SurfaceHolder surfaceHolder;

private MediaRecorder videoRecorder;

private Button recordBtn;

private TextView timeView;

private String videoPath;

private Timer autoStopTimer;

private Camera mCamera;

private Camera.Parameters parameters;

private List<Size> supportedSizes = null;

private SensorManager sensorManager = null;

private boolean isRecording = false;

boolean changeOrientation = false;

int mDetected_Orientention = 0;

Tosty toast;




@Override
public void onCreate(Bundle savedInstanceState) 

    super.onCreate(savedInstanceState);

    requestWindowFeature(Window.FEATURE_NO_TITLE);

    try 

        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);

        sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);

        setContentView(R.layout.video_recorder);

        videoPath = getIntent().getStringExtra("videoPath");

        width = getIntent().getIntExtra("Width", 320);

        height = getIntent().getIntExtra("Height", 240);

        WindowManager mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

        Display mDisplay = mWindowManager.getDefaultDisplay();

        this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

        toast = new Tosty(VideoRecorder.this);

        recordBtn = (Button) findViewById(R.id.recordBtn);

        recordBtn.setOnClickListener(this);

        surface = (SurfaceView) findViewById(R.id.surfaceView);

        surfaceHolder = surface.getHolder();

        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        timeView = (TextView) findViewById(R.id.timeView);

        timeView.setTextColor(Color.WHITE);

        initVideoRecording();

        initView();

        setListener();

    

    catch (Exception e) 

        // TODO: handle exception

        e.printStackTrace();

    



public void initView() 

    cameraFront = (ImageView) findViewById(R.id.cameraSwitch1);



public void setListener() 

    cameraFront.setOnClickListener(this);




@Override
protected void onResume() 

    super.onResume();

    (new Thread(new Runnable() 

        @Override
        public void run() 

            try 

                Thread.sleep(100);

             

            catch (InterruptedException e) 

                e.printStackTrace();

            

            try 

                initVideoRecording();

                //finish();

             

            catch (Exception e) 

                // TODO Auto-generated catch block

                e.printStackTrace();

            

        

    )).start();



@Override
public void onDestroy() 

    super.onDestroy();
    // Stop sensorManager

    sensorManager.unregisterListener(VideoRecorder.this);

    if (autoStopTimer != null) 

        autoStopTimer.cancel();

        autoStopTimer.purge();

        autoStopTimer = null;
    

    try 

        stopVideoRecording();

     

    catch (Exception e) 

        // TODO Auto-generated catch block

    



@Override
public void onPause() 

    super.onPause();

    if (autoStopTimer != null) 

        autoStopTimer.cancel();

        autoStopTimer.purge();

        autoStopTimer = null;

    

    try 

        stopVideoRecording();

     
    catch (Exception e) 

        // TODO Auto-generated catch block

    



@Override
public boolean onKeyDown(int keyCode, KeyEvent event) 

    if (keyCode == KeyEvent.KEYCODE_BACK) 

        // toast.showToast("Back button is pressed");

        sensorManager.unregisterListener(VideoRecorder.this);

        finish();

        return true;
     

    else if (keyCode == KeyEvent.KEYCODE_HOME) 

        try 

            stopVideoRecording();

        

        catch (Exception e) 

            // TODO Auto-generated catch block

            e.printStackTrace();

        

    

    return super.onKeyDown(keyCode, event);


public void onBackPressed() 
    startActivity(new Intent(this, VideoPlay.class)
    .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK));
    //overridePendingTransition(R.anim.left_right, R.anim.right_left);
    finish();
    return;



@Override
public void onClick(View v) 

    // TODO Auto-generated method stub

    switch (v.getId()) 

    case R.id.cameraSwitch1:



        Intent intent = new Intent(VideoRecorder.this, Cemara.class);

        //intent.putExtra("android.intent.extras.CAMERA_FACING", 1);

        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);

        //intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);

        finish();

        startActivity(intent);

        break;

    

    if (v == recordBtn) 

        try 

            if (isRecording) 

            if (autoStopTimer != null) 

                autoStopTimer.cancel();

                autoStopTimer.purge();

                autoStopTimer = null;

            

            try 

                stopVideoRecording();

            

            catch (Exception e) 

                // TODO Auto-generated catch block

            

            setResult(RESULT_OK);

            finish();

             

            else 

                startVideoRecording();

                autoStopTimer = new Timer();        

                autoStopTimer.schedule(new TimerTask() 

                public void run() 

                    timeCount++;

                    runOnUiThread(new Runnable() 

                        public void run() 

                            timeView.setText(String.format("00:%02d", timeCount));

                            if (timeCount == 31) 

                                try 

                                    stopVideoRecording();

                                 

                                catch (Exception e) 
                                    // TODO Auto-generated catch block

                                

                                setResult(RESULT_OK);

                                finish();

                            

                        

                    );

                    if (timeCount == 31) 

                        autoStopTimer.cancel();

                        autoStopTimer = null;

                    

                

                , 1000, 1000);

            

        

        catch (Exception e) 
        // TODO: handle exception
        e.printStackTrace();

        

    



private void initVideoRecording() 

    try 

        if (videoRecorder != null) 

            videoRecorder.stop();

            videoRecorder.release();

            videoRecorder = null;

        

        if (mCamera != null) 

            mCamera.reconnect();

            mCamera.stopPreview();

            mCamera.release();

            mCamera = null;

        

        sdkVersion = Build.VERSION.SDK_INT;

        android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();

        android.hardware.Camera.getCameraInfo(0, info);

        mCamera = Camera.open();

        //parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);

        //parameters.set("focus-mode", "continuous-video");

        //mCamera.setParameters(parameters);

        // Camera setup is based on the API Camera Preview demo
        mCamera.setPreviewDisplay(surfaceHolder);

        parameters = mCamera.getParameters();

        if (sdkVersion <= 8) 

            supportedSizes = parameters.getSupportedVideoSizes();

        

        // parameters.setRotation(90);

        mCamera.setParameters(parameters);

        // check the intial orientation depending on rotation
        int rotation = getWindowManager().getDefaultDisplay().getRotation();

        int nCurrentOrientation = _getScreenOrientation();

        if (nCurrentOrientation == Configuration.ORIENTATION_PORTRAIT && rotation == Surface.ROTATION_0) 

            System.out.println("We are in portrait mode");
            // parameters.setRotation(0);

            mCamera.setDisplayOrientation(90);

         

        else if (nCurrentOrientation == Configuration.ORIENTATION_LANDSCAPE && rotation == Surface.ROTATION_90) 

            System.out.println("We are in landscape mode");

            // parameters.setRotation(0);

            mCamera.setDisplayOrientation(0);

         

        else if (nCurrentOrientation == Configuration.ORIENTATION_LANDSCAPE && rotation == Surface.ROTATION_270) 

            System.out.println("Reverse Landscape Mode");

            mCamera.setDisplayOrientation(180);

         

        else if (nCurrentOrientation == Configuration.ORIENTATION_PORTRAIT && rotation == Surface.ROTATION_180) 

            System.out.println("Reverse potrait mode");

            mCamera.setDisplayOrientation(90);

        

        else

            mCamera.setDisplayOrientation(90);

        mCamera.startPreview();

        mCamera.unlock();

     

    catch (Exception e) 

        e.printStackTrace();

    



private void stopVideoRecording() throws Exception 

    try 

    if (videoRecorder != null) 

        videoRecorder.stop();

        videoRecorder.release();

        videoRecorder = null;

    

    if (mCamera != null) 

        mCamera.reconnect();

        mCamera.stopPreview();

        mCamera.release();

        mCamera = null;

    



    catch (Exception e) 

        // TODO: handle exception

        e.printStackTrace();

    



private void startVideoRecording() 

    try 

    if (videoRecorder == null) 

        videoRecorder = new MediaRecorder();

    

    videoRecorder.setCamera(mCamera);

    videoRecorder.setAudiosource(MediaRecorder.AudioSource.MIC);

    videoRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

    videoRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);

    videoRecorder.setAudioEncodingBitRate(128000);

    videoRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);

    videoRecorder.setAudioChannels(1);

    videoRecorder.setAudioSamplingRate(48000);

    if (width == 1280) 

        videoRecorder.setVideoEncodingBitRate(22100000);

     

    else if (width == 720) 

        videoRecorder.setVideoEncodingBitRate(3508000);

     

    else 

        videoRecorder.setVideoEncodingBitRate(777000);

    

    videoRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);

    videoRecorder.setVideoFrameRate(30);

    videoRecorder.setVideoSize(width, height);

    videoRecorder.setPreviewDisplay(surfaceHolder.getSurface());

    videoRecorder.setOrientationHint(90);

    if (mDetected_Orientention == PORTRAIT) 

        videoRecorder.setOrientationHint(90);

     

    else if (mDetected_Orientention == PORTRAIT_REV) 

        videoRecorder.setOrientationHint(270);

     

    else if (mDetected_Orientention == LANDSCAPE_RIGHT) 

        videoRecorder.setOrientationHint(180);

    

    try 

        videoRecorder.setOutputFile(videoPath);

        videoRecorder.prepare();

        videoRecorder.start();

        isRecording = true;

        recordBtn.setText("STOP");

     

    catch (Exception e) 

        Log.e("Video", "Failed to prepare and start video recording", e);

        videoRecorder.release();

        videoRecorder = null;

    

    

    catch (Exception e) 

        // TODO: handle exception

        e.printStackTrace();

    



@Override
public void onConfigurationChanged(Configuration newConfig) 

    super.onConfigurationChanged(newConfig);

    try 

    int rotation = getWindowManager().getDefaultDisplay().getRotation();

    int nCurrentOrientation = _getScreenOrientation();

    if (nCurrentOrientation == Configuration.ORIENTATION_PORTRAIT && rotation == Surface.ROTATION_0) 

        System.out.println("We are in portriat mode");

        // parameters.setRotation(0);

        mCamera.setDisplayOrientation(90);

        Log.e("Rotation", "90");

     

    else if (nCurrentOrientation == Configuration.ORIENTATION_LANDSCAPE && rotation == Surface.ROTATION_90) 

        System.out.println("We are in landscape mode");

        // parameters.setRotation(0);

        Log.e("Rotation", "0");

        mCamera.setDisplayOrientation(0);

     

    else if (nCurrentOrientation == Configuration.ORIENTATION_LANDSCAPE && rotation == Surface.ROTATION_270) 

        System.out.println("Reverse Landscape Mode");

        Log.e("Rotation", "180");

        mCamera.setDisplayOrientation(180);

     

    else if (nCurrentOrientation == Configuration.ORIENTATION_PORTRAIT && rotation == Surface.ROTATION_180) 

        System.out.println("Reverse potrait mode");

        Log.e("Rotation", "90");

        mCamera.setDisplayOrientation(90);

    

    

    catch (Exception e) 

        // TODO: handle exception

        e.printStackTrace();

    

    // _doSomeThingWhenChangeOrientation(nCurrentOrientation);



private int _getScreenOrientation() 

    int returnOrientation = 0;

    try 

        returnOrientation = getResources().getConfiguration().orientation;

     

    catch (Exception e) 

        System.out.println(e.getMessage());

    

    return returnOrientation;



int orientation = -1;

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) 

    // TODO Auto-generated method stub



@Override
public void onSensorChanged(SensorEvent sensorEvent) 

    float x = sensorEvent.values[0];

    float y = sensorEvent.values[1];

    if (x >= -5 && x < 5) 

        if (y > 0) 

            mDetected_Orientention = PORTRAIT;

            //Log.e("X", "PORTRAIT");

        

        else 

            mDetected_Orientention = PORTRAIT_REV;

            //Log.e("X", "PORTRAIT_REV");

        

     

    else 

        if (x >= -10 && x < -5) 

            //Log.e("X", "LAND_RIGHT");

            mDetected_Orientention = LANDSCAPE_RIGHT;

         

        else 

            //Log.e("X", "LEND_LEFT");

            mDetected_Orientention = LANDSCAPE_LEFT;

        

    


【问题讨论】:

如果你用谷歌搜索它而不是在这里问而不做研究会更快。 vogella.com/articles/AndroidCamera/article.html 一直在检查谷歌似乎无法在没有错误的情况下弄清楚它我看到其他人的代码只是无法将它添加到我的没有错误。 这很容易说嘿这里有一个链接,就像你所做的一样,但让我们实际看看实际放入我的代码的一些工作。 Cmon Josephus Villarey 向我展示你的编码技巧 不,我不会为您提供代码。我的“教人如何钓鱼”政策的一部分(我现在刚刚制定,只适用于你)。但这里有更多链接供您欣赏。 ***.com/questions/9686203/…***.com/questions/16869272/…***.com/questions/14545031/…***.com/questions/11246497/… 已经看过所有这些,还有你的 vogella 之一。我看不出用一些代码帮助某人有什么问题。整个代码是我从头开始的。就像我的应用程序一样。只需要一些帮助来实现前置摄像头,并且让它变得更难。就像真的,如果你帮不上忙,那就不要回信,因为将链接发送给某人进行编码是非常可悲的,达到我的水平。 【参考方案1】:

这个答案 99% 抄袭自 Commonsware tutorial/code sample。我添加了一个在前后摄像头之间切换的按钮。

PreviewDemo.java

package com.commonsware.android.camera;

import java.io.IOException;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Toast;

public class PreviewDemo extends Activity 

    private static final String TAG = PreviewDemo.class.getSimpleName();
    private SurfaceView preview = null;
    private SurfaceHolder previewHolder = null;
    private Camera camera = null;
    private boolean inPreview = false;
    private boolean cameraConfigured = false;
    int cameraID = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        preview = (SurfaceView) findViewById(R.id.preview);
        previewHolder = preview.getHolder();
        previewHolder.addCallback(surfaceCallback);
        previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    

    @SuppressLint("NewApi")
    @Override
    public void onResume() 
        super.onResume();

        // camera = Camera.open();
        camera = Camera.open(cameraID);
        startPreview();
    

    @Override
    public void onPause() 
        if (inPreview) 
            camera.stopPreview();
        

        camera.release();
        camera = null;
        inPreview = false;

        super.onPause();
    

    private Camera.Size getBestPreviewSize(int width, int height, Camera.Parameters parameters) 
        Camera.Size result = null;

        for (Camera.Size size : parameters.getSupportedPreviewSizes()) 
            if (size.width <= width && size.height <= height) 
                if (result == null) 
                    result = size;
                 else 
                    int resultArea = result.width * result.height;
                    int newArea = size.width * size.height;

                    if (newArea > resultArea) 
                        result = size;
                    
                
            
        

        return (result);
    

    private void initPreview(int width, int height) 
        if (camera != null && previewHolder.getSurface() != null) 
            try 
                camera.setPreviewDisplay(previewHolder);
             catch (Throwable t) 
                Log.e("PreviewDemo-surfaceCallback", "Exception in setPreviewDisplay()", t);
                Toast.makeText(PreviewDemo.this, t.getMessage(), Toast.LENGTH_LONG).show();
            

            if (!cameraConfigured) 
                Camera.Parameters parameters = camera.getParameters();
                Camera.Size size = getBestPreviewSize(width, height, parameters);

                if (size != null) 
                    parameters.setPreviewSize(size.width, size.height);
                    camera.setParameters(parameters);
                    cameraConfigured = true;
                
            
        
    

    private void startPreview() 
        Log.d(TAG, "start preview called");
        if (cameraConfigured && camera != null) 
            Log.d(TAG, "stuff works");
            camera.startPreview();
            inPreview = true;
        
    

    SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() 
        public void surfaceCreated(SurfaceHolder holder) 
            // no-op -- wait until surfaceChanged()
        

        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) 
            initPreview(width, height);
            startPreview();
        

        public void surfaceDestroyed(SurfaceHolder holder) 
            // no-op
        
    ;

    @SuppressLint("NewApi")
    public void switchCamera(View view) 
        Log.d(TAG, "switch called");
        if (inPreview) 
            camera.stopPreview();
        
        camera.release();

        cameraID = (cameraID + 1) % 2;
        camera = Camera.open(cameraID);
        try 
            camera.setPreviewDisplay(previewHolder);
         catch (IOException e) 
            e.printStackTrace();
        
        camera.startPreview();
    

main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_ >

    <android.view.SurfaceView
        android:id="@+id/preview"
        android:layout_
        android:layout_ >
    </android.view.SurfaceView>

    <Button
        android:layout_
        android:layout_
        android:text="switch"
        android:layout_alignParentBottom="true"
        android:onClick="switchCamera" />

</RelativeLayout>

【讨论】:

非常感谢brotha提供的源代码,这是一个巨大的帮助,真正看到这样的东西更好。我实际上是通过使用 mCamera = Camera.open(CameraInfo.CAMERA_FACING_FRONT);这是一段非常漂亮的代码,但唯一的问题是我在来回切换到每个摄像机时出错,并且录制视频的开始按钮不起作用。我肯定会尝试你的代码。这看起来是一个非常好的例子。祝我好运兄弟。 该死的brotha我仍然失败了,我得到了切换,但是每当我从前到后切换时,开始按钮就不再起作用了。不完全确定为什么它不起作用。你想让我的xml文件自己试试。再次感谢兄弟的所有帮助 终极解决方案...:)

以上是关于如何为前置摄像头添加开关按钮?的主要内容,如果未能解决你的问题,请参考以下文章

单击按钮启动前置摄像头

前后摄像头开关

iphone前置取消反向

即使成功切换到前置摄像头,iPhone 仍然显示后置摄像头的视图

将前置摄像头更改为后置摄像头

Android翻盖前置摄像头镜头翻转视频