Pages

Thursday, March 13, 2014

How to get absolute path when select image from gallery and SD Card (Kitkat and lower android version)?

In some special cast to need get image from gallery to display in application. so I am posting to get absolute path of the selected image from gallery using Intent.ACTION_GET_CONTENT.

In Kitkat version we get different Uri format(DocumentProvider)
Now
Uri format like this : content://com.android.providers.media.documents/document/image:3951
Before
Uri format like this : content://media/external/images/media/3951.

See the Kikat version change here

1. AbsolutePathActivity.java Activity Class

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class AbsolutePathActivity extends Activity 
{
 private static final int MY_INTENT_CLICK=302;
 private TextView txta;
 private Button btn_selectImage;

 @Override
 protected void onCreate(Bundle savedInstanceState) 
 {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_absolutepath);

  txta = (TextView) findViewById(R.id.textView1);
  btn_selectImage = (Button) findViewById(R.id.btn_selectImage);

  btn_selectImage.setOnClickListener(new OnClickListener() 
  {
   @Override
   public void onClick(View v) 
   {
    Intent intent = new Intent(); 
    intent.setType("*/*"); 
    intent.setAction(Intent.ACTION_GET_CONTENT); 
    startActivityForResult(Intent.createChooser(intent, "Select File"),MY_INTENT_CLICK);
   }
  });

 }

 @Override
 public void onActivityResult(int requestCode, int resultCode, Intent data)
 {
  if (resultCode == RESULT_OK)
  {
   if (requestCode == MY_INTENT_CLICK)
   {
    if (null == data) return;

    String selectedImagePath;
    Uri selectedImageUri = data.getData();

    //MEDIA GALLERY
    selectedImagePath = ImageFilePath.getPath(getApplicationContext(), selectedImageUri);
    Log.i("Image File Path", ""+selectedImagePath);
    txta.setText("File Path : \n"+selectedImagePath);
   }
  }
 }
}

Copy below class on your application for getting Gallery image file Uri AbsolutePath.

2.ImageFilePath.java  

import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;

public class ImageFilePath 
{
 
 
 /**
  * Method for return file path of Gallery image 
  * 
  * @param context
  * @param uri
  * @return path of the selected image file from gallery
  */
 public static String getPath(final Context context, final Uri uri) 
 {

  //check here to KITKAT or new version
  final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

  // DocumentProvider
  if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
   
   // ExternalStorageProvider
   if (isExternalStorageDocument(uri)) {
    final String docId = DocumentsContract.getDocumentId(uri);
    final String[] split = docId.split(":");
    final String type = split[0];

    if ("primary".equalsIgnoreCase(type)) {
     return Environment.getExternalStorageDirectory() + "/" + split[1];
    }
   }
   // DownloadsProvider
   else if (isDownloadsDocument(uri)) {

    final String id = DocumentsContract.getDocumentId(uri);
    final Uri contentUri = ContentUris.withAppendedId(
      Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

    return getDataColumn(context, contentUri, null, null);
   }
   // MediaProvider
   else if (isMediaDocument(uri)) {
    final String docId = DocumentsContract.getDocumentId(uri);
    final String[] split = docId.split(":");
    final String type = split[0];

    Uri contentUri = null;
    if ("image".equals(type)) {
     contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
    } else if ("video".equals(type)) {
     contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
    } else if ("audio".equals(type)) {
     contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    }

    final String selection = "_id=?";
    final String[] selectionArgs = new String[] {
      split[1]
    };

    return getDataColumn(context, contentUri, selection, selectionArgs);
   }
  }
  // MediaStore (and general)
  else if ("content".equalsIgnoreCase(uri.getScheme())) {

   // Return the remote address
   if (isGooglePhotosUri(uri))
    return uri.getLastPathSegment();

   return getDataColumn(context, uri, null, null);
  }
  // File
  else if ("file".equalsIgnoreCase(uri.getScheme())) {
   return uri.getPath();
  }

  return null;
 }

 /**
  * Get the value of the data column for this Uri. This is useful for
  * MediaStore Uris, and other file-based ContentProviders.
  *
  * @param context The context.
  * @param uri The Uri to query.
  * @param selection (Optional) Filter used in the query.
  * @param selectionArgs (Optional) Selection arguments used in the query.
  * @return The value of the _data column, which is typically a file path.
  */
 public static String getDataColumn(Context context, Uri uri, String selection,
   String[] selectionArgs) {

  Cursor cursor = null;
  final String column = "_data";
  final String[] projection = {
    column
  };

  try {
   cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
     null);
   if (cursor != null && cursor.moveToFirst()) {
    final int index = cursor.getColumnIndexOrThrow(column);
    return cursor.getString(index);
   }
  } finally {
   if (cursor != null)
    cursor.close();
  }
  return null;
 }

 /**
  * @param uri The Uri to check.
  * @return Whether the Uri authority is ExternalStorageProvider.
  */
 public static boolean isExternalStorageDocument(Uri uri) {
  return "com.android.externalstorage.documents".equals(uri.getAuthority());
 }

 /**
  * @param uri The Uri to check.
  * @return Whether the Uri authority is DownloadsProvider.
  */
 public static boolean isDownloadsDocument(Uri uri) {
  return "com.android.providers.downloads.documents".equals(uri.getAuthority());
 }

 /**
  * @param uri The Uri to check.
  * @return Whether the Uri authority is MediaProvider.
  */
 public static boolean isMediaDocument(Uri uri) {
  return "com.android.providers.media.documents".equals(uri.getAuthority());
 }

 /**
  * @param uri The Uri to check.
  * @return Whether the Uri authority is Google Photos.
  */
 public static boolean isGooglePhotosUri(Uri uri) {
  return "com.google.android.apps.photos.content".equals(uri.getAuthority());
 }
}


