How to use matrix camera preview left and right reverse on android? - android

I want camera preview left and right reverse,
and I search for google, answer is use Matrix
is it right answer?
first, my source.
MainActivity.class
private Agen agen = null;
protected static Activity mainActivity = null;
#Override
protected void onCreate(final Bundle savedInstanceState) {
agen = new Agen();
agen.CameraSetting();
}
public static Activity getMainActivity() {
return mainActivity;
}
Agen.class
private CamLiveView camLiveView;
private final FrameLayout liveFrame;
private final Context context;
public Agen() {
Activity activity = MainActivity.getMainActivity();
context = activity;
liveFrame = (FrameLayout) activity.findViewById(R.id.liveview);
public boolean CameraSetting() {
boolean state = false;
try {
LiveCam livecam = CamManage.getInstance();
camLiveView = new CamLiveView(context, livecam, this);
if (liveFrame != null)
liveFrame.addView(camLiveView);
state = true;
} catch (Exception e) {
e.printStackTrace();
} return state;
}
CamManage.class
private static Camera mCamera = null;
public static LiveCam getInstance() {
if (mCamera == null) {
int cameras = Camera.getNumberOfCameras();
mCamera = Camera.open(0);
if (mCamera != null) {
mCamera.lock();
}
} else {
}
return getLiveCam();
}
getLiveCam
static private LiveCam getLiveCam() {
LiveCam livecam = new LiveCam() ;
Camera.Parameters params = mCamera.getParameters();
liveCam.preSize = params.getPreviewSize();
liveCam.preFormat = params.getPreviewFormat();
liveCam.camera = mCamera;
return liveCam;
}
LiveCam.class
public class LiveCam {
public Camera camera;
public Camera.Size preSize;
public int preFormat;
}
this my source.
but I don't know where use matrix part.
in other words, I want camera preview left and right reverse.
please advice for me
thanks.
add
public class CamLiveView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camer mCamera;
private int preWidth;
private int preHeight;
private int preFormat;
private boolean playing = false;
public CamLiveView(Context context, LiveCam livecam) {
super(context);
mHolder = getHolder();
mHolder.addCallback(this);
mCamera = livecam.camera;
preWidth = livecam.preSize.width;
preHeight = livecam.preSize.height;
preFormat = livecam.previewFormat;
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
cameraPlay();
}
public boolean cameraPlay() {
if (mHolder == null)
return false;
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
playing = true;
} catch (Exception e) {
return false;
} return true;
}

Related

Xamarin - Droid (SurfaceView)

