From a2e3dedbe4e09c4299143110bf938956c74ffe6c Mon Sep 17 00:00:00 2001 From: Tim Redfern Date: Mon, 9 Sep 2013 12:38:17 +0100 Subject: integrated working example --- src/com/example/rotorm/CameraActivity.java | 134 ++++++++++++ src/com/example/rotorm/MainActivity.java | 316 ----------------------------- src/com/example/rotorm/Preview.java | 160 +++++++++++++++ 3 files changed, 294 insertions(+), 316 deletions(-) create mode 100644 src/com/example/rotorm/CameraActivity.java delete mode 100644 src/com/example/rotorm/MainActivity.java create mode 100644 src/com/example/rotorm/Preview.java (limited to 'src') diff --git a/src/com/example/rotorm/CameraActivity.java b/src/com/example/rotorm/CameraActivity.java new file mode 100644 index 0000000..6b35995 --- /dev/null +++ b/src/com/example/rotorm/CameraActivity.java @@ -0,0 +1,134 @@ +package com.example.rotorm; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; + +import android.app.Activity; +import android.content.Context; +import android.hardware.Camera; +import android.hardware.Camera.AutoFocusCallback; +import android.hardware.Camera.PictureCallback; +import android.hardware.Camera.ShutterCallback; +import android.os.Bundle; +import android.util.Log; +import android.view.SurfaceView; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.View.OnLongClickListener; +import android.view.ViewGroup.LayoutParams; +import android.view.Window; +import android.view.WindowManager; +import android.widget.Button; +import android.widget.FrameLayout; + + +//why is it so hard to put an eclipse project into git + +public class CameraActivity extends Activity { + public static final String TAG = "rotorM"; + Preview preview; + Button buttonClick; + Camera camera; + String fileName; + Activity act; + Context ctx; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + ctx = this; + act = this; + requestWindowFeature(Window.FEATURE_NO_TITLE); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + + setContentView(R.layout.main); + + preview = new Preview(this, (SurfaceView)findViewById(R.id.surfaceView)); + preview.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); + ((FrameLayout) findViewById(R.id.preview)).addView(preview); + preview.setKeepScreenOn(true); + + buttonClick = (Button) findViewById(R.id.buttonClick); + + buttonClick.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + // preview.camera.takePicture(shutterCallback, rawCallback, jpegCallback); + camera.takePicture(shutterCallback, rawCallback, jpegCallback); + } + }); + + buttonClick.setOnLongClickListener(new OnLongClickListener(){ + @Override + public boolean onLongClick(View arg0) { + camera.autoFocus(new AutoFocusCallback(){ + @Override + public void onAutoFocus(boolean arg0, Camera arg1) { + //camera.takePicture(shutterCallback, rawCallback, jpegCallback); + } + }); + return true; + } + }); + } + + @Override + protected void onResume() { + super.onResume(); + // preview.camera = Camera.open(); + camera = Camera.open(); + camera.startPreview(); + preview.setCamera(camera); + } + + @Override + protected void onPause() { + if(camera != null) { + camera.stopPreview(); + preview.setCamera(null); + camera.release(); + camera = null; + } + super.onPause(); + } + + private void resetCam() { + camera.startPreview(); + preview.setCamera(camera); + } + + ShutterCallback shutterCallback = new ShutterCallback() { + public void onShutter() { + // Log.d(TAG, "onShutter'd"); + } + }; + + PictureCallback rawCallback = new PictureCallback() { + public void onPictureTaken(byte[] data, Camera camera) { + // Log.d(TAG, "onPictureTaken - raw"); + } + }; + + PictureCallback jpegCallback = new PictureCallback() { + public void onPictureTaken(byte[] data, Camera camera) { + FileOutputStream outStream = null; + try { + // Write to SD Card + fileName = String.format("/sdcard/camtest/%d.jpg", System.currentTimeMillis()); + outStream = new FileOutputStream(fileName); + outStream.write(data); + outStream.close(); + Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length); + + resetCam(); + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + } + Log.d(TAG, "onPictureTaken - jpeg"); + } + }; +} diff --git a/src/com/example/rotorm/MainActivity.java b/src/com/example/rotorm/MainActivity.java deleted file mode 100644 index 9ed025f..0000000 --- a/src/com/example/rotorm/MainActivity.java +++ /dev/null @@ -1,316 +0,0 @@ -package com.example.rotorm; - - -import java.io.File; -import java.io.IOException; -import java.util.Date; -import java.util.List; - -import android.hardware.Camera; -import android.hardware.Camera.Parameters; -import android.media.MediaPlayer; -import android.media.MediaRecorder; -import android.net.Uri; -import android.os.Bundle; -import android.os.Environment; -import android.app.Activity; -import android.content.Intent; -import android.util.Log; -import android.view.Menu; -import android.view.MenuItem; -import android.view.SurfaceHolder; -import android.view.SurfaceView; -import android.view.SurfaceHolder.Callback; -import android.widget.Toast; - -//why is it so hard to put an eclipse project into git - -public class MainActivity extends Activity implements Callback { - - @Override - protected void onDestroy() { - stopRecording(); - super.onDestroy(); - } - - private SurfaceHolder surfaceHolder; - private SurfaceView surfaceView; - public MediaRecorder mrec = new MediaRecorder(); - private Camera mCamera; - private Uri uriSound; - MediaPlayer mp; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - - uriSound=Uri.parse(""); - - Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI); - startActivityForResult(intent, 10); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - menu.add(0, 0, 0, "Start"); - //menu.add(0, 0, 0, "Pick audio track"); - return super.onCreateOptionsMenu(menu); - // Inflate the menu; this adds items to the action bar if it is present. - //getMenuInflater().inflate(R.menu.main, menu); - //return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) - { - if(item.getTitle().equals("Start")) - { - try { - - startRecording(); - item.setTitle("Stop"); - - } catch (Exception e) { - - String message = e.getMessage(); - Log.i(null, "Problem " + message); - mrec.release(); - } - - } - else if(item.getTitle().equals("Stop")) - { - mrec.stop(); - mrec.release(); - mrec = null; - item.setTitle("Start"); - mp.stop(); - } - else if(item.getTitle().equals("Pick audio track")) - { - Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI); - startActivityForResult(intent, 10); - } - - return super.onOptionsItemSelected(item); - } - - protected void startPreview() throws IOException { - - //http://stackoverflow.com/questions/12098298/android-camera-app-passed-null-surface - //http://developer.android.com/training/camera/cameradirect.html - - if (mCamera!=null){ - Log.e("Rotor", "Nulling camera"); - mCamera.stopPreview(); - mCamera.setPreviewCallback(null); - mCamera.release(); - mCamera=null; - } - - if(mCamera == null){ - mCamera = Camera.open(); - Log.e("Rotor", "Setting up camera"); - - /* - Camera.Parameters parameters = mCamera.getParameters(); - //get a list of supported preview sizes and assign one - List previewSizes = parameters.getSupportedPreviewSizes(); - Camera.Size previewSize = previewSizes.get(0); - parameters.setPreviewSize(previewSize.width, previewSize.height); - //Set Frame rate - parameters.setPreviewFrameRate(25); - //Set Scene - List modes = parameters.getSupportedSceneModes(); - parameters.setSceneMode(modes.get(0)); - //Set focus mode - List focus = parameters.getSupportedFocusModes(); - parameters.setFocusMode(focus.get(0)); - - - */ - - - - - - Camera.Parameters parameters = mCamera.getParameters(); - parameters.setPreviewSize(1280,720); - parameters.setPreviewFrameRate(25); - parameters.setSceneMode(Camera.Parameters.SCENE_MODE_SPORTS); - parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); - parameters.setColorEffect(Camera.Parameters.EFFECT_NONE); - mCamera.setParameters(parameters); - - //Apply parameters to camera object - mCamera.setParameters(parameters); - Log.e("Rotor", "Camera configured"); - } - - - if(mCamera==null) mCamera = Camera.open(); - - setContentView(R.layout.main); - - surfaceView = (SurfaceView) findViewById(R.id.surface_camera); - - surfaceHolder = surfaceView.getHolder(); - surfaceHolder.addCallback(this); - surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); - - mCamera.lock(); - mCamera.unlock(); - - ////crashes on nexus 10 - //09-07 15:36:21.850: E/AndroidRuntime(5418): java.lang.RuntimeException: getParameters failed (empty parameters) - - //Start the preview - Log.e("Rotor", "Starting preview"); - //mCamera.setPreviewCallback(new cam_PreviewCallback()); - mCamera.setPreviewDisplay(surfaceHolder); - mCamera.startPreview(); - - } - - protected void startRecording() throws IOException - { - if(mCamera==null) - mCamera = Camera.open(); - - String filename; - String path; - - path= Environment.getExternalStorageDirectory().getAbsolutePath().toString(); - - Date date=new Date(); - filename="/rec"+date.toString().replace(" ", "_").replace(":", "_")+".mp4"; - - Log.i(null, "Saving video file: " + filename); - - //create empty file it must use - File file=new File(path,filename); - - mrec = new MediaRecorder(); - - mCamera.lock(); - mCamera.unlock(); - - // Please maintain sequence of following code. - - // If you change sequence it will not work. - mrec.setCamera(mCamera); - mrec.setVideoSource(MediaRecorder.VideoSource.CAMERA); - //mrec.setAudioSource(MediaRecorder.AudioSource.MIC); - mrec.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); - mrec.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP); - //mrec.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); - mrec.setPreviewDisplay(surfaceHolder.getSurface()); - mrec.setOutputFile(path+filename); - mrec.prepare(); - mrec.start(); - - Log.i(null, "Audio file: " + uriSound); - - //try { - //MediaPlayer mp = new MediaPlayer(); - //MediaPlayer mp = MediaPlayer.create(this, R.raw.stick); - mp = MediaPlayer.create(this, uriSound); - //mp.setDataSource(this, uriSound); - mp.start(); - ///} catch (IllegalArgumentException e) { - // TODO Auto-generated catch block - // e.printStackTrace(); - //} catch (SecurityException e) { - // TODO Auto-generated catch block - // e.printStackTrace(); - //} catch (IllegalStateException e) { - // TODO Auto-generated catch block - // e.printStackTrace(); - //} catch (IOException e) { - // TODO Auto-generated catch block - // e.printStackTrace(); - //} - } - - protected void stopRecording() { - - if(mrec!=null) - { - mrec.stop(); - mrec.release(); - mCamera.release(); - mCamera.lock(); - } - - mp.stop(); - } - - private void releaseMediaRecorder() { - - if (mrec != null) { - mrec.reset(); // clear recorder configuration - mrec.release(); // release the recorder object - } - } - - 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); - Log.i("Surface", "Created"); - } - else { - Toast.makeText(getApplicationContext(), "Camera not available!", - Toast.LENGTH_LONG).show(); - - finish(); - } - - } - - @Override - public void surfaceDestroyed(SurfaceHolder holder) { - mCamera.stopPreview(); - mCamera.release(); - //http://stackoverflow.com/questions/13235306/method-called-after-release-exception-camera-preview - //mCamera=null; - } - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - - //if(requestCode == RESULT_OK && requestCode == 10){ - uriSound=data.getData(); - - Log.i("Sound file",uriSound.toString()); - - //String temp="audioFileName"; - //this.getIntent().getStringExtra(temp); - //uriSound=Uri.parse(temp); - //uriSound=Uri.parse("/Music/stick.mp3"); - try { - startPreview(); - } catch (IOException e) { - Log.e("Preview","Error"); - e.printStackTrace(); - } - - //} - } - -} diff --git a/src/com/example/rotorm/Preview.java b/src/com/example/rotorm/Preview.java new file mode 100644 index 0000000..5fdea5a --- /dev/null +++ b/src/com/example/rotorm/Preview.java @@ -0,0 +1,160 @@ +package com.example.rotorm; + +import java.io.IOException; +import java.util.List; + +import android.content.Context; +import android.hardware.Camera; +import android.hardware.Camera.Size; +import android.util.Log; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.View; +import android.view.ViewGroup; + +class Preview extends ViewGroup implements SurfaceHolder.Callback { + private final String TAG = "Preview"; + + SurfaceView mSurfaceView; + SurfaceHolder mHolder; + Size mPreviewSize; + List mSupportedPreviewSizes; + Camera mCamera; + + Preview(Context context, SurfaceView sv) { + super(context); + + mSurfaceView = sv; +// addView(mSurfaceView); + + mHolder = mSurfaceView.getHolder(); + mHolder.addCallback(this); + mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); + } + + public void setCamera(Camera camera) { + mCamera = camera; + if (mCamera != null) { + mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes(); + requestLayout(); + + // get Camera parameters + Camera.Parameters params = mCamera.getParameters(); + + List focusModes = params.getSupportedFocusModes(); + if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) { + // set the focus mode + params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); + // set Camera parameters + mCamera.setParameters(params); + } + } + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + // We purposely disregard child measurements because act as a + // wrapper to a SurfaceView that centers the camera preview instead + // of stretching it. + final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec); + final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec); + setMeasuredDimension(width, height); + + if (mSupportedPreviewSizes != null) { + mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height); + } + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + if (changed && getChildCount() > 0) { + final View child = getChildAt(0); + + final int width = r - l; + final int height = b - t; + + int previewWidth = width; + int previewHeight = height; + if (mPreviewSize != null) { + previewWidth = mPreviewSize.width; + previewHeight = mPreviewSize.height; + } + + // Center the child SurfaceView within the parent. + if (width * previewHeight > height * previewWidth) { + final int scaledChildWidth = previewWidth * height / previewHeight; + child.layout((width - scaledChildWidth) / 2, 0, + (width + scaledChildWidth) / 2, height); + } else { + final int scaledChildHeight = previewHeight * width / previewWidth; + child.layout(0, (height - scaledChildHeight) / 2, + width, (height + scaledChildHeight) / 2); + } + } + } + + public void surfaceCreated(SurfaceHolder holder) { + // The Surface has been created, acquire the camera and tell it where + // to draw. + try { + if (mCamera != null) { + mCamera.setPreviewDisplay(holder); + } + } catch (IOException exception) { + Log.e(TAG, "IOException caused by setPreviewDisplay()", exception); + } + } + + public void surfaceDestroyed(SurfaceHolder holder) { + // Surface will be destroyed when we return, so stop the preview. + if (mCamera != null) { + mCamera.stopPreview(); + } + } + + + private Size getOptimalPreviewSize(List sizes, int w, int h) { + final double ASPECT_TOLERANCE = 0.1; + double targetRatio = (double) w / h; + if (sizes == null) return null; + + Size optimalSize = null; + double minDiff = Double.MAX_VALUE; + + int targetHeight = h; + + // 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) > ASPECT_TOLERANCE) 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 surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + if(mCamera != null) { + Camera.Parameters parameters = mCamera.getParameters(); + parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height); + requestLayout(); + + mCamera.setParameters(parameters); + mCamera.startPreview(); + } + } + +} -- cgit v1.2.3