package nz.co.android.cowseye.utility;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
public class Utils {
public static final int HTTP_OK = 200;
public static final int HTTP_LOGIC_ERROR = 400;
public static final int HTTP_SERVER_ERROR = 500;
//
public static final int MAX_PREVIEW_IMAGE_SIZE_WIDTH = 1600;
public static final int MAX_PREVIEW_IMAGE_SIZE_HEIGHT = 1600;
// public static final int IMAGE_SIZE_WIDTH = 1200;
// public static final int IMAGE_SIZE_HEIGHT = 800;
// public static final int MAX_GALLERY_IMAGE_SIZE = 1600;
//Camera Constants
public static final File DIR_MEDIA_STORAGE = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "RiverWatch");
public static final String CAMERA_FILE_NAME_PREFIX = "RiverWatch_";
/** Create a file Uri for saving an image or video */
public static Uri getNewCameraFileUri() {
String filename = CAMERA_FILE_NAME_PREFIX + new Date().getTime() + ".jpg";
return Uri.fromFile(getOutputMediaFile(filename));
}
/** Create a File for saving an image or video */
public static File getOutputMediaFile(String filename) {
// TODO: To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
// Create the storage directory if it does not exist
if (!DIR_MEDIA_STORAGE.exists()){
if (!DIR_MEDIA_STORAGE.mkdirs()){
Log.e("DetailsActivity", "failed to create directory");
return null;
}
}
// Create a media file name
File mediaFile = new File(DIR_MEDIA_STORAGE.getPath() + File.separator + filename);
return mediaFile;
}
/**
* Playing around with full-size images -> OOMErrors. Bad.
* So, let's downscale them
* @param uri - holds the path to the bitmap
* @return the scaled-down bitmap.
* @throws IOException
*/
public static Bitmap getAppFriendlyBitmap(Uri uri, ContentResolver contentResolver) throws IOException {
Bitmap b = null;
InputStream inputStream = null;
Cursor cur = null;
try {
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
inputStream = contentResolver.openInputStream(uri);
BitmapFactory.decodeStream(inputStream, null, o);
inputStream.close();
int scale = 1;
//resize
if (o.outHeight > MAX_PREVIEW_IMAGE_SIZE_HEIGHT || o.outWidth > MAX_PREVIEW_IMAGE_SIZE_WIDTH) {
scale = (int)Math.pow(2, (int) Math.round(Math.log(MAX_PREVIEW_IMAGE_SIZE_WIDTH / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
}
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
inputStream = contentResolver.openInputStream(uri);
b = BitmapFactory.decodeStream(inputStream, null, o2);
inputStream.close();
//re-orient
float rotation = rotationForImage(uri);
// Log.d("UTILS", "rotation : "+rotation);
if (rotation != 0f) {
Matrix matrix = new Matrix();
matrix.preRotate(rotation);
b = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(),
matrix, true);
}
else {
String[] orientationColumn = {MediaStore.Images.Media.ORIENTATION};
cur = contentResolver.query(uri, orientationColumn, null, null, null);
int orientation = -1;
if (cur != null && cur.moveToFirst()) {
orientation = cur.getInt(cur.getColumnIndex(orientationColumn[0]));
// Log.d("UTILS", "orientation : "+orientation);
if (orientation > 0) {
Matrix matrix = new Matrix();
matrix.preRotate(orientation);
b = Bitmap.createBitmap(b, 0, 0, b.getWidth(),
b.getHeight(), matrix, true);
}
}
}
}
finally {
if (cur != null && !cur.isClosed()) {
cur.close();
}
}
return b;
}
/**
* Scales the bitmap
* @return the scaled-down bitmap.
* @throws IOException
*/
public static Bitmap scaleBitmap(InputStream inputStream, int scale) throws IOException {
Bitmap b = null;
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
b = BitmapFactory.decodeStream(inputStream, null, o2);
inputStream.close();
return b;
}
/** Tries to return the rotation for an image if it has the associated EXIF data */
public static float rotationForImage(Uri uri) {
if (uri.getScheme().equals("file")) {
try {
ExifInterface exif = new ExifInterface(uri.getPath());
int rotation = (int)exifOrientationToDegrees(
exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL));
return rotation;
} catch (IOException e) {
Log.e("Utils", "Error checking exif", e);
}
}
return 0f;
}
/* Converts ExifOrientation data to degrees */
private static float exifOrientationToDegrees(int exifOrientation) {
if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) {
return 90;
} else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {
return 180;
} else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {
return 270;
}
return 0;
}
/** Goes back in the activity stack
* Simply finishes the current activity */
public static class BackEventOnClickListener implements OnClickListener{
private Activity activity;
/**
* @param a - Activity to finish upon click
*/
public BackEventOnClickListener(Activity a){
this.activity = a;
}
@Override
public void onClick(View v) {
//clicking back so set the result to cancelled
Intent intent=new Intent();
activity.setResult(Activity.RESULT_CANCELED, intent);
activity.finish();
}
}
/** Finishes the current activity and starts a new intent to a new activity upon click */
public static class StartNextActivityEventOnClickListener implements OnClickListener{
private Activity activity;
private Intent activityToStartIntent;
/**
* @param a - Coming from this Activity
* @param activityToClass - Class of the activity to start
*/
public StartNextActivityEventOnClickListener(Activity a, Class<?> activityToClass){
activityToStartIntent = constructActivityStartIntent(a, activityToClass);
this.activity = a;
}
/**
* @param a - Coming from this Activity
* @param activityToStartIntent - Intent to start the new activity
*/
public StartNextActivityEventOnClickListener(Activity a, Intent activityToStartIntent){
this.activityToStartIntent = activityToStartIntent;
this.activity = a;
}
@Override
public void onClick(View v) {
activity.startActivity(activityToStartIntent);
}
}
/**
* Helper method for creating an intent to go from one activity to another activity
* @param activityFrom - the activity you are coming from
* @param activityToClass - the class of the activity to go to
* @return
*/
public static Intent constructActivityStartIntent(Activity activityFrom, Class<?> activityToClass){
return new Intent(activityFrom, activityToClass);
}
}