Skip to content

Instantly share code, notes, and snippets.

@codebreaker
Created April 30, 2013 06:59
Show Gist options
  • Save codebreaker/5487057 to your computer and use it in GitHub Desktop.
Save codebreaker/5487057 to your computer and use it in GitHub Desktop.
<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>
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();
}
}
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();
}
}
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