Skip to main content

How to create Image Gallery App using MediaStore in Android



In the last tutorial, we have learned about how to create Video Gallery app in android. In this tutorial, we are going to create an Image Gallery App for Android.We can also add pinch zoom, crop, resize, delete and other functionality as well but we do not discuss these function in this tutorial because it will make the development complex and hard to understand.

 Create Project For Image Gallery


First of all, create a project with the name of Image Gallery and choose default empty activity. Once your project will be created it will look like as given below.











Image Gallery Project Structure
Image Gallery App Project Structure

So our project gets created with default man activity and layout file, now we have to work further to add the functionality to our Image Gallery App so that it can show the all image from user sd card.

 You may like this:


https://www.nplix.com/create-image-video-thumbnail-android/

Add RecylerView to activity_main.xml



So here we are going to add a Recycler view to our main layout file which contains all Photo of our SD card. But before adding the Recycler view we have to add the library in our app level gardle file.

So add below line at the app level build.gradle file.


compile 'com.android.support:recyclerview-v7:24.2.0'


we also required a card view for our item inside recycler view so we need to add other dependencies in our Gradle file.


compile 'com.android.support:cardview-v7:24.2.0'


The last dependency we are adding here is glide library which we are going to use to retrieve our thumbnail from the photo and showing it in the image view. So add the below library also in our app level build.gardle file.


compile 'com.github.bumptech.glide:glide:3.7.0'

So after adding the dependency to our build.gardle file it will look like as given below.

 dependencies {  
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:24.2.1'
compile 'com.android.support:cardview-v7:24.2.0'
compile 'com.android.support:recyclerview-v7:24.2.0'
compile 'com.github.bumptech.glide:glide:3.7.0'
testCompile 'junit:junit:4.12'
}


Add the above dependency and click on sync button to sync the project with added dependency.
Our project is ready now we can add our recycler view to activity_main.xml layout file so open the activity_main.xml files add the Recycler view, after adding the recycler view our activity_main.xml will look like as given below.
activity_main.xml
 <?xml version="1.0" encoding="utf-8"?>  
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.debugandroid.imagegallery.MainActivity">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/recyclerView">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>

Create ItemView to display the image inside RecylcerView


Item view we will use an image view and text view, Image for showing the image and text view for displaying the name of the photo. Create a XML file with name of item_view.xml
 <?xml version="1.0" encoding="utf-8"?>  
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="1dp"
android:layout_margin="2dp">
<LinearLayout android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
card_view:cardCornerRadius="1dp"
android:layout_margin="0dp">
<ImageView
android:layout_width="200dp"
android:layout_height="100dp"
android:id="@+id/media_img_bck"
android:layout_gravity="center"
android:scaleType="fitXY"
/>
</android.support.v7.widget.CardView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:weightSum="1">
<TextView
android:layout_marginTop="5dp"
android:layout_marginLeft="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Title"
android:gravity="left|top"
android:id="@+id/media_name"
android:textColor="@android:color/primary_text_light"
android:layout_gravity="center_vertical"
android:layout_weight="0.60"
android:textSize="12sp"/>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>

Creating ImageItem template class


We need to create a class for our item to show the data type with getter and setter.
ImageItem.java
 package com.debugandroid.imagegallery;  
/**
* Created by Pawan.
*/
public class ImageItem {
String DATA;
String DISPLAY_NAME;
String CREATED;
public ImageItem(String DATA, String DISPLAY_NAME,String CREATED){
this.DATA=DATA;
this.DISPLAY_NAME=DISPLAY_NAME;
this.CREATED=CREATED;
};
public ImageItem(){
}
public String getDATA() {
return DATA;
}
public void setDATA(String DATA) {
this.DATA = DATA;
}
public String getDISPLAY_NAME() {
return DISPLAY_NAME;
}
public void setDISPLAY_NAME(String DISPLAY_NAME) {
this.DISPLAY_NAME = DISPLAY_NAME;
}
public String getCREATED() {
return CREATED;
}
public void setCREATED(String CREATED) {
this.CREATED = CREATED;
}
}

We create a class MediaQuery.java to extract the all image URI from sd card. Create a class and modify it as given below.

MediaQuery.java
 package com.debugandroid.imagegallery;  
