Fun With Computers
Wednesday, June 1, 2022
Wednesday, September 8, 2021
Decide Processor
https://laptopmedia.com/in/top-laptop-cpu-ranking/
11th-generation-intel-core-i5-processors list
Rank-16
Intel® Core™ i5-11260H Processor Launched Q2'21 6 4.40 GHz 12 MB Intel® Smart Cache
10th-generation-intel-core-i5-processors list
Rank-22
Intel® Core™ i5-11400H Processor Launched Q2'21 6 4.50 GHz 12 MB Intel® Smart Cache
Rank-26
Intel® Core™ i5-10500H Processor Launched Q4'20 6 4.50 GHz 2.50 GHz 12 MB Intel® Smart Cache
10th-generation-intel-core-i7-processors list
Rank-17
Intel® Core™ i7-10875H Processor Launched Q2'20 8 5.10 GHz 2.30 GHz 16 MB Intel® Smart Cache
Rank-31
Intel® Core™ i7-10750H Processor Launched Q2'20 6 5.00 GHz 2.60 GHz 12 MB Intel® Smart Cache
Lenovo Legion 5 Core i7 10th Gen - (16 GB/512 GB SSD/Windows 10 Home/4 GB Graphics/NVIDIA GeForce GTX 1650/120 Hz) 15IMH05 Gaming Laptop (15.6 Inch, Phantom Black, 2.3 KG
11th-generation-intel-core-i7-processors list
Specs table
Intel Core i7-10875H | Intel Core i7-10750H | |
---|---|---|
Architecture | Comet Lake H | Comet Lake H |
Cores / Threads | 8/16 | 6/12 |
Clock Speeds – Base/Boost | 2.30 – 5.10GHz | 2.60 – 5.00GHz |
Cache | 16MB | 12MB |
Lithography | 14nm | 14nm |
TDP | 45W | 45W |
Memory type | DDR4-2933MHz | DDR4-2933MHz |
Integrated GPU | Intel UHD Graphics 630 | Intel UHD Graphics 630 |
No. of Cores/ Max Turbo Frequency/ Processor Base Frequency/ Cache
https://laptopmedia.com/in/laptop-specs/lenovo-legion-5i-15-887/
https://www.investorsunderground.com/how-to-build-a-day-trading-computer/
Sunday, April 12, 2020
Friday, April 10, 2020
My Quick Find Gallery (Part 5 - Share, Delete and Update Image)
If your targetSdkVersion >= 24, then we have to use FileProvider class to give access to the particular file or folder to make them accessible for other apps.
Steps to replace file:// URI with content:// URI:
i) Add a FileProvider <provider> tag in AndroidManifest.xml under <application> tag:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
...
<application
...
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.myfileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider_paths" />
</provider>
</application>
</manifest>
ii) Then create a file_provider_paths.xml file in res/xml folder:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="share" path="/" />
</paths>
iii) ShowPhoto.java
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_share:
File file = new File(searchFilesPath.get(selectedImagePosition));
Intent shareIntent = new Intent(Intent.ACTION_SEND);
Uri picUri = FileProvider.getUriForFile(this, "com.myfileprovider", file);
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.setType("image/*");
shareIntent.putExtra(Intent.EXTRA_STREAM, picUri);
startActivity(Intent.createChooser(shareIntent, "Share with"));
break;
default:
break;
}
return true;
}
13) Delete Image
Call function alert() on Delete Button in ShowPhoto.java
public void alert(){
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle("Delete Photo");
alertDialogBuilder
.setMessage("are you sure you want to delete ?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
delete();
}
})
.setNegativeButton("No",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
public void delete(){
File fdelete = new File(searchFilesPath.get(selectedImagePosition));
if (fdelete.exists()) {
if (fdelete.delete()) {
//Toast.makeText(this, "Successfully Deleted", Toast.LENGTH_SHORT).show();
Intent intent = new Intent();
setResult(RESULT_OK, intent);
finish();
} else {
Toast.makeText(this, "File not deleted", Toast.LENGTH_LONG).show();
}
}
}
14) Update Image
Call function alert() on Update Button in EditPhoto.java
public void alert(){
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle("Update Tag or Photo");
alertDialogBuilder
.setMessage("are you sure you want to update ?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
update();
}
})
.setNegativeButton("No",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
public void update(){
String tag=tag_editText.getText().toString();
if(tag.matches("")) {
Toast.makeText(this, "Please Enter Tag", Toast.LENGTH_LONG).show();
}
else {
if(replaceToInternalStorage(bitmap,tag.trim())) {
Intent intent = new Intent();
setResult(RESULT_OK, intent);
finish();
}
else {
Toast toast = Toast.makeText(this, "File not updated", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
}
}
private boolean replaceToInternalStorage(Bitmap bitmapImage, String filename) {
if (filename.equals(editFileName) && isImageChange == 0)
return true;
else if (!filename.equals(editFileName) && isImageChange == 0) {
File oldFilePath = new File(editFilePath);
File directory = oldFilePath.getParentFile();
File newFilePath = new File(directory, filename + ".jpeg");
int i = 2;
while (newFilePath.exists()) {
newFilePath = new File(directory, filename + "[" + i + "].jpeg");
i++;
}
oldFilePath.renameTo(newFilePath);
return true;
}
else if (isImageChange == 1) {
if(delete(editFilePath)) {
File mypath = new File(editFilePath);
if(!filename.equals(editFileName)){
File oldFile = new File(editFilePath);
File directory = oldFile.getParentFile();
File newFile = new File(directory, filename + ".jpeg");
int i = 2;
while (newFile.exists()) {
newFile = new File(directory, filename + "[" + i + "].jpeg");
i++;
}
mypath=newFile;
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mypath);
bitmapImage.compress(Bitmap.CompressFormat.JPEG, 85, fos);
return true;
} catch (Exception e) {
Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show();
return false;//e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show();
return false;//e.printStackTrace();
}
}
}
else
return false;
}
else
return false;
}
My Quick Find Gallery (Part 4 - Show Image with Zoom, Drag and Slide Features)
Subtasks:
i) Get the set of images and selected image position from Parent Activity and show selected image in ImageView.
activity_show_photo.xml
<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=".ShowPhoto">
<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>
ShowPhoto.java
ImageView selectedImage;
ArrayList<String> searchFilesPath;
ArrayList<String> searchFilesName;
int selectedImagePosition;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_photo);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
selectedImage = (ImageView) findViewById(R.id.imageView);
try {
Intent intent = getIntent(); // get Intent which we set from Previous Activity
selectedImagePosition = intent.getIntExtra("selectedImagePosition",0);
searchFilesPath=intent.getStringArrayListExtra("searchFilesPath");
searchFilesName=intent.getStringArrayListExtra("searchFilesName");
//from file path
Bitmap myBitmap = BitmapFactory.decodeFile(searchFilesPath.get(selectedImagePosition));
selectedImage.setImageBitmap(myBitmap);
getSupportActionBar().setTitle(searchFilesName.get(selectedImagePosition));
}
catch(Exception e) {
Toast.makeText(this, e.toString(), Toast.LENGTH_LONG).show();
}
}
ii) setOnTouchListener to ImageView for Zoom, Drag and Slide Features.
ShowPhoto.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_photo);
selectedImage = (ImageView) findViewById(R.id.imageView);
selectedImage.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView) v;
view.bringToFront();
viewTransformation(view, event);
return true;
}
});
}
//====================================================================
//ImageView Zoom-in and Zoom-Out
//ZOOM (two finger) / ROTATION (two finger) / DRAG (Single finger)
//====================================================================
float[] lastEvent = null;
float d = 0f;
float newRot = 0f;
private boolean isZoomAndRotate;
private boolean isOutSide;
private static final int NONE = 0;
private static final int DRAG = 1;
private static final int ZOOM = 2;
private int mode = NONE;
private PointF start = new PointF();
private PointF mid = new PointF();
float oldDist = 1f;
private float xCoOrdinate, yCoOrdinate;
private int isPreviousMode = NONE;
private void viewTransformation(View view, MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
// executed after the user touch on the screen
xCoOrdinate = view.getX() - event.getRawX();
yCoOrdinate = view.getY() - event.getRawY();
start.set(event.getX(), event.getY());
isOutSide = false;
mode = DRAG;
lastEvent = null;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
if (oldDist > 10f) {
midPoint(mid, event);
mode = ZOOM;
}
lastEvent = new float[4];
lastEvent[0] = event.getX(0);
lastEvent[1] = event.getX(1);
lastEvent[2] = event.getY(0);
lastEvent[3] = event.getY(1);
//d = rotation(event);
break;
case MotionEvent.ACTION_UP:
// executed after the user release the touch on the screen
isZoomAndRotate = false;
if (mode == DRAG) {
float x = event.getX();
float y = event.getY();
if (isPreviousMode != ZOOM) {
if (start.x - x > 1) { //using start.x-x>1, not start.x>x because start.x>x executes in case of tapping also ()
selectedImagePosition = selectedImagePosition + 1;
if (selectedImagePosition <= maxImagePosition) {
selectedImage.setImageBitmap(BitmapFactory.decodeFile(searchFilesPath.get(selectedImagePosition)));
getSupportActionBar().setTitle(searchFilesName.get(selectedImagePosition));
isPreviousMode = NONE;
} else
selectedImagePosition = maxImagePosition;//when reach to last picture and thenafter move the finger again and again then selectedImagePosition values go to very high one by one therefore put the last picture index
} else if (x - start.x > 1) {
selectedImagePosition = selectedImagePosition - 1;
if (selectedImagePosition >= 0) {
selectedImage.setImageBitmap(BitmapFactory.decodeFile(searchFilesPath.get(selectedImagePosition)));
getSupportActionBar().setTitle(searchFilesName.get(selectedImagePosition));
isPreviousMode = NONE;
} else
selectedImagePosition = 0;
}
}
}
case MotionEvent.ACTION_OUTSIDE:
isOutSide = true;
mode = NONE;
lastEvent = null;
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
lastEvent = null;
break;
case MotionEvent.ACTION_MOVE:
// executed when user move the finger on the screen
if (!isOutSide) {
if (mode == DRAG) {
isZoomAndRotate = false;
if(isPreviousMode == ZOOM)
view.animate().x(event.getRawX() + xCoOrdinate).y(event.getRawY() + yCoOrdinate).setDuration(0).start();
}
if (mode == ZOOM && event.getPointerCount() == 2) {
float newDist1 = spacing(event);
if (newDist1 > 10f) {
float scale = newDist1 / oldDist * view.getScaleX();
view.setScaleX(scale);
view.setScaleY(scale);
isPreviousMode = ZOOM;
}
if (lastEvent != null) {
//newRot = rotation(event);
//view.setRotation((float) (view.getRotation() + (newRot - d)));
}
}
}
break;
}
}
private float rotation(MotionEvent event) {
double delta_x = (event.getX(0) - event.getX(1));
double delta_y = (event.getY(0) - event.getY(1));
double radians = Math.atan2(delta_y, delta_x);
return (float) Math.toDegrees(radians);
}
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (int) Math.sqrt(x * x + y * y);
}
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
}
Wednesday, April 8, 2020
My Quick Find Gallery (Part 3 - Storage Permission & Browse, Tag and Save Image)
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);
}
}
Friday, April 3, 2020
My Quick Find Gallery (Part 2 - GridView to Show Images)
4) Show images in GridView and after clicking a image, move to Display Photo Screen
We show data in gridview via adapter. Adapter is a medium between Data and Gridview.
Data ( eg:Array) ------> Adapter -------> GridView
Subtasks:
i) Our Data i.e, image files present in a particular folder. All Files path of that folder will be stored in a string array variable (for transferring string array to adabter to Gridview):
Subtasks:
a) A list of files of a folder will be stored in a File Array variable
b) Files in a File array variable will be sorted by modification date (new modified file comes first)
c) Fetch Absolute path of files from Sorted File Array Variable and store into string array variable
d) Fetch File Name without extension of files from Sorted File Array Variable and store into another string array variable
e) Files Name is repeated in a string array therefor make a string array where all file names are unique. That will be use in suggestion list in search box.
ii) Actual Data which will be shown in GridView will come by three different actions of user. We will discuss in point iv) later. Now move to Adabter. Data transfer Array Data to Adabter via below line code:
ImageCustomAdapter customAdapter = new ImageCustomAdapter(getApplicationContext(), ArrayList<String> variable name);
iii) Suppose Gridview will show 3 images in a row. Data transfer Adapter to GridView via this line code: mImageGrid.setAdapter(customAdapter);
Note: Array Data ---> Adabter ------> GridView
public void showImageInGrid(ArrayList<String> imagesPath){
ImageCustomAdapter customAdapter = new ImageCustomAdapter(getApplicationContext(),imagesPath);
mImageGrid.setAdapter(customAdapter);
}
iv) GridView displays images when
a) click the Show All Button: All Images will show
b) File Name is selected from suggestion list of search box and then click the search button: Suggestion List File Name matches Images will show
c) Random file name enter in search box and then click the search button: Random File Name contains Images will show
Note: Text Change in Search Box should not searched because communication break to writing in search box due to system searching & showing image files in grid view after each letter typing in search box, make system inconstancy state
v) GridView Item Click event
SearchActivity.java
ArrayList<String> allFilePath;// list of all file paths
ArrayList<String> allFileName;// list of all file name
ArrayList<String> uniqueFileName;// list of unique file name without extension
public void getAllFilesPathAndName() {
allFilePath = new ArrayList<String>();
allFileName = new ArrayList<String>();
try {
//i)a)
//path to /internal storage/ERS/0/my directory
File directory = new File(Environment.getExternalStorageDirectory().getPath(), getResources().getString(R.string.tag_image_directory_name));
if (directory.isDirectory()) {
File[] listFile = directory.listFiles();
//i)b)
Arrays.sort(listFile, new Comparator<File>() {
@Override
public int compare(File a, File b) {
if(a.lastModified() < b.lastModified() )
return 1;
if(a.lastModified() > b.lastModified() )
return -1;
return 0;
}
});
//i)c)&d)
for (int i = 0; i < listFile.length; i++) {
allFilePath.add(listFile[i].getAbsolutePath());
allFileName.add(getFileNameWithoutExtension(listFile[i].getName()));
}
}
//i)e)
List<String> allfilename = this.allFileName;
Set<String> uniquefilename = new HashSet<String>(allfilename);//unique filename
this.uniqueFileName=new ArrayList<String>(uniquefilename);
}
catch(Exception e){
Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show();
}
}
//i)d)
public String getFileNameWithoutExtension(String fileName){
String[] fileNameParts;
if(fileName.contains("[")){
fileNameParts = fileName.split("\\[");
return fileNameParts[0];
}
else{
int pos = fileName.lastIndexOf(".");//"\\." is not working
return fileName.substring(0, pos);
}
}
//ii)
galleryitem.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="1dp"
android:orientation="vertical">
<ImageView
android:id="@+id/thumbImage"
android:layout_width="match_parent"
android:layout_height="100dp"
android:scaleType="fitXY"
android:layout_gravity="center_horizontal"/>
</LinearLayout>
ImageCustomAdapter.java
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.ThumbnailUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import java.util.ArrayList;
public class ImageCustomAdapter extends BaseAdapter {
Context mContext;
ArrayList<String> mFileArray;// list of file paths
LayoutInflater mInflater;
public int selectedImage = 0;
public ImageCustomAdapter(Context applicationContext, ArrayList<String> fileArray) {
this.mContext = applicationContext;
this.mFileArray = fileArray;
mInflater = (LayoutInflater.from(applicationContext));
}
@Override
public int getCount() {
return mFileArray.size();
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
convertView = mInflater.inflate(R.layout.galleryitem, null); // inflate the layout
ImageView icon = (ImageView) convertView.findViewById(R.id.thumbImage); // get the reference of ImageView
Bitmap myBitmap = BitmapFactory.decodeFile(mFileArray.get(i));
Bitmap thumbnail = ThumbnailUtils.extractThumbnail(myBitmap,300,300);
//Bitmap scaled = Bitmap.createScaledBitmap(myBitmap, 100, 100, true);
icon.setImageBitmap(thumbnail);
return convertView;
}
}
//iii)
<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=".SearchActivity">
<GridView
android:id="@+id/ImageGrid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:numColumns="3"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
</android.support.constraint.ConstraintLayout>.
//iv)
SearchActivity.java
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
//iv)a)
case R.id.action_show_all:
search.setQuery("", false);//this is because when i am adding photo then search box has adding file name. when i click on show all button then should be it clear it.
isSearchAction=1;//Show All
if(getFilePathArray(isSearchAction,"")>0) {
showImageInGrid(searchFilesPath);////ByFilePathArrayStringAndImageCustomAdapter
search.clearFocus();
}
else {
mImageGrid.setAdapter(null);
emptyResult();
}
break;
default:
break;
}
return true;
}
ArrayList<String> searchFilesPath;// list of filter files path
ArrayList<String> searchFilesName;// list of filter files name
public int getFilePathArray(int isSearchAction, String searchTag){
searchFilesPath=new ArrayList<String>();
searchFilesName=new ArrayList<String>();
//iv)a)
if(isSearchAction==1) {//show all
searchFilesPath=allFilePath;
searchFilesName=allFileName;
}
//iv)b)
else if(isSearchAction==2) {//autocomplete name
for (int i = 0; i < allFileName.size(); i++) {
if (allFileName.get(i).equalsIgnoreCase(searchTag)) {
searchFilesPath.add(allFilePath.get(i));
searchFilesName.add(allFileName.get(i));
}
}
}
//iv)c)
else if(isSearchAction==3){//random name
for (int i = 0; i < allFileName.size(); i++) {
if (allFileName.get(i).toLowerCase().contains(searchTag.toLowerCase())) {
searchFilesPath.add(allFilePath.get(i));
searchFilesName.add(allFileName.get(i));
}
}
} else{ }
return searchFilesPath.size();
}
public void showImageInGrid(ArrayList<String> searchFilesPath){ //ByFilePathArrayStringAndImageCustomAdapter
mImageGrid.setAdapter(null);
ImageCustomAdapter customAdapter = new ImageCustomAdapter(getApplicationContext(), searchFilesPath);
mImageGrid.setAdapter(customAdapter);
}
private void emptyResult() {
Toast toast = Toast.makeText(this, "No image found", Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
//v)
SearchActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
mImageGrid = findViewById(R.id.ImageGrid);
//GridView Item Click Event
mImageGrid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(SearchActivity.this, ShowPhoto.class);
intent.putExtra("selectedImagePosition", position);
intent.putStringArrayListExtra("searchFilesPath",searchFilesPath);
intent.putStringArrayListExtra("searchFilesName",searchFilesName);
startActivity(intent); // start Intent
}
});
}