package org.bcsphere.camera; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; import org.bcsphere.findme.R; import android.annotation.SuppressLint; import android.app.ActionBar.LayoutParams; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.graphics.drawable.BitmapDrawable; import android.hardware.Camera; import android.hardware.Camera.AutoFocusCallback; import android.hardware.Camera.Parameters; import android.hardware.Camera.PictureCallback; import android.hardware.Camera.ShutterCallback; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.StatFs; import android.provider.MediaStore; import android.util.DisplayMetrics; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; import android.widget.Button; import android.widget.ImageView; import android.widget.PopupWindow; import android.widget.Toast; @SuppressLint({ "NewApi", "SdCardPath" }) public class TakePictureAty extends Activity implements OnTouchListener,OnClickListener,SurfaceHolder.Callback{ private Button btnFlashLightSwitch,btnLensSwitch,btnBrowsePhoto,btnTakePicture,btnClose; private SurfaceView mSurfaceView; private SurfaceHolder mSurfaceHolder; private Camera mCamera; private boolean isFront = false; private boolean isOk = true; private int flashLightState = 0; private int mode = 0; private Bitmap mBitmap; private View mainView; private String flashLightMode[] = {Camera.Parameters.FLASH_MODE_AUTO,Camera.Parameters.FLASH_MODE_ON, Camera.Parameters.FLASH_MODE_OFF}; private int flashBackground[] = {R.drawable.flash_auto,R.drawable.flash_turn_on,R.drawable.flash_turn_off}; private PopupWindow mPopupWindow; private ImageView imgPhoto; @SuppressWarnings("deprecation") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.take_picture_activity); Intent intent = getIntent(); mode = intent.getIntExtra("MODE", 0); LayoutInflater inflater = LayoutInflater.from(TakePictureAty.this); mainView = inflater.inflate(R.layout.take_picture_activity, null); View view = inflater.inflate(R.layout.popupwindow_view, null); mPopupWindow = new PopupWindow(view,LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT); imgPhoto = (ImageView) view.findViewById(R.id.imgPhoto); imgPhoto.setOnClickListener(this); mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView); mSurfaceView.setOnTouchListener(this); mSurfaceHolder = mSurfaceView.getHolder(); mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); mSurfaceHolder.addCallback(this); btnFlashLightSwitch = (Button) findViewById(R.id.btnFlashLightSwitch); btnLensSwitch = (Button) findViewById(R.id.btnLensSwitch); btnBrowsePhoto = (Button) findViewById(R.id.btnBrowsePhoto); btnTakePicture = (Button) findViewById(R.id.btnTakePicture); btnClose = (Button) findViewById(R.id.btnClose); btnFlashLightSwitch.setOnClickListener(this); btnLensSwitch.setOnClickListener(this); btnBrowsePhoto.setOnClickListener(this); btnTakePicture.setOnClickListener(this); btnClose.setOnClickListener(this); btnFlashLightSwitch.setBackgroundDrawable(getResources().getDrawable(flashBackground[flashLightState%3])); isFront = false; } @Override protected void onResume() { super.onResume(); org.bcsphere.camera.Camera.setCameraState(true); if (mCamera == null) { if (isFront) { mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT); }else { mCamera = Camera.open(); } initCamera(isFront); } IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction("TAKE_PICTURE"); registerReceiver(receiver, intentFilter); } @Override protected void onPause() { super.onPause(); org.bcsphere.camera.Camera.setCameraState(false); unregisterReceiver(receiver); cleanCamera(); } public void takePicture(){ if (examineSDCard()) { if (examineStorageSpace((getScreenHeight(TakePictureAty.this)+1) * (getScreenWidth(TakePictureAty.this)+1))) { if (mCamera != null) { if (isOk) { isOk = false; mCamera.takePicture(shutterCallback, null, pictureCallback); } } }else{ Toast.makeText(TakePictureAty.this, "Insufficient storage space in!", Toast.LENGTH_SHORT).show(); } }else { Toast.makeText(TakePictureAty.this, "Did not mount the sd card ! ", Toast.LENGTH_SHORT).show(); } } @SuppressWarnings("deprecation") private void initCamera(boolean isFrontLens){ mCamera.setDisplayOrientation(90); btnFlashLightSwitch.setBackgroundDrawable(getResources().getDrawable(flashBackground[flashLightState%3])); if (!isFrontLens) { Camera.Parameters parameters = mCamera.getParameters(); parameters.setFlashMode(flashLightMode[flashLightState%3]); mCamera.setParameters(parameters); } Parameters parameters = mCamera.getParameters(); Camera.Size pictureSize = getMostFitSize(parameters.getSupportedPictureSizes()); parameters.setPictureSize(pictureSize.width, pictureSize.height); Camera.Size previewSize = getMostFitSize(parameters.getSupportedPreviewSizes()); parameters.setPreviewSize(previewSize.width,previewSize.height); mCamera.setParameters(parameters); try { mCamera.setPreviewDisplay(mSurfaceHolder); } catch (IOException e) { e.printStackTrace(); } mCamera.startPreview(); if (mode== 0) { Handler handler = new Handler(); handler.postDelayed(runnable, 1000); } } @SuppressWarnings("deprecation") private void setCameraLens(boolean isFrontLens){ int lensCount = 0; if (isFrontLens) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { lensCount = Camera.getNumberOfCameras(); } if (lensCount == 2) { cleanCamera(); flashLightState = 0; btnFlashLightSwitch.setBackgroundDrawable(getResources().getDrawable(flashBackground[flashLightState%3])); mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT); }else { isFront = false; } }else { cleanCamera(); mCamera = Camera.open(); btnFlashLightSwitch.setBackgroundDrawable(getResources().getDrawable(flashBackground[flashLightState%3])); } initCamera(isFrontLens); } private void cleanCamera(){ if (mCamera != null) { mCamera.stopPreview(); mCamera.release(); mCamera = null; } } public static boolean examineSDCard(){ return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED); } @SuppressWarnings("deprecation") public static boolean examineStorageSpace(long fileSize){ File path =new File("/mnt/sdcard/"); StatFs statFs = new StatFs(path.getPath()); long blockSize = statFs.getBlockSize(); long availableBlocks = statFs.getAvailableBlocks(); long spaceSize = availableBlocks * blockSize; if (spaceSize > fileSize) { return true; }else { return false; } } public static byte[] getBytesFromBitmapUri(Context context, Uri uri) { byte[] data = null; ContentResolver resolver = context.getContentResolver(); try { data = getBytesFromInputStream( resolver.openInputStream(Uri.parse(uri.toString())), 3500000); } catch (IOException e) { e.printStackTrace(); } return data; } public static byte[] getBytesFromInputStream(InputStream is, int bufsiz) throws IOException { int total = 0; byte[] bytes = new byte[4096]; ByteBuffer bb = ByteBuffer.allocate(bufsiz); while (true) { int read = is.read(bytes); if (read == -1) break; bb.put(bytes, 0, read); total += read; } byte[] content = new byte[total]; bb.flip(); bb.get(content, 0, total); return content; } public static int getScreenHeight(Activity activity){ DisplayMetrics displayMetrics = new DisplayMetrics(); activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); return displayMetrics.heightPixels; } public static int getScreenWidth(Activity activity){ DisplayMetrics displayMetrics = new DisplayMetrics(); activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); return displayMetrics.widthPixels; } @SuppressWarnings("deprecation") @Override public void onClick(View arg0) { switch (arg0.getId()) { case R.id.btnFlashLightSwitch: if (isFront) { Toast.makeText(TakePictureAty.this, "Device does not support flash light !", Toast.LENGTH_SHORT).show(); }else { flashLightState++; btnFlashLightSwitch.setBackgroundDrawable(getResources().getDrawable(flashBackground[flashLightState%3])); Camera.Parameters parameters = mCamera.getParameters(); parameters.setFlashMode(flashLightMode[flashLightState%3]); mCamera.setParameters(parameters); } break; case R.id.btnLensSwitch: isFront = (!isFront); setCameraLens(isFront); break; case R.id.btnBrowsePhoto: if (mBitmap != null) { imgPhoto.setBackgroundDrawable(new BitmapDrawable(mBitmap)); mPopupWindow.showAsDropDown(mainView, 0, 0); } break; case R.id.btnTakePicture: if (examineSDCard()) { if (examineStorageSpace((getScreenHeight(TakePictureAty.this)+1) * (getScreenWidth(TakePictureAty.this)+1))) { if (mCamera != null) { if (isOk) { isOk = false; mCamera.takePicture(shutterCallback, null, pictureCallback); } } }else{ Toast.makeText(TakePictureAty.this, "Insufficient storage space in!", Toast.LENGTH_SHORT).show(); } }else { Toast.makeText(TakePictureAty.this, "Did not mount the sd card ! ", Toast.LENGTH_SHORT).show(); } break; case R.id.btnClose: close(); break; case R.id.imgPhoto: if (mPopupWindow.isShowing()) { mPopupWindow.dismiss(); } break; } } @Override public boolean onTouch(View arg0, MotionEvent arg1) { if (mCamera != null) { mCamera.autoFocus(new AutoFocusCallback() { @Override public void onAutoFocus(boolean arg0, Camera arg1) { } }); } return false; } @Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { } @Override public void surfaceCreated(SurfaceHolder arg0) { mSurfaceHolder = arg0; if (mCamera != null) { try { mCamera.setPreviewDisplay(mSurfaceHolder); } catch (IOException e) { e.printStackTrace(); } } } @Override public void surfaceDestroyed(SurfaceHolder arg0) { cleanCamera(); } private ShutterCallback shutterCallback = new ShutterCallback() { @Override public void onShutter() { } }; private PictureCallback pictureCallback = new PictureCallback() { @SuppressWarnings("deprecation") @Override public void onPictureTaken(byte[] arg0, Camera arg1) { isOk = true; if (mode == 0) { close(); }else if (mode == 1) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } arg1.startPreview(); } Bitmap bitmap = BitmapFactory.decodeByteArray(arg0, 0, arg0.length); Matrix matrix = new Matrix(); if (isFront) { matrix.setRotate(270); }else { matrix.setRotate(90); } bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); ContentResolver localContentResolver = getContentResolver(); try { String url = MediaStore.Images.Media.insertImage(localContentResolver, bitmap, "", ""); refresh(url, TakePictureAty.this.getApplicationContext()); } catch (Exception error) { error.printStackTrace(); cleanCamera(); } mBitmap = bitmap; btnBrowsePhoto.setBackgroundDrawable(new BitmapDrawable(mBitmap)); } }; private void refresh(String url, Context context) { Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); Uri uri = Uri.fromFile(new File(url)); intent.setData(uri); context.sendBroadcast(intent); } public boolean onKeyDown(int keyCode, android.view.KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (mPopupWindow.isShowing()) { mPopupWindow.dismiss(); return false; } TakePictureAty.this.finish(); return false; }else { return super.onKeyDown(keyCode, event); } }; public Camera.Size getMostFitSize(List<Camera.Size> list){ int screenHeight = getScreenHeight(TakePictureAty.this); int screenWidth = getScreenWidth(TakePictureAty.this); List<Integer> indexList = new ArrayList<Integer>(); int minHeight = -1; int minWidth = -1; int mostFitSize = -1; for (int i = 0; i < list.size(); i++) { Camera.Size size = list.get(i); if (i == 0) { minHeight = Math.abs(size.height - screenWidth); indexList.add(i); }else { if (Math.abs(size.height - screenWidth) < minHeight) { minHeight = Math.abs(size.height - screenWidth); indexList.clear(); indexList.add(i); }else if (Math.abs(size.height - screenWidth) == minHeight) { indexList.add(i); } } } for (int i = 0; i < indexList.size(); i++) { if ( i == 0) { minWidth = Math.abs(list.get(indexList.get(i)).width - screenHeight); mostFitSize = indexList.get(i); }else { if (Math.abs(list.get(indexList.get(i)).width - screenHeight) < minWidth) { minWidth = Math.abs(list.get(indexList.get(i)).width - screenHeight); mostFitSize = indexList.get(i); } } } return list.get(mostFitSize); } BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context arg0, Intent arg1) { takePicture(); } }; Runnable runnable = new Runnable() { @Override public void run() { takePicture(); } }; private void close(){ TakePictureAty.this.finish(); Intent intent = new Intent(); intent.setAction("ON_CAMERA_CLOSE"); sendBroadcast(intent); } }