import android.content.Context;
import android.database.Cursor;
import android.provider.MediaStore;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
/**
* Created by Pawan.
*/
public class MediaQuery {
private Context context;
private int count = 0;
private Cursor cursor;
List<ImageItem> imageItems;
public MediaQuery(Context context){
this.context=context;
}
public List<ImageItem> getAllImage() {
String selection = null;
cursor = context.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
null,
selection,
null,
null);
imageItems = new ArrayList<ImageItem>();
ImageItem imageItem;
while (cursor.moveToNext()) {
imageItem = new ImageItem();
imageItem.setDATA(cursor.getString(1));
imageItem.setCREATED(getCreatedDate(cursor.getString(1)));
imageItem.setDISPLAY_NAME(getFileName(cursor.getString(1)));
imageItems.add(imageItem);
}
return imageItems;
}
public static String getCreatedDate(String filePath){
File file =new File(filePath);
long currentTime=System.currentTimeMillis();
long lastmodified=file.lastModified();
String createdTime;
SimpleDateFormat formatter = new SimpleDateFormat("HH:MM dd-MM-yyyy");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(lastmodified);
return formatter.format(calendar.getTime());
}
public static String getFileName(String path) {
if (path == null || path.length() == 0) {
return "";
}
int query = path.lastIndexOf('?');
if (query > 0) {
path = path.substring(0, query);
}
int filenamePos = path.lastIndexOf(File.separatorChar);
return (filenamePos >= 0) ? path.substring(filenamePos + 1) : path;
}
}

Create Adapter for Image Gallery


We create an adapter for our recycler view which will show the image in recycler view.
MyAdapter.java
 package com.debugandroid.imagegallery;  
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import java.util.List;
/**
* Created by Pawan on 2/20/2016.
*/
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<ImageItem> videoList;
Context context;
private final static int FADE_DURATION = 1000;
public static Glide glid;
String name;
Bundle bundle=new Bundle();
private static final int TYPE_ITEM = 1;
public MyAdapter(List<ImageItem> videoList, Context context) {
this.videoList = videoList;
this.context=context;
}
@Override
public int getItemViewType(int position) {
return TYPE_ITEM;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View itemView = LayoutInflater.
from(viewGroup.getContext()).
inflate(R.layout.item_view, viewGroup, false);
VideoViewHolder holder = new VideoViewHolder(itemView);
itemView.setTag(holder);
return holder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
ImageItem mediaObject=getItem(position);
name=mediaObject.getDISPLAY_NAME();
if (name.length() > 25) {
((VideoViewHolder) holder).vName.setText(name.substring(0, 25) + "..");
} else {
((VideoViewHolder) holder).vName.setText(name);
}
((VideoViewHolder) holder).vImage.setImageResource(R.color.cardview_dark_background);
((VideoViewHolder) holder).vFilePath = mediaObject.getDATA();
((VideoViewHolder) holder).context = context;
((VideoViewHolder) holder).position = position;
glid.with(context)
.load(mediaObject.getDATA())
.centerCrop()
.placeholder(R.color.cardview_dark_background)
.crossFade()
.into(((VideoViewHolder) holder).vImage);
setScaleAnimation(((VideoViewHolder) holder).vImage);
}
private void setScaleAnimation(View view) {
ScaleAnimation anim = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
anim.setDuration(FADE_DURATION);
view.startAnimation(anim);
}
private void setFadeAnimation(View view) {
AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f);
anim.setDuration(FADE_DURATION);
view.startAnimation(anim);
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
@Override
public int getItemCount() {
int itemCount = videoList.size();
return itemCount;
}
private boolean isPositionHeader(int position) {
return position == 0;
}
private boolean isPositionFooter(int position) {
return position == getItemCount() - 1;
}
protected ImageItem getItem(int position) {
return videoList.get(position);
}
private int getItemPosition(int position){
return position;
}
public class VideoViewHolder extends RecyclerView.ViewHolder {
protected ImageView vImage;
protected TextView vName;
protected String vFilePath;
protected Context context;
protected int position;
public VideoViewHolder(View v) {
super(v);
vName = (TextView) v.findViewById(R.id.media_name);
vImage = (ImageView) v.findViewById(R.id.media_img_bck);
v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse(vFilePath));
intent.setDataAndType(Uri.parse(vFilePath), "image/*");
context.startActivity(intent);
}
});
}
}
}

Finally, open MainActivity.java and modify it as given below.
 package com.debugandroid.imagegallery;  