I have an app for face detection, thus I need to open the camera when the app is launched, I have looked into the similar problems yet I can't find a solution to the problem I currently have now. The problem is that the function SurfaceCreated(ISurfaceHolder holder) is not being called, thus, the camera is not being launched. Thanks for the response
CameraLayout.axml
<AppName.Droid.CameraControls.CameraLiveStream
android:id="#+id/cameraPreview"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</App2.Droid.CameraControls.CameraLiveStream>
The CameraLiveStream.cs inherits ViewGroup, ISurfaceHolderCallback2
CameraLiveStream.cs
private Context mContext;
private SurfaceView mSurfaceView;
private bool mStartRequested;
private bool mSurfaceAvailable;
private CameraSource mCameraSource;
public CameraLiveStream(Context context, IAttributeSet attrs) : base(context, attrs)
{
mContext = context;
mStartRequested = false;
mSurfaceAvailable = false;
mSurfaceView = new SurfaceView(context);
mSurfaceView.Holder.AddCallback(this);
AddView(mSurfaceView);
}
#region camera-surface
public void SurfaceChanged(ISurfaceHolder holder, [GeneratedEnum] Format format, int width, int height)
{
throw new NotImplementedException();
}
public void SurfaceCreated(ISurfaceHolder holder)
{
mSurfaceAvailable = true;
try
{
StartCameraIfReady();
}
catch
{
Log.Error("CameraLiveStream", "Error when starting camera");
}
}
Here's my MainActivity.cs OnCreate()
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.CameraLayout);
mPreview = FindViewById<CameraLiveStream>(Resource.Id.cameraPreview);
if (ActivityCompat.CheckSelfPermission(this, Manifest.Permission.Camera) == Permission.Granted)
{
CreateCameraSource();
}
else
{
RequestCameraPermissions();
}
}
CreateCameraSource Function
private void CreateCameraSource()
{
var context = Application.Context;
FaceDetector detector = new FaceDetector.Builder(context)
.SetClassificationType(ClassificationType.All)
.Build();
if (!detector.IsOperational)
{
Log.Warn("MainActivity", "Face detector dependencies are not yet available.");
}
mCameraSource = new CameraSource.Builder(context, detector)
.SetRequestedPreviewSize(200, 200)
.SetFacing(CameraFacing.Back)
.SetRequestedFps(30.0f)
.Build();
}
StartCameraSource Function
private void StartCameraSource()
{
int code = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(
this.ApplicationContext);
if (code != ConnectionResult.Success)
{
Dialog dlg =
GoogleApiAvailability.Instance.GetErrorDialog(this, code, RC_HANDLE_GMS);
dlg.Show();
}
if (mCameraSource != null)
{
try
{
mPreview.StartCamera(mCameraSource);
}
catch (System.Exception e)
{
Log.Error("MainActivity-StartCameraSource", "Unable to start camera source.", e);
mCameraSource.Release();
mCameraSource = null;
}
You are creating a SurfaceView with no layout params and thus its size it 0,0 and thus a surface would never need to be created.
Full screen:
var layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent);
var view = new SurfaceView(someContext)
{
LayoutParameters = layoutParams
};
Or Parent the SurfaceView to a container in your layout
var aViewGroup = FindViewById<ViewGroup>(Resource.Id.SomeContainer);
aViewGroup.AddView(yourSurfaceView, new LayoutParams(MATCH_PARENT, WRAP_CONTENT));
Fixed the issue:
I have created another type of view underneath my
AppName.Droid.CameraControls.CameraLiveStream
So it became like this
<AppName.Droid.Camera.Controls.CameraLiveStream>
<AppName.Droid.Camera.Controls.Overlay>
</AppName.Droid.Camera.Controls.Overlay>
</AppName.Droid.Camera.Controls.CameraLiveStream>
Wherein I the overlay inherited the View which implements the width/height of the view.
public int mPrevWidth { get => mWidth; set => mWidth = value; }
public int mPrevHeight { get => mHeight; set => mHeight = value; }
public float mPrevWidthScaleFactor { get => mWidthScaleFactor; set => mWidthScaleFactor = value; }
public float mPrevHeightScaleFactor { get => mHeightScaleFactor; set => mHeightScaleFactor = value; }
public CameraFacing mCameraFacing { get => mFacing; set => mFacing = value; }

onfocuschanged never gets called for surfaceview (android)

In my android app i have activity containing a surfaceview. I want to start the surfaceview thread when the surfaceview/activity is visible to user. I have tried starting the thread in OnSurfaceCreated. That works but on some mobiles(samsung) The activity takes many seconds to become visible.The screen turns black when i resume activity. So i googled and found that when a view becomes visible onFocusChanged is called. I tried implementing OnFocusChanged in surfaceview but it is never called. below is my surfaceview class.
public class ImageSurface extends SurfaceView implements SurfaceHolder.Callback {
private DrawThread drawThread;
private SurfaceHolder sHolder;
private ImageHolder imageHolder;
Bitmap mybit;
Bitmap orgiBitmap;// ;)
int message;
Context context;
private String valMagField;
public ImageSurface(Context context, AttributeSet attrs) {
super(context, attrs);
this.context=context;
SurfaceHolder holder = getHolder();
holder.addCallback(this);
setFocusable(true);
clearFocus();
drawThread = new DrawThread(context);
}
public void setImageHolder(ImageHolder imageHolder){
this.imageHolder = imageHolder;
}
public void setBitmap(String filePath){
}
public void resume(){
drawThread.resumeThread();
}
#Override
public void onFocusChanged(boolean focus,int direction,Rect rect){
super.onFocusChanged(focus, direction, rect);
Log.d("in focus changed","onfocuschanged"+System.currentTimeMillis());
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
drawThread.setSurfaceSize(width, height);
resume();
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
long startTime, stopTime;
startTime = System.currentTimeMillis();
sHolder = holder;
drawThread.setRunning(true);
if(drawThread.getState()==Thread.State.NEW){
drawThread.start();
}
if(drawThread.getState()==Thread.State.TERMINATED){
drawThread = new DrawThread(context);
drawThread.setRunning(true);
drawThread.start();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
drawThread.pauseThread();
}
class DrawThread extends Thread{
int value=0;
private Boolean drun;
int valSize =30;
Context context;
private int sHeight , sWidth;
int lastmessage;
boolean threadPaused= false;
public DrawThread(Context context){
drun = false;
this.context = context;
}
public void pauseThread(){
synchronized(this){
threadPaused = true;
this.notify();
}
}
public void resumeThread(){
synchronized(this){
threadPaused = false;
this.notify();
}
}
public void setRunning(Boolean run){
drun = run;
}
public boolean isRunning(){
return drun;
}
public void setSurfaceSize(int width , int height){
sWidth = width;
sHeight = height;
}
#Override
public void run(){
while(drun){
Canvas c = null;
//Log.d("yes","thread is running");
try{
synchronized(this){
if(threadPaused)
try {
this.wait();
} catch (InterruptedException e) {
Log.d("in wait of surface view thread","error"+e.toString());
}
}
c = sHolder.lockCanvas(null);
synchronized(sHolder){
updateCanvas(c);
}
}finally {
if(c!=null){
sHolder.unlockCanvasAndPost(c);
}
}
}
}
private void updateCanvas(Canvas canvas){
try{
if(imageHolder.dispBit!= null){
int x=(sWidth-imageHolder.dispBit.getWidth())/2,y=(sHeight-imageHolder.dispBit.getHeight())/2;
imageHolder.applyEffects();
if(canvas!=null)
canvas.drawBitmap(imageHolder.dispBit, x,y,null);
}
else if(imageHolder!=null)
imageHolder.setDisplaySize(sWidth, sHeight);
}catch(Exception e){
e.printStackTrace();
}
}
}
}

SurfaceView not working inside PopupWindow

I gonna show a preview using a PopupWindow based on AirView feature of Samsung SPen
But the problem is that the SurfaceView is not created and non of the SurfaceHolder.Callback methods are called.
The surface region becomes transparent when the popup is displayed because the surface is not created at all.
SurfaceView is not created and is transparent:
HoverPreview:
public class HoverPreview extends LinearLayout implements View.OnHoverListener, SurfaceHolder.Callback {
private static final String TAG = "HoverPreview";
private SurfaceHolder mHolder = null;
View mAnchorView = null;
String videoPath;
int position;
private boolean IsMediaPlayerReady = false;
private MediaPlayer mMediaPlayer;
private SurfaceView mSurfaceView;
Context context;
public HoverPreview(Context context, String videoPath, int position) {
super(context);
this.videoPath = videoPath;
this.position = position;
setupLayout(context);
}
public HoverPreview(Context context, AttributeSet attrs) {
super(context, attrs);
setupLayout(context);
}
public HoverPreview(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setupLayout(context);
}
private void setupLayout(Context context) {
this.context = context;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.media_browser_hover, this);
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
Log.d(TAG, "HoverSurface created");
final Surface surface = surfaceHolder.getSurface();
if (surface == null) return;
if (!surface.isValid()) return;
mHolder = surfaceHolder;
mMediaPlayer = new MediaPlayer();
try {
mMediaPlayer.setDataSource(videoPath);
} catch (IOException e) {
e.printStackTrace();
}
mMediaPlayer.setDisplay(mHolder);
mAnchorView.setTag(mMediaPlayer);
mMediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
#Override
public void onVideoSizeChanged(MediaPlayer mediaPlayer, int i, int i2) {
mHolder.setFixedSize(i, i2);
}
});
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
Log.d(TAG, "MediaPlayer preview is prepared");
IsMediaPlayerReady = true;
if (mMediaPlayer != null && IsMediaPlayerReady) {
if (position > 0)
mMediaPlayer.seekTo(position);
mMediaPlayer.start();
}
}
});
Log.d(TAG, "MediaPlayer is created");
try {
mMediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
Log.d(TAG, "HoverSurface changed");
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
Log.d(TAG, "HoverSurface destroyed");
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer.release();
//thumbnailImageView.setTag(null);
}
}
public void setAnchorView(View view) {
mAnchorView = view;
}
#Override
public boolean onHover(View view, MotionEvent motionEvent) {
try {
if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_ENTER) {
Log.d(TAG, "ACTION_HOVER_ENTER");
mSurfaceView = (SurfaceView) findViewById(R.id.media_browser_hoverSurfaceView);
mHolder = mSurfaceView.getHolder();
if (mHolder != null) {
mHolder.addCallback(this);
}
} else if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
Log.d(TAG, "ACTION_HOVER_EXIT");
if (mAnchorView.getTag() != null) {
MediaPlayer mMediaPlayer = (MediaPlayer) mAnchorView.getTag();
mMediaPlayer.stop();
mMediaPlayer.release();
mAnchorView.setTag(null);
}
}
} catch (Exception e) {
Log.e(TAG, e.getMessage() + Utils.toString(e.getStackTrace()));
}
return false;
}
}
The code to show the preview:
final PopupWindow popupWindow = new PopupWindow(context);
final HoverPreview hoverPreview = new HoverPreview(context, videoPath, 0);
hoverPreview.setAnchorView(thumbnailImageView);
thumbnailImageView.setOnHoverListener(new View.OnHoverListener() {
#Override
public boolean onHover(View view, MotionEvent motionEvent) {
hoverPreview.onHover(view, motionEvent);
if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_ENTER) {
popupWindow.setContentView(hoverPreview);
popupWindow.setWidth(600);
popupWindow.setHeight(400);
popupWindow.showAtLocation(thumbnailImageView, ToolHoverPopup.Gravity.NO_GRAVITY, 10, 10);
Log.d(TAG, "Manual Hover Enter");
} else if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
Log.d(TAG, "Manual Hover Exit");
if (popupWindow != null)
popupWindow.dismiss();
}
return true;
});
Here's my complete working solution:
I borrowed some code from ToolHoverPopup class from SPen library, also I customized for this special popup so that nothing is created or inflated until the actual hovering is happened so that we don't consume resources for enabling such a preview in lists.
We need to have our preview attached to a Window so because of this we have to manage all the underlying job of positioning which is normally done by PopupWindow, so I completely removed the dependency on the PopupWindow and now my HoverPreview class is fully working and manages all the jobs, also it has the ability to determine the Hover Detection delay in milliseconds.
Screenshot (SurfaceView is created)
Usage: (Since the layout contains SurfaceView and is resource intensive, I manually trigger onHover event so that the real surface creation is performed only when the real hover is performed. Also by this, I don't create any object of HoverPreview before it's needed)
thumbnailImageView.setOnHoverListener(new View.OnHoverListener() {
#Override
public boolean onHover(View view, MotionEvent motionEvent) {
HoverPreview hoverPreview;
if (thumbnailImageView.getTag() == null) {
hoverPreview = new HoverPreview(context, getActivity().getWindow(), videoPath, 0);
hoverPreview.setHoverDetectTime(1000);
thumbnailImageView.setTag(hoverPreview);
} else
hoverPreview = (HoverPreview) thumbnailImageView.getTag();
hoverPreview.onHover(null, motionEvent);
if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_EXIT)
thumbnailImageView.setTag(null);
return true;
}
});
HoverPreview:
public class HoverPreview extends LinearLayout implements View.OnHoverListener, SurfaceHolder.Callback {
private static final int MSG_SHOW_POPUP = 1;
private static final int MSG_DISMISS_POPUP = 2;
private static final int HOVER_DETECT_TIME_MS = 300;
private static final int POPUP_TIMEOUT_MS = 60 * 1000;
protected int mHoverDetectTimeMS;
private static final String TAG = "HoverPreview";
private SurfaceHolder mHolder = null;
String videoPath;
int position;
private boolean IsMediaPlayerReady = false;
private MediaPlayer mMediaPlayer;
private SurfaceView mSurfaceView;
Context context;
private HoverPopupHandler mHandler;
Window window;
public HoverPreview(Context context, Window window, String videoPath, int position) {
super(context);
this.mHoverDetectTimeMS = HOVER_DETECT_TIME_MS;
this.videoPath = videoPath;
this.position = position;
this.window = window;
setupLayout(context);
}
private void setupLayout(Context context) {
this.context = context;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rootView = inflater.inflate(R.layout.media_browser_hover, this);
mSurfaceView = (SurfaceView) findViewById(R.id.media_browser_hoverSurfaceView);
}
View rootView;
#Override
protected void onFinishInflate() {
super.onFinishInflate();
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
Log.d(TAG, "HoverSurface created");
final Surface surface = surfaceHolder.getSurface();
if (surface == null) return;
if (!surface.isValid()) return;
mHolder = surfaceHolder;
mMediaPlayer = new MediaPlayer();
try {
mMediaPlayer.setDataSource(videoPath);
} catch (IOException e) {
e.printStackTrace();
return;
}
mMediaPlayer.setDisplay(mHolder);
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
Log.d(TAG, "MediaPlayer preview is prepared");
IsMediaPlayerReady = true;
int videoWidth = mMediaPlayer.getVideoWidth();
int videoHeight = mMediaPlayer.getVideoHeight();
Point size = new Point();
int screenHeight = 0;
int screenWidth = 0;
Display display = getDisplay();
display.getSize(size);
screenWidth = size.x - (350 + 30); // margin + padding
screenHeight = size.y;
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mSurfaceView.getLayoutParams();
lp.width = screenWidth;
lp.height = (int) (((float) videoHeight / (float) videoWidth) * (float) screenWidth);
mSurfaceView.setLayoutParams(lp);
if (mMediaPlayer != null && IsMediaPlayerReady) {
if (position > 0)
mMediaPlayer.seekTo(position);
mMediaPlayer.start();
findViewById(R.id.media_browser_hoverRootFrameLayout).setVisibility(VISIBLE);
}
}
});
Log.d(TAG, "MediaPlayer is created");
try {
mMediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
Log.d(TAG, "HoverSurface changed");
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
Log.d(TAG, "HoverSurface destroyed");
try {
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer.release();
}
} catch (Exception e) {
}
}
#Override
public boolean onHover(View view, MotionEvent motionEvent) {
try {
if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_ENTER) {
Log.d(TAG, "ACTION_HOVER_ENTER");
show(); // checks the timing
} else if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
Log.d(TAG, "ACTION_HOVER_EXIT");
dismiss();
}
} catch (Exception e) {
Log.e(TAG, e.getMessage() + Utils.toString(e.getStackTrace()));
}
return false;
}
/**
* Sets the time that detecting hovering.
*
* #param ms The time, milliseconds
*/
public void setHoverDetectTime(int ms) {
mHoverDetectTimeMS = ms;
}
public void dismiss() {
dismissPopup();
}
private void dismissPopup() {
// remove pending message and dismiss popup
getMyHandler().removeMessages(MSG_SHOW_POPUP);
getMyHandler().removeMessages(MSG_DISMISS_POPUP);
try {
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer.release();
}
} catch (Exception e) {
}
if (getParent() != null)
((ViewGroup) getParent()).removeView(this);
}
private Handler getMyHandler() {
if (mHandler == null)
mHandler = new HoverPopupHandler();
return mHandler;
}
public void show() {
// send message to show.
if (getMyHandler().hasMessages(MSG_SHOW_POPUP)) {
return;
// getHandler().removeMessages(MSG_SHOW_POPUP);
}
getMyHandler().sendEmptyMessageDelayed(MSG_SHOW_POPUP, mHoverDetectTimeMS);
}
private void showPopup() {
if (getParent() == null) {
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.CENTER_VERTICAL;
params.x = 350;
window.addContentView(this, params);
}
mHolder = mSurfaceView.getHolder();
if (mHolder != null) {
mHolder.addCallback(this);
}
}
;
private class HoverPopupHandler extends Handler {
#Override
public void handleMessage(Message msg) {
// if (DEBUG)
// android.util.Log.e(TAG, "handleMessage : " + ((msg.what == MSG_SHOW_POPUP) ? "SHOW" : "DISMISS"));
switch (msg.what) {
case MSG_SHOW_POPUP:
showPopup();
sendEmptyMessageDelayed(MSG_DISMISS_POPUP, POPUP_TIMEOUT_MS);
break;
case MSG_DISMISS_POPUP:
dismissPopup();
break;
}
}
}
}

