Android | Display Selected Image and Its Real Path

android-display-image-real-pathThis post shows how to select an image from image gallery, display it on ImageView and how to get its real path on different API versions (19, 17 & 10). We will use ACTION_GET_CONTENT intent that is set to select data of type image only.

 

 

 

 

 

 

 

( 1 )  Create a New Android Project

  • Application Name: Show Image & Path
  • Project Name: android-show-image-and-path
  • Package Name: com.hmkcode.android.image

( 2 )  Activity Layout

  • res/layout/activity_main.xml
  • TextView: displays SDK version
  • Button: to select an image
  • TextView: displays URI path
  • TextView: displays real path
  • ImageView; displays the image
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.hmkcode.android.image.MainActivity" >

    <TextView
        android:id="@+id/txtSDK"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

    <Button
        android:id="@+id/btnSelectImage"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/txtSDK"
        android:text="Select Image"
        android:layout_marginBottom="20dp" />

     <TextView
        android:id="@+id/txtUriPath"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btnSelectImage"
        android:text="URI Path:"
        android:layout_marginBottom="20dp"  />
     
     <TextView
        android:id="@+id/txtRealPath"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/txtUriPath"
        android:text="Real Path:"
        android:layout_marginBottom="20dp"  />

     <ImageView
         android:id="@+id/imgView"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_below="@+id/txtRealPath"
         android:src="@drawable/abc_ab_bottom_solid_light_holo" />
     
</RelativeLayout>

( 3 ) Main Activity

  • src/com/hmkcode/android/image/MainActivity.java
  • onCreate() : get reference to views defined in main_layout.xml
  • onClick(): call ACTION_GET_CONTENT intent
  • onActivityResult(): defines how to get real path for different SDK versions call setTextViews()
  • setTextViews(): displays SDK version, uri path, real path and selected image.
package com.hmkcode.android.image;

import java.io.File;
import java.io.FileNotFoundException;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener {

    TextView txtSDK;
    Button btnSelectImage;
    TextView txtUriPath,txtRealPath;
    ImageView imageView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        // get reference to views
        txtSDK = (TextView) findViewById(R.id.txtSDK);
        btnSelectImage = (Button) findViewById(R.id.btnSelectImage);
        txtUriPath = (TextView) findViewById(R.id.txtUriPath);
        txtRealPath = (TextView) findViewById(R.id.txtRealPath);
        imageView = (ImageView) findViewById(R.id.imgView);
        
        // add click listener to button
        btnSelectImage.setOnClickListener(this); 
    }
    
    @Override
    public void onClick(View view) {
        
        // 1. on Upload click call ACTION_GET_CONTENT intent
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        // 2. pick image only
        intent.setType("image/*");
        // 3. start activity
        startActivityForResult(intent, 0);
        
        // define onActivityResult to do something with picked image 
    }
    
    
    @Override
     protected void onActivityResult(int reqCode, int resCode, Intent data) {
        if(resCode == Activity.RESULT_OK && data != null){
            String realPath;
            // SDK < API11
            if (Build.VERSION.SDK_INT < 11)
                realPath = RealPathUtil.getRealPathFromURI_BelowAPI11(this, data.getData());
            
            // SDK >= 11 && SDK < 19
            else if (Build.VERSION.SDK_INT < 19)
                realPath = RealPathUtil.getRealPathFromURI_API11to18(this, data.getData());
            
            // SDK > 19 (Android 4.4)
            else
                realPath = RealPathUtil.getRealPathFromURI_API19(this, data.getData());
                
            
            setTextViews(Build.VERSION.SDK_INT, data.getData().getPath(),realPath);
        }
    }
    
    private void setTextViews(int sdk, String uriPath,String realPath){
        
        this.txtSDK.setText("Build.VERSION.SDK_INT: "+sdk);
        this.txtUriPath.setText("URI Path: "+uriPath);
        this.txtRealPath.setText("Real Path: "+realPath);
        
        Uri uriFromPath = Uri.fromFile(new File(realPath));
        
        // you have two ways to display selected image
        
        // ( 1 ) imageView.setImageURI(uriFromPath);

        // ( 2 ) imageView.setImageBitmap(bitmap); 
        Bitmap bitmap = null;
        try {
            bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uriFromPath));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        imageView.setImageBitmap(bitmap); 
        
        Log.d("HMKCODE", "Build.VERSION.SDK_INT:"+sdk);
        Log.d("HMKCODE", "URI Path:"+uriPath);
        Log.d("HMKCODE", "Real Path: "+realPath);
    }

}

( 4 ) Getting Real Path On Different Android SDK (19, 17 & 10)

  • src/com/hmkcode/android/image/RealPathUtil.java

the code to get the real path is a bit different from one SDK to another so below we have three methods that deals with different SDKs.

  • getRealPathFromURI_API19(): returns real path for API 19 (or above but not tested)
  • getRealPathFromURI_API11to18(): returns real path for API 11 to API 18
  • getRealPathFromURI_below11(): returns real path for API below 11
package com.hmkcode.android.image;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.CursorLoader;
import android.database.Cursor;
import android.net.Uri;
import android.provider.DocumentsContract;
import android.provider.MediaStore;

public class RealPathUtil {

    @SuppressLint("NewApi")
    public static String getRealPathFromURI_API19(Context context, Uri uri){
        String filePath = "";
        String wholeID = DocumentsContract.getDocumentId(uri);

         // Split at colon, use second item in the array
         String id = wholeID.split(":")[1];

         String[] column = { MediaStore.Images.Media.DATA };     

         // where id is equal to             
         String sel = MediaStore.Images.Media._ID + "=?";

         Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 
                                   column, sel, new String[]{ id }, null);
         
         int columnIndex = cursor.getColumnIndex(column[0]);

         if (cursor.moveToFirst()) {
             filePath = cursor.getString(columnIndex);
         }   
         cursor.close();
         return filePath;
    }
    
    
    @SuppressLint("NewApi")
    public static String getRealPathFromURI_API11to18(Context context, Uri contentUri) {
          String[] proj = { MediaStore.Images.Media.DATA };
          String result = null;
           
          CursorLoader cursorLoader = new CursorLoader(
                  context, 
            contentUri, proj, null, null, null);        
          Cursor cursor = cursorLoader.loadInBackground();
          
          if(cursor != null){
           int column_index = 
             cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
           cursor.moveToFirst();
           result = cursor.getString(column_index);
          }
          return result;  
    }
    
    public static String getRealPathFromURI_BelowAPI11(Context context, Uri contentUri){
               String[] proj = { MediaStore.Images.Media.DATA };
               Cursor 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);
    }
}

( 5 ) Manifest Permission

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

( 6 ) Run & Test

We will run on emulator with SDK 17 & 10 and on real device Nexsus 5 SDK 19

android-display-image-real-path-sdk17

android-display-image-real-path-sdk10android-display-image-real-pathSource Code @ GitHub

Leave a Reply