如何为前置摄像头添加开关按钮?
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文件自己试试。再次感谢兄弟的所有帮助 终极解决方案...:)以上是关于如何为前置摄像头添加开关按钮?的主要内容,如果未能解决你的问题,请参考以下文章