How to block the orientation of a particular part in a layout, the other part should change with orientation?

I have created a video capture app using surface-view, I have a header and footer bar in this layout. I want to block the orientation change of only surface view, while the header and footer should change with orientation .
public class MainActivity extends Activity implements SurfaceHolder.Callback{
private SurfaceHolder surfaceHolder;
private SurfaceView surfaceView;
public MediaRecorder mrec = new MediaRecorder();
private ImageButton startRecording = null;
//private Button stopRecording = null;
File video;
private Camera mCamera;
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i(null , "Video starting");
startRecording = (ImageButton)findViewById(R.id.buttonstart);
mCamera = Camera.open();
surfaceView = (SurfaceView) findViewById(R.id.surface_camera);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
menu.add(0, 0, 0, "StartRecording");
menu.add(0, 1, 0, "StopRecording");
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case 0:
try {
startRecording();
} catch (Exception e) {
String message = e.getMessage();
Log.i(null, "Problem Start"+message);
mrec.release();
}
break;
case 1: //GoToAllNotes
mrec.stop();
mrec.release();
mrec = null;
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
public void StrBtnClick(View view) throws IOException
{
startRecording();
}
protected void startRecording() throws IOException
{
mrec = new MediaRecorder(); // Works well
mCamera.unlock();
mrec.setCamera(mCamera);
mrec.setPreviewDisplay(surfaceHolder.getSurface());
mrec.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mrec.setAudioSource(MediaRecorder.AudioSource.MIC);
mrec.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
mrec.setPreviewDisplay(surfaceHolder.getSurface());
mrec.setOutputFile("/sdcard/Myvideo.3gp");
mrec.prepare();
mrec.start();
}
protected void stopRecording() {
mrec.stop();
mrec.release();
mCamera.release();
}
private void releaseMediaRecorder(){
if (mrec != null) {
mrec.reset(); // clear recorder configuration
mrec.release(); // release the recorder object
mrec = null;
mCamera.lock(); // lock camera for later use
}
}
private void releaseCamera(){
if (mCamera != null){
mCamera.release(); // release the camera for other applications
mCamera = null;
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
if (mCamera != null){
Parameters params = mCamera.getParameters();
mCamera.setParameters(params);
}
else {
Toast.makeText(getApplicationContext(), "Camera not available!", Toast.LENGTH_LONG).show();
finish();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
mCamera.release();
}
}
I would remove the onLayout from your Activity and add it to the SurfaceView, should work like this:
private CustomSurfaceView surfaceView; //line 4.
class CustomSurfaceView extends SurfaceView { //at the end of your Activity
public CSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
}
}
This way your SurfaceView will not be affected by any layout changes.

Using Camera on android

In my library project I have the following code to initialize the camera, and start previewing.
public class CameraView {
private SurfaceView preview;
private SurfaceHolder previewHolder;
private Camera camera;
private boolean activeCamera;
private boolean cameraConfigured;
private Activity activity;
private final static int NINTY_DEGREES = 90;
public CameraView(Activity activity) {
this.activity = activity;
View rootView;
LayoutInflater inflater = activity.getLayoutInflater();
rootView = inflater.inflate(R.layout.layout_cameraview, null);
preview = (SurfaceView) rootView.findViewById(R.id.surfaceView);
previewHolder = preview.getHolder();
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
cameraConfigured = false;
}
private void initializeCamera(int w, int h) {
if(camera != null && previewHolder.getSurface() != null) {
try
{
camera.setPreviewDisplay(previewHolder);
}
catch(Exception e)
{
Log.e("Camera: ", e.getMessage());
}
if(!cameraConfigured) {
Camera.Parameters params = camera.getParameters();
Camera.Size size = getBestPreviewSize(w, h, params);
if(size != null) {
params.setPreviewSize(size.width, size.height);
cameraConfigured = true;
}
}
}
}
public void startCamera() {
camera = Camera.open();
previewHolder.addCallback(surfaceCallback);
}
public void stopCamera() {
stopPreviewingOnDisplay();
}
public void takePicture() {
View rootView;
LayoutInflater inflater = activity.getLayoutInflater();
rootView = inflater.inflate(R.layout.layout_cameraview, null);
Button capture = (Button) rootView.findViewById(R.id.capture);
capture.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.e("CameraView: ", "Capture button pressed!");
}
});
}
private void startPreviewingOnDisplay() {
if(camera != null) {
camera.setDisplayOrientation(NINTY_DEGREES);
camera.startPreview();
activeCamera = true;
}
}
private void stopPreviewingOnDisplay() {
if(camera != null && activeCamera) {
camera.stopPreview();
activeCamera = false;
}
}
private SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
initializeCamera(width, height);
startPreviewingOnDisplay();
Log.d("CameraView: ", "SurfaceChanged");
}
};
private Camera.Size getBestPreviewSize(int w, int h, Camera.Parameters params) {
Camera.Size result = null;
for(Camera.Size size : params.getSupportedPreviewSizes()) {
if(size.width < w && size.height <= h) {
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);
}
}
The usage of this class:
public class History extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
......
camera = new CameraView(this);
}
#Override
public void onResume() {
super.onResume();
Log.i("History.class", "onResume called!");
camera.startCamera();
}
#Override
public void onPause() {
super.onPause();
camera.stopCamera();
}
}
I've debugged the code, and I notice that the camera object is being intitalized, but there is nothing appearing on the screen, it should have previewed the camera. Could anyone see whats wrong with this approach?
Thanks.

Categories

Resources