5) Storage Read/Write Permission
AndroidMainfest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
SplashScreen.java
private static final int MY_WRITE_EXTERNAL_PERMISSION_CODE = 1;
public boolean storagePermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_WRITE_EXTERNAL_PERMISSION_CODE);
}
else
return true;
}
return false;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == MY_WRITE_EXTERNAL_PERMISSION_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Intent intent = new Intent(SplashScreen.this, SearchActivity.class);
startActivity(intent);
}
else {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("You need to give permission to access storage in order to work this app.");
builder.setPositiveButton("GIVE PERMISSION", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
// Show permission request popup
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_WRITE_EXTERNAL_PERMISSION_CODE);
}
}
});
builder.setNegativeButton("CLOSE", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
finish();
}
});
builder.show();
}
}
}
6) Browse Image from Gallery and Show Image in ImageView
Subtasks:
i) Set ImageView Property like that all different Scale of Images are perfectly fit into different type of phone screen.
activity_save_photo.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SavePhoto">
<ImageView
android:id="@+id/imageView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="8dp"
android:layout_marginEnd="0dp"
android:layout_marginStart="0dp"
android:layout_marginTop="8dp"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
ii) Open chooser Intent which show only Image Files
SavePhoto.java
private int PICK_IMAGE_REQUEST = 1;
public void choosePhotoFromGallery(){
// Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
// intent.setType("image/*");
// startActivityForResult(intent, PICK_IMAGE_REQUEST);
// startActivityForResult(Intent.createChooser(intent, "Select Image"), PICK_IMAGE_REQUEST);
Intent getIntent = new Intent(Intent.ACTION_GET_CONTENT);
getIntent.setType("image/*");
Intent pickIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
pickIntent.setType("image/*");
Intent chooserIntent = Intent.createChooser(getIntent, "Select Image");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] {pickIntent});
startActivityForResult(chooserIntent, PICK_IMAGE_REQUEST);
}
iii) Selected Image will be shown in ImageView
Subtasks
a) Image will be get in form of URI from Image Chooser Intent.
b) We will find the path of image from Image URI
c) We will reduce the size of image but image quality will be almost same via ImageCompression class.
//iii)
SavePhoto.java
Uri selectedImageUri;
String picturePath;
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
//iii)a)
selectedImageUri = data.getData();
//iii)b)
picturePath = getPath(this, selectedImageUri );
if(!picturePath.matches( "Not found")) {
try {
//iii)c)
ImageCompression ic= new ImageCompression(this);
bitmap=ic.compressImage(picturePath);
selectedImage.setImageBitmap(bitmap);
} catch (Exception e) {
Toast.makeText(this, e.toString() , Toast.LENGTH_LONG).show();
}
}
else
Toast.makeText(this, "Image Path not found., Toast.LENGTH_SHORT).show();
}
}
//iii)b)
public static String getPath(Context context, Uri uri ) {
String result = null;
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = context.getContentResolver( ).query( uri, proj, null, null, null );
if(cursor != null){
if ( cursor.moveToFirst( ) ) {
int column_index = cursor.getColumnIndexOrThrow( proj[0] );
result = cursor.getString( column_index );
}
cursor.close( );
}
if(result == null) {
result = "Not found";
}
return result;
}
//iii)c)
ImageCompression.java
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.media.ExifInterface;
import android.os.AsyncTask;
import android.os.Environment;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* Created by HP-HP on 03-07-2015.
*/
public class ImageCompression extends AsyncTask<String, Void, String> {
private Context context;
private static final float maxHeight = 1280.0f;
private static final float maxWidth = 1280.0f;
public ImageCompression(Context context){
this.context=context;
}
@Override
protected String doInBackground(String... strings) {
if(strings.length == 0 || strings[0] == null)
return null;
//return compressImage(strings[0]);
return "";
}
protected void onPostExecute(String imagePath){
// imagePath is path of new compressed image.
}
public Bitmap compressImage(String imagePath) {
Bitmap scaledBitmap = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeFile(imagePath, options);
int actualHeight = options.outHeight;
int actualWidth = options.outWidth;
float imgRatio = (float) actualWidth / (float) actualHeight;
float maxRatio = maxWidth / maxHeight;
if (actualHeight > maxHeight || actualWidth > maxWidth) {
if (imgRatio < maxRatio) {
imgRatio = maxHeight / actualHeight;
actualWidth = (int) (imgRatio * actualWidth);
actualHeight = (int) maxHeight;
} else if (imgRatio > maxRatio) {
imgRatio = maxWidth / actualWidth;
actualHeight = (int) (imgRatio * actualHeight);
actualWidth = (int) maxWidth;
} else {
actualHeight = (int) maxHeight;
actualWidth = (int) maxWidth;
}
}
options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight);
options.inJustDecodeBounds = false;
options.inDither = false;
options.inPurgeable = true;
options.inInputShareable = true;
options.inTempStorage = new byte[16 * 1024];
try {
bmp = BitmapFactory.decodeFile(imagePath, options);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
try {
scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.RGB_565);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
float ratioX = actualWidth / (float) options.outWidth;
float ratioY = actualHeight / (float) options.outHeight;
float middleX = actualWidth / 2.0f;
float middleY = actualHeight / 2.0f;
Matrix scaleMatrix = new Matrix();
scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);
Canvas canvas = new Canvas(scaledBitmap);
canvas.setMatrix(scaleMatrix);
canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));
if(bmp!=null){
bmp.recycle();
}
ExifInterface exif;
try {
exif = new ExifInterface(imagePath);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
Matrix matrix = new Matrix();
if (orientation == 6) {
matrix.postRotate(90);
} else if (orientation == 3) {
matrix.postRotate(180);
} else if (orientation == 8) {
matrix.postRotate(270);
}
scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
} catch (IOException e) {
e.printStackTrace();
}
return scaledBitmap;
// ByteArrayOutputStream out = new ByteArrayOutputStream();
// scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
// return out.toByteArray();
// FileOutputStream out = null;
// String filepath = getFilename();
// try {
// out = new FileOutputStream(filepath);
//
// //write the compressed bitmap at the destination specified by filename.
// scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
//
// } catch (FileNotFoundException e) {
// e.printStackTrace();
// }
//
// return filepath;
}
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int heightRatio = Math.round((float) height / (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
final float totalPixels = width * height;
final float totalReqPixelsCap = reqWidth * reqHeight * 2;
while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
inSampleSize++;
}
return inSampleSize;
}
public String getFilename() {
File mediaStorageDir = new File(Environment.getExternalStorageDirectory()
+ "/Android/data/"
+ context.getApplicationContext().getPackageName()
+ "/Files/Compressed");
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
mediaStorageDir.mkdirs();
}
String mImageName="IMG_"+ String.valueOf(System.currentTimeMillis()) +".jpg";
String uriString = (mediaStorageDir.getAbsolutePath() + "/"+ mImageName);;
return uriString;
}
}
7) Textbox in Action Bar, AutoCompleteList and Input Legal Character
menu_save.xml
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_tag_editText"
android:title="Enter Tag"
app:showAsAction="always"
app:actionViewClass="android.widget.AutoCompleteTextView" />
<item
android:id="@+id/action_save"
android:title="Save"
app:showAsAction="always" />
</menu>
SavePhoto.java
private Menu menu;
AutoCompleteTextView tag_editText;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_save, menu);
this.menu = menu;
tag_editText = (AutoCompleteTextView)menu.findItem(R.id.action_tag_editText).getActionView();
tag_editText.getBackground().setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP);
tag_editText.setHint("Enter tag here...");
tag_editText.requestFocus();
ArrayAdapter<String> adapter = new ArrayAdapter<String> (this,android.R.layout.simple_list_item_1,uniqueFileName);
tag_editText.setAdapter(adapter);
tag_editText.setDropDownBackgroundResource(R.color.White);
tag_editText.setFilters(new InputFilter[] { filter });
return true;
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
if (source != null && !(LEGAL_CHARACTERSET.contains("" + source)) && source.length()==1){//source.length==1 because autocomplete selection was going to empty.
return "";
}
return null;
}
};
8) Save image in Storage. File name should be same as Tag Name. If Tag Name is repeating but File name can't be repeat therefor File name format should be Tag Name[count].jpeg
SavePhoto.java
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_save:
String tag=tag_editText.getText().toString();
if(tag.matches("")) {
Toast toast = Toast.makeText(this, "Please Enter Tag", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
else {
if (bitmap != null) {
if (saveToInternalStorage(bitmap, tag.trim())) {
Intent intent = new Intent();
intent.putExtra("savePhotoFileName", tag);
setResult(RESULT_OK, intent);
finish();
} else {
Toast toast = Toast.makeText(this, "File not saved", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
} else {
Toast toast = Toast.makeText(this, "Please select image", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
}
break;
default:
break;
}
return true;
}
private boolean saveToInternalStorage(Bitmap bitmapImage, String filename){
File directory = new File(Environment.getExternalStorageDirectory().getPath(), getResources().getString(R.string.tag_image_directory_name));
if (!directory.exists()) {
directory.mkdirs();
}
File mypath=new File(directory,filename + ".jpeg");
int i=2;
while(mypath.exists()){
mypath=new File(directory,filename + "["+ i + "].jpeg");
i++;
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mypath);
// Use the compress method on the BitMap object to write image to the OutputStream
bitmapImage.compress(Bitmap.CompressFormat.JPEG, 85, fos);
return true;
} catch (Exception e) {
Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show();
return false;
} finally {
try {
fos.close();
} catch (IOException e) {
Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show();
return false;
}
}
}
9) Back Arrow in Action Bar
SavePhoto.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_save_photo);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
break;
default:
break;
}
return true;
}
10)i) Passing Variable from Parent Activity (SearchActivity) to Child Activity (SavePhoto)
SearchActivity.java
int SAVE_PHOTO_REQUEST_CODE=1;//it will use when i add photo and then comeback to this activity. Child activity passing value to parent activity.
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_add_photo:
Intent intent=new Intent(SearchActivity.this,SavePhoto.class);
intent.putStringArrayListExtra("uniqueFileName",uniqueFileName);
startActivityForResult(intent,SAVE_PHOTO_REQUEST_CODE);
break;
default:
break;
}
return true;
}
SavePhoto.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_save_photo);
Intent intent = getIntent(); // get Intent which we set from Previous Activity
uniqueFileName=intent.getStringArrayListExtra("uniqueFileName");
}
10)ii) Passing Variable from Child Activity (SavePhoto) to Parent Activity (SearchActivity)
Note: Child Activity should be open via startActivityForResult from Parent Activity
SavePhoto.java
Save Success Message as follows:
Intent intent = new Intent();
intent.putExtra("savePhotoFileName", tag);
setResult(RESULT_OK, intent);
finish();
SearchActivity.java
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == SAVE_PHOTO_REQUEST_CODE && resultCode == RESULT_OK) {
String savePhotoFileName = data.getStringExtra("savePhotoFileName");
search.setQuery(savePhotoFileName, true);
}
}
AndroidMainfest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
SplashScreen.java
private static final int MY_WRITE_EXTERNAL_PERMISSION_CODE = 1;
public boolean storagePermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_WRITE_EXTERNAL_PERMISSION_CODE);
}
else
return true;
}
return false;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == MY_WRITE_EXTERNAL_PERMISSION_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Intent intent = new Intent(SplashScreen.this, SearchActivity.class);
startActivity(intent);
}
else {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("You need to give permission to access storage in order to work this app.");
builder.setPositiveButton("GIVE PERMISSION", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
// Show permission request popup
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_WRITE_EXTERNAL_PERMISSION_CODE);
}
}
});
builder.setNegativeButton("CLOSE", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
finish();
}
});
builder.show();
}
}
}
6) Browse Image from Gallery and Show Image in ImageView
Subtasks:
i) Set ImageView Property like that all different Scale of Images are perfectly fit into different type of phone screen.
activity_save_photo.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SavePhoto">
<ImageView
android:id="@+id/imageView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="8dp"
android:layout_marginEnd="0dp"
android:layout_marginStart="0dp"
android:layout_marginTop="8dp"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
ii) Open chooser Intent which show only Image Files
SavePhoto.java
private int PICK_IMAGE_REQUEST = 1;
public void choosePhotoFromGallery(){
// Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
// intent.setType("image/*");
// startActivityForResult(intent, PICK_IMAGE_REQUEST);
// startActivityForResult(Intent.createChooser(intent, "Select Image"), PICK_IMAGE_REQUEST);
Intent getIntent = new Intent(Intent.ACTION_GET_CONTENT);
getIntent.setType("image/*");
Intent pickIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
pickIntent.setType("image/*");
Intent chooserIntent = Intent.createChooser(getIntent, "Select Image");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] {pickIntent});
startActivityForResult(chooserIntent, PICK_IMAGE_REQUEST);
}
iii) Selected Image will be shown in ImageView
Subtasks
a) Image will be get in form of URI from Image Chooser Intent.
b) We will find the path of image from Image URI
c) We will reduce the size of image but image quality will be almost same via ImageCompression class.
//iii)
SavePhoto.java
Uri selectedImageUri;
String picturePath;
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
//iii)a)
selectedImageUri = data.getData();
//iii)b)
picturePath = getPath(this, selectedImageUri );
if(!picturePath.matches( "Not found")) {
try {
//iii)c)
ImageCompression ic= new ImageCompression(this);
bitmap=ic.compressImage(picturePath);
selectedImage.setImageBitmap(bitmap);
} catch (Exception e) {
Toast.makeText(this, e.toString() , Toast.LENGTH_LONG).show();
}
}
else
Toast.makeText(this, "Image Path not found., Toast.LENGTH_SHORT).show();
}
}
//iii)b)
public static String getPath(Context context, Uri uri ) {
String result = null;
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = context.getContentResolver( ).query( uri, proj, null, null, null );
if(cursor != null){
if ( cursor.moveToFirst( ) ) {
int column_index = cursor.getColumnIndexOrThrow( proj[0] );
result = cursor.getString( column_index );
}
cursor.close( );
}
if(result == null) {
result = "Not found";
}
return result;
}
//iii)c)
ImageCompression.java
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.media.ExifInterface;
import android.os.AsyncTask;
import android.os.Environment;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* Created by HP-HP on 03-07-2015.
*/
public class ImageCompression extends AsyncTask<String, Void, String> {
private Context context;
private static final float maxHeight = 1280.0f;
private static final float maxWidth = 1280.0f;
public ImageCompression(Context context){
this.context=context;
}
@Override
protected String doInBackground(String... strings) {
if(strings.length == 0 || strings[0] == null)
return null;
//return compressImage(strings[0]);
return "";
}
protected void onPostExecute(String imagePath){
// imagePath is path of new compressed image.
}
public Bitmap compressImage(String imagePath) {
Bitmap scaledBitmap = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeFile(imagePath, options);
int actualHeight = options.outHeight;
int actualWidth = options.outWidth;
float imgRatio = (float) actualWidth / (float) actualHeight;
float maxRatio = maxWidth / maxHeight;
if (actualHeight > maxHeight || actualWidth > maxWidth) {
if (imgRatio < maxRatio) {
imgRatio = maxHeight / actualHeight;
actualWidth = (int) (imgRatio * actualWidth);
actualHeight = (int) maxHeight;
} else if (imgRatio > maxRatio) {
imgRatio = maxWidth / actualWidth;
actualHeight = (int) (imgRatio * actualHeight);
actualWidth = (int) maxWidth;
} else {
actualHeight = (int) maxHeight;
actualWidth = (int) maxWidth;
}
}
options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight);
options.inJustDecodeBounds = false;
options.inDither = false;
options.inPurgeable = true;
options.inInputShareable = true;
options.inTempStorage = new byte[16 * 1024];
try {
bmp = BitmapFactory.decodeFile(imagePath, options);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
try {
scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.RGB_565);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
float ratioX = actualWidth / (float) options.outWidth;
float ratioY = actualHeight / (float) options.outHeight;
float middleX = actualWidth / 2.0f;
float middleY = actualHeight / 2.0f;
Matrix scaleMatrix = new Matrix();
scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);
Canvas canvas = new Canvas(scaledBitmap);
canvas.setMatrix(scaleMatrix);
canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));
if(bmp!=null){
bmp.recycle();
}
ExifInterface exif;
try {
exif = new ExifInterface(imagePath);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
Matrix matrix = new Matrix();
if (orientation == 6) {
matrix.postRotate(90);
} else if (orientation == 3) {
matrix.postRotate(180);
} else if (orientation == 8) {
matrix.postRotate(270);
}
scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
} catch (IOException e) {
e.printStackTrace();
}
return scaledBitmap;
// ByteArrayOutputStream out = new ByteArrayOutputStream();
// scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
// return out.toByteArray();
// FileOutputStream out = null;
// String filepath = getFilename();
// try {
// out = new FileOutputStream(filepath);
//
// //write the compressed bitmap at the destination specified by filename.
// scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
//
// } catch (FileNotFoundException e) {
// e.printStackTrace();
// }
//
// return filepath;
}
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int heightRatio = Math.round((float) height / (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
final float totalPixels = width * height;
final float totalReqPixelsCap = reqWidth * reqHeight * 2;
while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
inSampleSize++;
}
return inSampleSize;
}
public String getFilename() {
File mediaStorageDir = new File(Environment.getExternalStorageDirectory()
+ "/Android/data/"
+ context.getApplicationContext().getPackageName()
+ "/Files/Compressed");
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
mediaStorageDir.mkdirs();
}
String mImageName="IMG_"+ String.valueOf(System.currentTimeMillis()) +".jpg";
String uriString = (mediaStorageDir.getAbsolutePath() + "/"+ mImageName);;
return uriString;
}
}
7) Textbox in Action Bar, AutoCompleteList and Input Legal Character
menu_save.xml
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_tag_editText"
android:title="Enter Tag"
app:showAsAction="always"
app:actionViewClass="android.widget.AutoCompleteTextView" />
<item
android:id="@+id/action_save"
android:title="Save"
app:showAsAction="always" />
</menu>
SavePhoto.java
private Menu menu;
AutoCompleteTextView tag_editText;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_save, menu);
this.menu = menu;
tag_editText = (AutoCompleteTextView)menu.findItem(R.id.action_tag_editText).getActionView();
tag_editText.getBackground().setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP);
tag_editText.setHint("Enter tag here...");
tag_editText.requestFocus();
ArrayAdapter<String> adapter = new ArrayAdapter<String> (this,android.R.layout.simple_list_item_1,uniqueFileName);
tag_editText.setAdapter(adapter);
tag_editText.setDropDownBackgroundResource(R.color.White);
tag_editText.setFilters(new InputFilter[] { filter });
return true;
}
private String LEGAL_CHARACTERSET = " 1234567890().,'@#$&ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";private InputFilter filter = new InputFilter() {
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
if (source != null && !(LEGAL_CHARACTERSET.contains("" + source)) && source.length()==1){//source.length==1 because autocomplete selection was going to empty.
return "";
}
return null;
}
};
8) Save image in Storage. File name should be same as Tag Name. If Tag Name is repeating but File name can't be repeat therefor File name format should be Tag Name[count].jpeg
SavePhoto.java
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_save:
String tag=tag_editText.getText().toString();
if(tag.matches("")) {
Toast toast = Toast.makeText(this, "Please Enter Tag", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
else {
if (bitmap != null) {
if (saveToInternalStorage(bitmap, tag.trim())) {
Intent intent = new Intent();
intent.putExtra("savePhotoFileName", tag);
setResult(RESULT_OK, intent);
finish();
} else {
Toast toast = Toast.makeText(this, "File not saved", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
} else {
Toast toast = Toast.makeText(this, "Please select image", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
}
break;
default:
break;
}
return true;
}
private boolean saveToInternalStorage(Bitmap bitmapImage, String filename){
File directory = new File(Environment.getExternalStorageDirectory().getPath(), getResources().getString(R.string.tag_image_directory_name));
if (!directory.exists()) {
directory.mkdirs();
}
File mypath=new File(directory,filename + ".jpeg");
int i=2;
while(mypath.exists()){
mypath=new File(directory,filename + "["+ i + "].jpeg");
i++;
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mypath);
// Use the compress method on the BitMap object to write image to the OutputStream
bitmapImage.compress(Bitmap.CompressFormat.JPEG, 85, fos);
return true;
} catch (Exception e) {
Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show();
return false;
} finally {
try {
fos.close();
} catch (IOException e) {
Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show();
return false;
}
}
}
9) Back Arrow in Action Bar
SavePhoto.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_save_photo);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
break;
default:
break;
}
return true;
}
10)i) Passing Variable from Parent Activity (SearchActivity) to Child Activity (SavePhoto)
SearchActivity.java
int SAVE_PHOTO_REQUEST_CODE=1;//it will use when i add photo and then comeback to this activity. Child activity passing value to parent activity.
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_add_photo:
Intent intent=new Intent(SearchActivity.this,SavePhoto.class);
intent.putStringArrayListExtra("uniqueFileName",uniqueFileName);
startActivityForResult(intent,SAVE_PHOTO_REQUEST_CODE);
break;
default:
break;
}
return true;
}
SavePhoto.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_save_photo);
Intent intent = getIntent(); // get Intent which we set from Previous Activity
uniqueFileName=intent.getStringArrayListExtra("uniqueFileName");
}
10)ii) Passing Variable from Child Activity (SavePhoto) to Parent Activity (SearchActivity)
Note: Child Activity should be open via startActivityForResult from Parent Activity
SavePhoto.java
Save Success Message as follows:
Intent intent = new Intent();
intent.putExtra("savePhotoFileName", tag);
setResult(RESULT_OK, intent);
finish();
SearchActivity.java
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == SAVE_PHOTO_REQUEST_CODE && resultCode == RESULT_OK) {
String savePhotoFileName = data.getStringExtra("savePhotoFileName");
search.setQuery(savePhotoFileName, true);
}
}
No comments:
Post a Comment