import android.Manifest;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Build;
import android.provider.MediaStore;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
private MediaQuery mediaQuery;
private List<ImageItem> imageItemList;
private RecyclerView recyclerView;
private MyAdapter imageAdapter;
final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
checkandAskPermission();
}
else {
initMedia();
}
}
private void initMedia(){
recyclerView= (RecyclerView) findViewById(R.id.recyclerView);
imageItemList=new ArrayList<ImageItem>();
mediaQuery=new MediaQuery(this);
imageItemList=mediaQuery.getAllImage();
Log.d("ImageList","Count:"+imageItemList.size());
imageAdapter=new MyAdapter(imageItemList,this);
GridLayoutManager glm = new GridLayoutManager(this, 2);
glm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
switch (imageAdapter.getItemViewType(position)) {
case 0:
return 2;
case 1:
return 1;
case 2:
return 2;
default:
return 1;
}
}
});
recyclerView.setLayoutManager(glm);
recyclerView.setAdapter(imageAdapter);
}
private void checkandAskPermission() {
List<String> permissionsNeeded = new ArrayList<String>();
final List<String> permissionsList = new ArrayList<String>();
if (!addPermission(permissionsList, Manifest.permission.READ_EXTERNAL_STORAGE))
permissionsNeeded.add("Storage");
if (permissionsList.size() > 0) {
if (permissionsNeeded.size() > 0) {
String message = "You need to grant access to " + permissionsNeeded.get(0);
for (int i = 0; i < permissionsNeeded.size(); i++)
message = message + ", " + permissionsNeeded.get(i);
showMessageOKCancel(message,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
}
});
return;
}
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
return;
}
initMedia();
}
private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(this)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", okListener)
.create()
.show();
}
private boolean addPermission(List<String> permissionsList, String permission) {
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
permissionsList.add(permission);
if (!shouldShowRequestPermissionRationale(permission))
return false;
}
return true;
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults){
switch (requestCode) {
case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS: {
Map<String, Integer> perms = new HashMap<String, Integer>();
perms.put(Manifest.permission.READ_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED);
for (int i = 0; i < permissions.length; i++)
perms.put(permissions[i], grantResults[i]);
if (perms.get(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
initMedia();
}
else {
// Permission Denied
Toast.makeText(MainActivity.this, "Some Permission is Denied", Toast.LENGTH_SHORT)
.show();
}
}
}
}
}

Download the full source code from GitHub https://github.com/debugandroid/ImageGallery

Comments

Popular posts from this blog

WordPress Android App with REST API And Retrofit

Retrofit is the library which converts your JSON data into Java object. In this tutorial, we will learn about how to implement the Retrofit to create a WordPress Mobile App. As we all know, WordPress is the one of the biggest CMS (Content Management System) of the world. Wordpress full fill the requirements for all most every type of the website. So, in this tutorial, I am going to learn how to create an Android App using the WordPress REST API and Retrofit.
What is Retrofit?
If you want to know about Retrofit, I would like to give you just a simple one-line explanation of the Retrofit. It is a library which converts your REST HTTP request to Java interface. We will learn how we can do all these stuff using some very simple steps.

Further, you can check the Retrofit Library here.

So, In this tutorial, we will use the Retrofit to retrieve all post and there except ( A short Description of Post) form a WordPress website.
Prerequisite for using the Retrofit for WordPress Android App
There is s…

Flutter Theme Creation, Programmatic Way

Flutter and Dart is an excellent combination for creating the mobile app with material design with nice GUI. Its lots of widget which help the developer for creating the app UI very fast with respect to the other language. You may face some problem in starting due to comm, curly brace and semicolon but after some time you will find the way how to work with these all stuff and it becomes very easy for you. But in this article, we are not going to discuss all these. In this article, we will handle a very interesting topic on how to create a custom theme or multiple themes and let's user decide which theme to use.



Create a flutter project



So let's create a flutter project by selecting the appropriate option from the File menu in android studio or Visual Code. If you are new to Flutter and Dart you can check out our recent post to get started Creating Cross-platform app using flutter.



Once your project is created you will get the default counter app and you try running the app in the…

Flutter How to Start Android Activity from Flutter View

Flutter and Dart is an excellent combination for creating the UI, but for accessing the platform-specific service we need to open platform-specific activity. So lets in this article we will explore how to start an android activity and access the service from Flutter View.

Create a Project for this Android Activity Flutter View Demo Create a Project From File menu select the New Flutter Project Enter the project name Select the AndroidX support and click on next After the above, we step click on Finish We will have the following project structure created. Create the Second Activity in Android
Just go to the android folder and open it in separate windows. We will have the following project structure.









Create the Activity Just right click on the Kotlin folder and create a blank activity from the menu. If you create the activity then you may be required to upgrade the Gradle and do some import. So Just click on update and wait for the project sync completed.
Update the project build config …