3. activity_absolutepath.xml layout file

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="30dp" >

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Example code for get absolute path when select image from gallery"
        android:textSize="14sp"
        android:textStyle="bold" />

    <Button
        android:id="@+id/btn_selectImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:layout_marginTop="10dp"
        android:text="Select Image" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:textSize="14sp"
        android:textStyle="bold" />

</LinearLayout>

4. AndroidManifest.xml file

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.limbani.masterapp"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.limbani.masterapp.AbsolutePathActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

5. ScreenShot




And Gallery image file Absolute path write in Log as per above code.

That's it, And it's working in Kitkat and  lower version too.

Doanload APK file Here

enjoy :)
Thank you.


35 comments:

  1. can you post complete code ?
    i still getting some error so please

    ReplyDelete
    Replies
    1. Hello Dharmendra,
      I have update My post Please check it,
      I hope now it's halp you.
      Thank you.

      Delete
  2. how can i get contact photo uri in intent

    ReplyDelete
  3. Hello, I am testing the code in android 4.4.4 and I am experiencing problems when trying to get a google drive element, I'm trying to fix it but there is little information about. Do you have the same problem?

    Regards,
    Jose.

    ReplyDelete
  4. Awesum Example ....Very Helpful to me.
    Thanks a Lot

    ReplyDelete
  5. Hi, I want to get content of file (docx,txt,pdf) from sdcard which opens default file manager to browse file from sdcard with help of intent action_get_content.which returns me path as /external/file/2631 .I want to absolute path of this file i Installed LimbaniAndroid apk and its 'Get file absolute path ' gives me correct value as /Removable/MicroSD/Docs/test.docx but when i run above code application crashes when i select document. Can you please help me with this issue or post comple code of limbaniandroid.apk.

    ReplyDelete
  6. Hello Sir,
    When i try to open a file or image from file manager i get the path like external/file/2546 etc.Now what i want is to get the actual path like sdcard/pictures/images/img.jpg.Now how can i achieve it.
    Thanks

    ReplyDelete
    Replies
    1. Hello Anuj,

      Did you try above code?
      I hope it's working for you.

      Thanks,

      Delete
  7. Yes, sir I tried it but still I am getting path as external/file/2546

    ReplyDelete
    Replies
    1. Hello Anuj,

      I have update my post to add one permission in manifest file,
      Please try this.

      Thanks

      Delete
  8. Mr.
    after i stored the image path in remote db
    i need to veiw this image in imageview how can i do that

    ReplyDelete
  9. java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=101, result=-1, data=Intent { dat=content://com.android.externalstorage.documents/document/D489-F060:log.txt flg=0x1 }} to activity {com.exampe.myfirst/com.exampe.myfirst.Compose}: java.lang.NullPointerException

    ReplyDelete
  10. code is fine but
    only external content provider not working


    when i selecting an file from external storage(sd card)using sony xperia z1,kitkat

    selected file path: null

    not getting the path

    ReplyDelete
  11. get all media data like (video, image , Audio) in sdcard in an android

    ReplyDelete
  12. Ohhh Sir what a great post. U did a brilliant work. I can't explain.

    ReplyDelete
  13. Awesome Work...just remove some html span tags that are in between tag.
    Thank You.

    ReplyDelete
  14. It doesn't work when selected image that have Google drive icon. How to solve it?

    ReplyDelete
  15. Thank you so much. Earlier I was getting issues with Android Marshmallow while getting the path of chosen image but through your example I have successfully completed the task.

    ReplyDelete
  16. i want to clear this path on a reset button, please suggest what to do.

    Thanks.

    ReplyDelete
  17. i get path from sdCard is null, help me !

    ReplyDelete
  18. Finally a working method *.* I thank you so much for sharing this with us :D

    ReplyDelete
  19. thanks Dear
    This tutorials helps us to accomplish our projects

    ReplyDelete
  20. Thanks a lot Durgesh. It really saved my hours. I have tested in only one device so far but it worked smoothly.

    ReplyDelete
  21. Durgesh its giving errror
    E/AndroidRuntime: FATAL EXCEPTION: main
    Process: poc.servicedesigntoolkit.getpost, PID: 15223
    java.lang.IllegalArgumentException: column '_data' does not exist

    ReplyDelete
  22. How to get file from google drive... as per your example.. selected file path is null when selecting file from google drive

    ReplyDelete