Android supports seamless integration of applications and content providers. Lot many things are handy provided to developers, which helps in reducing the code and consumes less time to integrate different features to app.
For example, if we have an application that allow user to change his profile picture. In this requirement user will be welling to browse his mobile gallery and pick a picture of his own to set his profile picture. Integrating this feature in traditional operating system, need lot of effort write code to integrate file browser. But in android we can use Intent.ACTION_PICK
action to get this feature integrated .
In this tutorial, we are going to learn how to pick an Image from Gallery and display in our app.
1. Create a new project in Eclipse by navigating to File ⇒ New Android ⇒ Application Project and fill required details. By default my activity is MainActivity.java.
2. First create a layout in xml file naming activity_main.xml that contains Button for selecting image , and ImageView to display image and two TextViews for displaying URI path and original path of image.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:fillViewport="true" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:orientation="vertical" android:padding="5dp" > <FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/border" > <ImageView android:id="@+id/gallery_imageview" android:layout_width="300dp" android:layout_height="300dp" android:layout_gravity="center_horizontal" android:layout_margin="5dp" android:contentDescription="@string/gallery_imageview" android:scaleType="centerCrop" android:src="@drawable/logo" /> </FrameLayout> <TextView android:id="@+id/uri_path" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="5dp" android:textColor="#000000" android:textSize="16sp" android:visibility="gone" /> <TextView android:id="@+id/real_path" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="5dp" android:textColor="#000000" android:textSize="16sp" android:visibility="gone" /> <Button android:id="@+id/change_image" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="5dp" android:layout_marginTop="20dp" android:padding="10dp" android:text="@string/change_image" /> </LinearLayout> </ScrollView> |
3. In above layout you had seen i had set background to FrameLayout creating a border to ImageView for this we have to create an xml file under drawable directory naming border.xml.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <corners android:radius="10dp" /> <padding android:bottom="5dp" android:left="5dp" android:right="5dp" android:top="5dp" /> <solid android:color="#ffffff" /> <stroke android:color="#000000" android:width="1dp" /> </shape> |
4. Now there are only three main steps by which we can achieve our goal :
Step 1: Starting Intent
Step 2: Receiving the gallery response
The selected image will result in onActivityforResult where we get the image URI and we convert the URI into real path via below method :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public static String getRealPathFromUri(Context context, Uri contentUri) { Cursor cursor = null; try { String[] proj = { MediaStore.Images.Media.DATA }; cursor = context.getContentResolver().query(contentUri, proj, null, null, null); int column_index = cursor .getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); } finally { if (cursor != null) { cursor.close(); } } } |
Step 3: After receiving response we have to compress the image
We have to compress and scale the image because large images can cause Exceptions so better to avoid exception. The below method is going to do this task and return a bitmap:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
public static Bitmap decodeUri(Context context, Uri uri, final int requiredSize) throws FileNotFoundException { BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; BitmapFactory.decodeStream(context.getContentResolver() .openInputStream(uri), null, o); int width_tmp = o.outWidth, height_tmp = o.outHeight; int scale = 1; while (true) { if (width_tmp / 2 < requiredSize || height_tmp / 2 < requiredSize) break; width_tmp /= 2; height_tmp /= 2; scale *= 2; } BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize = scale; return BitmapFactory.decodeStream(context.getContentResolver() .openInputStream(uri), null, o2); } |
5. Finally come to your MainActivity.java and add the following code that we had discusses in above point.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
package com.galleryimagepicker_demo; import java.io.FileNotFoundException; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Bundle; import android.provider.MediaStore; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private final int select_photo = 1; // request code fot gallery intent private static ImageView gallery_image; private static TextView uriPath, realPath; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); gallery_image = (ImageView) findViewById(R.id.gallery_imageview); uriPath = (TextView) findViewById(R.id.uri_path); realPath = (TextView) findViewById(R.id.real_path); // Implement click listener over button findViewById(R.id.change_image).setOnClickListener( new OnClickListener() { @Override public void onClick(View arg0) { // Intent to gallery Intent in = new Intent(Intent.ACTION_PICK); in.setType("image/*"); startActivityForResult(in, select_photo);// start // activity // for // result } }); } protected void onActivityResult(int requestcode, int resultcode, Intent imagereturnintent) { super.onActivityResult(requestcode, resultcode, imagereturnintent); switch (requestcode) { case select_photo: if (resultcode == RESULT_OK) { try { Uri imageuri = imagereturnintent.getData();// Get intent // data uriPath.setText("URI Path: " + imageuri.toString()); // Get real path and show over text view String real_Path = getRealPathFromUri(MainActivity.this, imageuri); realPath.setText("Real Path: " + real_Path); uriPath.setVisibility(View.VISIBLE); realPath.setVisibility(View.VISIBLE); Bitmap bitmap = decodeUri(MainActivity.this, imageuri, 300);// call // deocde // uri // method // Check if bitmap is not null then set image else show // toast if (bitmap != null) gallery_image.setImageBitmap(bitmap);// Set image over // bitmap else Toast.makeText(MainActivity.this, "Error while decoding image.", Toast.LENGTH_SHORT).show(); } catch (FileNotFoundException e) { e.printStackTrace(); Toast.makeText(MainActivity.this, "File not found.", Toast.LENGTH_SHORT).show(); } } } } // Method that deocde uri into bitmap. This method is necessary to deocde // large size images to load over imageview public static Bitmap decodeUri(Context context, Uri uri, final int requiredSize) throws FileNotFoundException { BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; BitmapFactory.decodeStream(context.getContentResolver() .openInputStream(uri), null, o); int width_tmp = o.outWidth, height_tmp = o.outHeight; int scale = 1; while (true) { if (width_tmp / 2 < requiredSize || height_tmp / 2 < requiredSize) break; width_tmp /= 2; height_tmp /= 2; scale *= 2; } BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize = scale; return BitmapFactory.decodeStream(context.getContentResolver() .openInputStream(uri), null, o2); } // Get Original image path public static String getRealPathFromUri(Context context, Uri contentUri) { Cursor cursor = null; try { String[] proj = { MediaStore.Images.Media.DATA }; cursor = context.getContentResolver().query(contentUri, proj, null, null, null); int column_index = cursor .getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); } finally { if (cursor != null) { cursor.close(); } } } } |
6. Now, you are all done, run your app and you will get the output as shown in video.
Thanks.
Subscribe to us and get the latest news.