Created
April 30, 2013 06:59
-
-
Save codebreaker/5487057 to your computer and use it in GitHub Desktop.
Activity to handle Capture Image from camera, for all devices. Taken from http://stackoverflow.com/questions/16019165/summary-take-a-picture-utilizing-camera-intent-and-display-the-photo-with-corre
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<uses-sdk | |
android:minSdkVersion="8" | |
android:targetSdkVersion="17" /> | |
<!-- FOR Camera --> | |
<uses-permission android:name="android.permission.CAMERA" /> | |
<uses-permission android:name="android.permission.VIBRATE" /> | |
<uses-permission android:name="android.permission.FLASHLIGHT" /> | |
<!-- Don't require camera, as this requires a rear camera. This allows it to work on the Nexus 7 --> | |
<uses-feature | |
android:name="android.hardware.camera" | |
android:required="false" /> | |
<uses-feature | |
android:name="android.hardware.camera.front" | |
android:required="false" /> | |
<uses-feature | |
android:name="android.hardware.camera.autofocus" | |
android:required="false" /> | |
<uses-feature | |
android:name="android.hardware.camera.flash" | |
android:required="false" /> | |
<uses-feature android:name="android.hardware.screen.landscape" /> | |
<uses-feature | |
android:name="android.hardware.wifi" | |
android:required="false" /> | |
<uses-feature | |
android:name="android.hardware.touchscreen" | |
android:required="false" /> | |
<application | |
android:allowBackup="true" | |
android:icon="@drawable/ic_youricon" | |
android:label="@string/app_name" | |
android:theme="@android:style/Theme.Light.NoTitleBar" > | |
<activity | |
android:name="your.package.android.photo.TakePhotoActivity" | |
android:label="@string/app_name" > | |
</activity> | |
<activity | |
android:name="your.package.android.photo.UploadPhotoActivity" | |
android:label="@string/app_name" | |
android:noHistory="true" > | |
</activity> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class BitmapHelper { | |
public static byte[] bitmapToByteArray(Bitmap bitmap) { | |
ByteArrayOutputStream stream = new ByteArrayOutputStream(); | |
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); | |
return stream.toByteArray(); | |
} | |
public static Bitmap byteArrayToBitmap(byte[] byteArray) { | |
if (byteArray == null) { | |
return null; | |
} else { | |
return BitmapFactory | |
.decodeByteArray(byteArray, 0, byteArray.length); | |
} | |
} | |
public static Bitmap shrinkBitmap(Bitmap bm, int maxLengthOfEdge) { | |
return shrinkBitmap(bm, maxLengthOfEdge, 0); | |
} | |
public static Bitmap shrinkBitmap(Bitmap bm, int maxLengthOfEdge, | |
int rotateXDegree) { | |
if (maxLengthOfEdge > bm.getWidth() && maxLengthOfEdge > bm.getHeight()) { | |
return bm; | |
} else { | |
// shrink image | |
float scale = (float) 1.0; | |
if (bm.getHeight() > bm.getWidth()) { | |
scale = ((float) maxLengthOfEdge) / bm.getHeight(); | |
} else { | |
scale = ((float) maxLengthOfEdge) / bm.getWidth(); | |
} | |
// CREATE A MATRIX FOR THE MANIPULATION | |
Matrix matrix = new Matrix(); | |
// RESIZE THE BIT MAP | |
matrix.postScale(scale, scale); | |
matrix.postRotate(rotateXDegree); | |
// RECREATE THE NEW BITMAP | |
bm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), | |
matrix, false); | |
matrix = null; | |
System.gc(); | |
return bm; | |
} | |
} | |
public static Bitmap readBitmap(Context context, Uri selectedImage) { | |
Bitmap bm = null; | |
BitmapFactory.Options options = new BitmapFactory.Options(); | |
options.inPreferredConfig = Bitmap.Config.RGB_565; | |
options.inScaled = false; | |
// options.inSampleSize = 3; | |
AssetFileDescriptor fileDescriptor = null; | |
try { | |
fileDescriptor = context.getContentResolver().openAssetFileDescriptor(selectedImage, "r"); | |
} catch (FileNotFoundException e) { | |
return null; | |
} finally { | |
try { | |
bm = BitmapFactory.decodeFileDescriptor( | |
fileDescriptor.getFileDescriptor(), null, options); | |
fileDescriptor.close(); | |
} catch (IOException e) { | |
return null; | |
} | |
} | |
return bm; | |
} | |
public static void clearBitmap(Bitmap bm) { | |
bm.recycle(); | |
System.gc(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class TakePhotoActivity extends Activity { | |
public final static String TAG = TakePhotoActivity.class.getName(); | |
public final static String CAMERA_PIC_URI_FOR_UPLOAD = "your.package.android.TakePhotoActivity.CAMERA_PIC_URI_FOR_UPLOAD"; | |
public final static String CAMERA_PIC_ORIENTATION_FOR_UPLOAD = "your.package.android.TakePhotoActivity.CAMERA_PIC_ORIENTATION_FOR_UPLOAD"; | |
private final static int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100; | |
public final static int MEDIA_TYPE_IMAGE = 1; | |
public final static int MEDIA_TYPE_VIDEO = 2; | |
private static final String DATE_CAMERA_INTENT_STARTED_STATE = "your.package.android.photo.TakePhotoActivity.dateCameraIntentStarted"; | |
private static Date dateCameraIntentStarted = null; | |
private static final String CAMERA_PIC_URI_STATE = "your.package.android.photo.TakePhotoActivity.CAMERA_PIC_URI_STATE"; | |
private static Uri cameraPicUri = null; | |
private static final String ROTATE_X_DEGREES_STATE = "your.package.android.photo.TakePhotoActivity.ROTATE_X_DEGREES_STATE"; | |
private static int rotateXDegrees = 0; | |
@Override | |
public void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
ViewGroup vg = (ViewGroup) findViewById(R.id.content); | |
ViewGroup.inflate(TakePhotoActivity.this, R.layout.activity_take_photo_action, vg); | |
super.setFooterButtonColor(R.id.footer_capture_actions_button); | |
((ImageButton) findViewById(R.id.footer_capture_actions_button)).setImageResource(R.drawable.ic_camera_grey); | |
if (savedInstanceState == null) { | |
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { | |
startCameraIntent(); | |
} else { | |
showWarningDialog(getString(R.string.error_sd_card_not_mounted)); | |
} | |
} | |
} | |
private void startCameraIntent() { | |
try { | |
dateCameraIntentStarted = new Date(); | |
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); | |
//NOTE: Do NOT SET: intent.putExtra(MediaStore.EXTRA_OUTPUT, cameraPicUri) on Samsung Galaxy S2/S3/.. for the following reasons: | |
// 1.) it will break the correct picture orientation | |
// 2.) the photo will be stored in two locations (the given path and additionally in the MediaStore) | |
String manufacturer = android.os.Build.MANUFACTURER.toLowerCase(); | |
if(!(manufacturer.contains("samsung")) && !(manufacturer.contains("sony"))) { | |
String filename = System.currentTimeMillis() + ".jpg"; | |
ContentValues values = new ContentValues(); | |
values.put(MediaStore.Images.Media.TITLE, filename); | |
cameraPicUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); | |
intent.putExtra(MediaStore.EXTRA_OUTPUT, cameraPicUri); | |
} | |
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE); | |
} catch (ActivityNotFoundException e) { | |
showWarningDialog(getString(R.string.error_could_not_take_photo)); | |
} | |
} | |
@Override | |
public void onSaveInstanceState(Bundle savedInstanceState) { | |
super.onSaveInstanceState(savedInstanceState); | |
if (dateCameraIntentStarted != null) { | |
savedInstanceState.putString(DATE_CAMERA_INTENT_STARTED_STATE, DateHelper.dateToString(dateCameraIntentStarted)); | |
} | |
if (cameraPicUri != null) { | |
savedInstanceState.putString(CAMERA_PIC_URI_STATE, cameraPicUri.toString()); | |
} | |
savedInstanceState.putInt(ROTATE_X_DEGREES_STATE, rotateXDegrees); | |
} | |
@Override | |
public void onRestoreInstanceState(Bundle savedInstanceState) { | |
super.onRestoreInstanceState(savedInstanceState); | |
if (savedInstanceState.containsKey(DATE_CAMERA_INTENT_STARTED_STATE)) { | |
dateCameraIntentStarted = DateHelper.stringToDate(savedInstanceState.getString(DATE_CAMERA_INTENT_STARTED_STATE)); | |
} | |
if (savedInstanceState.containsKey(CAMERA_PIC_URI_STATE)) { | |
cameraPicUri = Uri.parse(savedInstanceState.getString(CAMERA_PIC_URI_STATE)); | |
} | |
rotateXDegrees = savedInstanceState.getInt(ROTATE_X_DEGREES_STATE); | |
} | |
@Override | |
protected void onActivityResult(int requestCode, int resultCode, Intent intent) { | |
super.onActivityResult(requestCode, resultCode, intent); | |
switch (requestCode) { | |
case CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE: { | |
onTakePhotoActivityResult(requestCode, resultCode, intent); | |
break; | |
} | |
} | |
} | |
private void onTakePhotoActivityResult(int requestCode, int resultCode, Intent intent) { | |
if (resultCode == RESULT_OK) { | |
Cursor myCursor = null; | |
Date dateOfPicture = null; | |
try { | |
// Create a Cursor to obtain the file Path for the large image | |
String[] largeFileProjection = {MediaStore.Images.ImageColumns._ID, | |
MediaStore.Images.ImageColumns.DATA, | |
MediaStore.Images.ImageColumns.ORIENTATION, | |
MediaStore.Images.ImageColumns.DATE_TAKEN}; | |
String largeFileSort = MediaStore.Images.ImageColumns._ID + " DESC"; | |
myCursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, | |
largeFileProjection, null, null, largeFileSort); | |
myCursor.moveToFirst(); | |
// This will actually give you the file path location of the image. | |
String largeImagePath = myCursor.getString(myCursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATA)); | |
Uri tempCameraPicUri = Uri.fromFile(new File(largeImagePath)); | |
if (tempCameraPicUri != null) { | |
dateOfPicture = new Date(myCursor.getLong(myCursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATE_TAKEN))); | |
if (dateOfPicture != null && dateOfPicture.after(dateCameraIntentStarted)) { | |
cameraPicUri = tempCameraPicUri; | |
rotateXDegrees = myCursor.getInt(myCursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.ORIENTATION)); | |
} | |
} | |
} catch (Exception e) { | |
// Log.w("TAG", "Exception - optaining the picture's uri failed: " + e.toString()); | |
} finally { | |
if (myCursor != null) { | |
myCursor.close(); | |
} | |
} | |
if (cameraPicUri == null) { | |
try { | |
cameraPicUri = intent.getData(); | |
} catch (Exception e){ | |
showWarningDialog(getString(R.string.error_could_not_take_photo)); | |
} | |
} | |
if (cameraPicUri != null) { | |
Intent actionIntent = new Intent(TakePhotoActivity.this, UploadPhotoActivity.class); | |
actionIntent.putExtra(CAMERA_PIC_URI_FOR_UPLOAD, cameraPicUri.toString()); | |
actionIntent.putExtra(CAMERA_PIC_ORIENTATION_FOR_UPLOAD, rotateXDegrees); | |
startActivity(actionIntent); | |
this.finish(); | |
} else { | |
showWarningDialog(getString(R.string.error_could_not_take_photo)); | |
} | |
} else if (resultCode == Activity.RESULT_CANCELED) { | |
cancelActivity(); | |
} else { | |
cancelActivity(); | |
} | |
} | |
private void showWarningDialog(String message) { | |
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this); | |
alertDialogBuilder.setTitle(getResources().getString(R.string.warning_dialog_heading)); | |
alertDialogBuilder | |
.setMessage(message) | |
.setCancelable(false) | |
.setPositiveButton("OK",new DialogInterface.OnClickListener() { | |
public void onClick(DialogInterface dialog,int id) { | |
dialog.cancel(); | |
cancelActivity(); | |
} | |
}); | |
AlertDialog alertDialog = alertDialogBuilder.create(); | |
alertDialog.show(); | |
} | |
private void cancelActivity() { | |
this.finish(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class UploadPhotoActivity extends Activity { | |
private static final String PHOTO_STATE = "your.package.android.photo.UploadPhotoActivity.photo"; | |
private Bitmap photo = null; | |
private static final String THUMBNAIL_STATE = "your.package.android.photo.UploadPhotoActivity.thumbnail"; | |
private Bitmap thumbnail = null; | |
private static final String CAMERA_PIC_URI_STATE = "your.package.android.photo.UploadPhotoActivity.cameraPicUri"; | |
private Uri cameraPicUri = null; | |
private static final String ROTATE_X_DEGREES_STATE = "your.package.android.photo.TakePhotoActivity.ROTATE_X_DEGREES_STATE"; | |
private int rotateXDegrees = 0; | |
@Override | |
public void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_upload_photo); | |
Intent intent = getIntent(); | |
cameraPicUri = Uri.parse(intent.getStringExtra(TakePhotoActivity.CAMERA_PIC_URI_FOR_UPLOAD)); | |
rotateXDegrees = intent.getIntExtra(TakePhotoActivity.CAMERA_PIC_ORIENTATION_FOR_UPLOAD, 0); | |
try { | |
photo = BitmapHelper.readBitmap(this, cameraPicUri); | |
if (photo != null) { | |
photo = BitmapHelper.shrinkBitmap(photo, 600, rotateXDegrees); | |
thumbnail = BitmapHelper.shrinkBitmap(photo, 100); | |
ImageView imageView = (ImageView) findViewById(R.id.sustainable_action_photo); | |
imageView.setImageBitmap(photo); | |
} else { | |
showWarningDialog(getResources().getString(R.string.error_could_not_take_photo)); | |
} | |
} catch (Exception e) { | |
showWarningDialog(getResources().getString(R.string.error_could_not_take_photo)); | |
} | |
} | |
@Override | |
public void onSaveInstanceState(Bundle savedInstanceState) { | |
super.onSaveInstanceState(savedInstanceState); | |
if (photo != null) { | |
savedInstanceState.putByteArray(PHOTO_STATE, BitmapHelper.bitmapToByteArray(photo)); | |
BitmapHelper.clearBitmap(photo); | |
} | |
if (thumbnail != null) { | |
savedInstanceState.putByteArray(THUMBNAIL_STATE, BitmapHelper.bitmapToByteArray(thumbnail)); | |
BitmapHelper.clearBitmap(thumbnail); | |
} | |
if (cameraPicUri != null) { | |
savedInstanceState.putString(CAMERA_PIC_URI_STATE, cameraPicUri.toString()); | |
} | |
savedInstanceState.putInt(ROTATE_X_DEGREES_STATE, rotateXDegrees); | |
} | |
@Override | |
public void onRestoreInstanceState(Bundle savedInstanceState) { | |
super.onRestoreInstanceState(savedInstanceState); | |
if (savedInstanceState.containsKey(PHOTO_STATE)) { | |
photo = BitmapHelper.byteArrayToBitmap(savedInstanceState.getByteArray(PHOTO_STATE)); | |
} | |
if (savedInstanceState.containsKey(THUMBNAIL_STATE)) { | |
thumbnail = BitmapHelper.byteArrayToBitmap(savedInstanceState.getByteArray(THUMBNAIL_STATE)); | |
} | |
if (savedInstanceState.containsKey(CAMERA_PIC_URI_STATE)) { | |
cameraPicUri = Uri.parse(savedInstanceState.getString(CAMERA_PIC_URI_STATE)); | |
} | |
rotateXDegrees = savedInstanceState.getInt(ROTATE_X_DEGREES_STATE); | |
} | |
@Override | |
protected void onDestroy() { | |
ImageView imageView = (ImageView) findViewById(R.id.sustainable_action_photo); | |
imageView.setImageBitmap(null); | |
super.onDestroy(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment