package com.RSen.Commandr.builtincommands; import android.app.Activity; import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.ImageFormat; import android.graphics.Matrix; import android.hardware.Camera; import android.media.AudioManager; import android.media.MediaPlayer; import android.net.Uri; import android.os.Bundle; import android.os.CountDownTimer; import android.os.Environment; import android.provider.MediaStore; import android.util.Log; import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.widget.FrameLayout; import android.widget.TextView; import com.RSen.Commandr.R; import com.RSen.Commandr.util.GoogleNowUtil; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; public class TakePictureActivity extends Activity { private SurfaceView preview=null; private SurfaceHolder previewHolder=null; private Camera camera=null; private TextView countdownTV; private static int orientation; private static boolean frontFacingCamera; private boolean inPreview = false; private boolean cameraConfigured=false; private boolean safeToTakePicture = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_take_picture); preview=(SurfaceView)findViewById(R.id.camera_preview); previewHolder=preview.getHolder(); previewHolder.addCallback(surfaceCallback); previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } @Override protected void onResume() { super.onResume(); frontFacingCamera = getIntent().getBooleanExtra("frontCamera", false); // Create an instance of Camera camera = getCameraInstance(frontFacingCamera); countdownTV = (TextView) findViewById(R.id.countdown); } CountDownTimer timer = new CountDownTimer(3000, 1000) { @Override public void onTick(long l) { countdownTV.setText(((int) l / 1000) + ""); } @Override public void onFinish() { if (safeToTakePicture) { if (camera != null) { countdownTV.setText(getString(R.string.smile)); shootSound(); camera.takePicture(null, null, mPicture); safeToTakePicture = false; } } } }; public void shootSound() { MediaPlayer _shootMP = null; AudioManager meng = (AudioManager) TakePictureActivity.this.getSystemService(Context.AUDIO_SERVICE); int volume = meng.getStreamVolume(AudioManager.STREAM_NOTIFICATION); if (volume != 0) { if (_shootMP == null) _shootMP = MediaPlayer.create(TakePictureActivity.this, Uri.parse("file:///system/media/audio/ui/camera_click.ogg")); if (_shootMP != null) _shootMP.start(); } } private Camera.PictureCallback mPicture = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); Date date = new Date(); insertImage(getContentResolver(), BitmapFactory.decodeByteArray(data, 0, data.length, null), "Commandr " + dateFormat.format(date), getString(R.string.taken_with_commandr)); safeToTakePicture = true; finish(); GoogleNowUtil.resetGoogleNow(TakePictureActivity.this); } }; public String insertImage(ContentResolver cr, Bitmap source, String title, String description) { ContentValues values = new ContentValues(); values.put(MediaStore.Images.Media.TITLE, title); values.put(MediaStore.Images.Media.DISPLAY_NAME, title); values.put(MediaStore.Images.Media.DESCRIPTION, description); values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg"); // Add the date meta data to ensure the image is added at the front of the gallery values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis()); values.put(MediaStore.Images.Media.DATE_MODIFIED, System.currentTimeMillis()); values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis()); if (frontFacingCamera && orientation == 90) //weird flipped front-facing camera { orientation += 180; } values.put(MediaStore.Images.Media.ORIENTATION, orientation); Uri url = null; String stringUrl = null; /* value to be returned */ try { url = cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); if (source != null) { OutputStream imageOut = cr.openOutputStream(url); try { source.compress(Bitmap.CompressFormat.JPEG, 50, imageOut); } finally { imageOut.close(); } long id = ContentUris.parseId(url); // Wait until MINI_KIND thumbnail is generated. Bitmap miniThumb = MediaStore.Images.Thumbnails.getThumbnail(cr, id, MediaStore.Images.Thumbnails.MINI_KIND, null); // This is for backward compatibility. storeThumbnail(cr, miniThumb, id, 50F, 50F, MediaStore.Images.Thumbnails.MICRO_KIND); } else { cr.delete(url, null, null); url = null; } } catch (Exception e) { if (url != null) { cr.delete(url, null, null); url = null; } } if (url != null) { stringUrl = url.toString(); } return stringUrl; } /** * A copy of the Android internals StoreThumbnail method, it used with the insertImage to * populate the android.provider.MediaStore.Images.Media#insertImage with all the correct * meta data. The StoreThumbnail method is private so it must be duplicated here. * * @see android.provider.MediaStore.Images.Media (StoreThumbnail private method) */ private static final Bitmap storeThumbnail( ContentResolver cr, Bitmap source, long id, float width, float height, int kind) { // create the matrix to scale it Matrix matrix = new Matrix(); float scaleX = width / source.getWidth(); float scaleY = height / source.getHeight(); matrix.setScale(scaleX, scaleY); Bitmap thumb = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true ); ContentValues values = new ContentValues(4); values.put(MediaStore.Images.Thumbnails.KIND, kind); values.put(MediaStore.Images.Thumbnails.IMAGE_ID, (int) id); values.put(MediaStore.Images.Thumbnails.HEIGHT, thumb.getHeight()); values.put(MediaStore.Images.Thumbnails.WIDTH, thumb.getWidth()); Uri url = cr.insert(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, values); try { OutputStream thumbOut = cr.openOutputStream(url); thumb.compress(Bitmap.CompressFormat.JPEG, 100, thumbOut); thumbOut.close(); return thumb; } catch (FileNotFoundException ex) { return null; } catch (IOException ex) { return null; } } /** * A safe way to get an instance of the Camera object. */ public static Camera getCameraInstance(boolean frontCamera) { Camera c = null; try { if (!frontCamera) { c = Camera.open(); // attempt to get a Camera instance } else { Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); int cameraCount = Camera.getNumberOfCameras(); for (int camIdx = 0; camIdx < cameraCount; camIdx++) { Camera.getCameraInfo(camIdx, cameraInfo); if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { try { c = Camera.open(camIdx); } catch (RuntimeException e) { } } } } } catch (Exception e) { // Camera is not available (in use or does not exist) } return c; // returns null if camera is unavailable } public static void setCameraDisplayOrientation(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; } orientation = info.orientation; int result; if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { result = (orientation + degrees) % 360; result = (360 - result) % 360; // compensate the mirror } else { // back-facing result = (orientation - degrees + 360) % 360; } orientation = result; camera.setDisplayOrientation(result); } @Override protected void onPause() { super.onPause(); timer.cancel(); if (camera != null) { if (inPreview) { camera.stopPreview(); } camera.release(); camera = null; inPreview = false; } } 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 Camera.Size getLargestPictureSize(Camera.Parameters parameters) { Camera.Size result=null; for (Camera.Size size : parameters.getSupportedPictureSizes()) { 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) { } if (!cameraConfigured) { Camera.Parameters parameters=camera.getParameters(); Camera.Size size=getBestPreviewSize(width, height, parameters); Camera.Size pictureSize=getLargestPictureSize(parameters); if (size != null && pictureSize != null) { if (parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_AUTO)) { // set the focus mode parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); } parameters.setPreviewSize(size.width, size.height); parameters.setPictureSize(pictureSize.width, pictureSize.height); parameters.setPictureFormat(ImageFormat.JPEG); camera.setParameters(parameters); cameraConfigured=true; } } } } private void startPreview() { if (cameraConfigured && camera != null) { camera.startPreview(); inPreview=true; } } SurfaceHolder.Callback surfaceCallback=new SurfaceHolder.Callback() { public void surfaceCreated(SurfaceHolder holder) { } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { if (previewHolder.getSurface() == null) { // preview surface does not exist return; } // stop preview before making changes try { camera.stopPreview(); } catch (Exception e) { // ignore: tried to stop a non-existent preview } // set preview size and make any resize, rotate or // reformatting changes here // start preview with new settings try { setCameraDisplayOrientation(TakePictureActivity.this, 0, camera); initPreview(width, height); startPreview(); safeToTakePicture = true; timer.cancel(); timer.start(); } catch (Exception e) { } } public void surfaceDestroyed(SurfaceHolder holder) { // no-op } }; }