Path of selected image is null - android

I am trying to get the real path of a URI.
First I start the gallery app through an intent:
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select picture"), SELECT_IMAGE );
After that the onActivityResult gets called, where I try to get the absolut path of the URI.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
if (resultCode == RESULT_OK) {
Uri uri;
if (requestCode == SELECT_IMAGE) {
final Uri uri_data = data.getData();
// Get the path from the Uri
final String path = getPathFromURI(uri_data);
if (path != null) {
File f = new File(path);
uri = Uri.fromFile(f);
}
}
}
} catch (Exception e) {
Log.e("FileSelectorActivity", "File select error", e);
}
}
The uri_data contains "content://com.android.providers.media.documents/document/image%3A67", but the resulting path is null.
The pathFromUri method looks like this:
private String getPathFromURI(Uri contentUri) {
String res = null;
String[] proj = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(contentUri, proj, null, null, null);
if (cursor.moveToFirst()) {
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
res = cursor.getString(column_index);
}
cursor.close();
return res;
}
Here the column_index is 0, but cursor.getString returns null.
Why does this happen?
I have the permission android.permission.READ_EXTERNAL_STORAGE
EDIT:
So I want to take a picture through the camera app, and the user then chooses the image. So the file should be acutally stored on the phone (which is, since I am testing it on my phone)
EDIT:
Okey, the solution was to request the permissions at runtime...sorry guys

Related

how to get a real path of PDF file in android

we want to choose a pdf file using intent from a gallery so how can get a real path of a pdf file. We want to choose a PDF file from a gallery and upload this file on a server.
public String getPathFromURI(Context context, Uri contentUri) {
if ( contentUri.toString().indexOf("file:///") > -1 ){
return contentUri.getPath();
}
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();
}
}
}
Hi here is sample code for selecting pdf file from external storage and get file's path using which you can access file's data and upload data on your server.
Here PICK_IMAGE is any number you want as your request code.
Intent intent = new Intent();
intent.setType("application/pdf");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select File"),PICK_IMAGE);
public void onActivityResult(int requestCode, int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE) {
try {
Uri uri1 = data.getData();
String path = String.valueOf(uri1);
String path_lastPart = path.substring(path.indexOf("/storage"));
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
// Do the file write
path_lastPart = path_lastPart.replace("%20", " ");
File yourFile = new File(path_lastPart);
} else {
// Request permission from the user
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
}
} catch (Exception e2) {
Log.e("macro", "" + e2);
}
}
}

Android How to Load an Audio file from the sdcard/file manager and play it

I'm developing an app, and in that app I have one button, named 'choose sound'. When user will click this button, he/she should be asked to choose any audio file from the file manager/memory.
So, I know that for this, I'll have to use Intent.Action_GetData. I'm doing the same:
//code start
Intent intent = new Intent();
intent.setType("audio/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent,1);
#Override
protected void onActivityResult(int requestCode,int resultCode,Intent data){
if(requestCode == 1){
if(resultCode == RESULT_OK){
//the selected audio.
Uri uri = data.getData();
int SoundID=soundPool.Load(uri.toString(), 1);
//SoundPool is already constructed and is working perfectly for the resource files
PlaySound(SoundID);
//PlaySound method is already defined
}
}
super.onActivityResult(requestCode, resultCode, data);
}
//end of code
but it's not working
Now, in OnActivityResult, I'm not getting that how to load the proper URI of the file selected by user, because before Android 4.4, it returns the different URI and after Android 4.4 it returns the different URI on intent.GetData();. Now, what I have to do?
Also, I know that for playing the audio file, I'll have to use SoundPool, and I have the code for that too, in fact it's working fine for the resource/raw/audio files, but how to load/play files in SoundPool from this URI?
In your onActivityResult(), do the following changes:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK && data != null)
{
String realPath = null;
Uri uriFromPath = null;
realPath = getPathForAudio(YourActivity.this, data.getData());
uriFromPath = Uri.fromFile(new File(realPath)); // use this uriFromPath for further operations
}
}
Add this method in your Activity:
public static String getPathForAudio(Context context, Uri uri)
{
String result = null;
Cursor cursor = null;
try {
String[] proj = { MediaStore.Audio.Media.DATA };
cursor = context.getContentResolver().query(uri, proj, null, null, null);
if (cursor == null) {
result = uri.getPath();
} else {
cursor.moveToFirst();
int column_index = cursor.getColumnIndex(MediaStore.Audio.AudioColumns.DATA);
result = cursor.getString(column_index);
cursor.close();
}
}
catch (Exception e)
{
e.printStackTrace();
}
finally {
if (cursor != null) {
cursor.close();
}
}
return result;
}
Hope It will do your job. You can play audio using MediaPlayer class also
You can put below codes in your project when you want to select audio.
Intent intent_upload = new Intent();
intent_upload.setType("audio/*");
intent_upload.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent_upload,1);
And override onActivityResult in the same Activity, as below
#Override
protected void onActivityResult(int requestCode,int resultCode,Intent data){
if(requestCode == 1){
if(resultCode == RESULT_OK){
//the selected audio.
Uri uri = data.getData();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
Try to get the path :
//method to get the file path from uri
public String getPath(Uri uri) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
String document_id = cursor.getString(0);
document_id = document_id.substring(document_id.lastIndexOf(":") + 1);
cursor.close();
cursor = getContentResolver().query(
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
null, MediaStore.Images.Media._ID + " = ? ", new String[]{document_id}, null);
cursor.moveToFirst();
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
cursor.close();
return path;
}
then load it :
s2 = soundPool.load(YOU_PATH, PRIORITY);

Android - How to get selected file name from the document

I am launching the intent for selecting documnets using following code.
private void showFileChooser() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
try {
startActivityForResult(
Intent.createChooser(intent, "Select a File to Upload"), 1);
} catch (android.content.ActivityNotFoundException ex) {
// Potentially direct the user to the Market with a Dialog
Toast.makeText(this, "Please install a File Manager.",
Toast.LENGTH_SHORT).show();
}
}
In onActivity results when i am trying to get the file path it is giving some other number in the place of file name.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case 1:
if (resultCode == RESULT_OK) {
// Get the Uri of the selected file
Uri uri = data.getData();
File myFile = new File(uri.toString());
String path = myFile.getAbsolutePath();
}
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
That path value i am getting like this.
"content://com.android.providers.downloads.documents/document/1433"
But i want real file name like doc1.pdf etc.. How to get it?
When you get a content:// uri, you'll need to query a content resolver and then grab the display name.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case 1:
if (resultCode == RESULT_OK) {
// Get the Uri of the selected file
Uri uri = data.getData();
String uriString = uri.toString();
File myFile = new File(uriString);
String path = myFile.getAbsolutePath();
String displayName = null;
if (uriString.startsWith("content://")) {
Cursor cursor = null;
try {
cursor = getActivity().getContentResolver().query(uri, null, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
displayName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
}
} finally {
cursor.close();
}
} else if (uriString.startsWith("file://")) {
displayName = myFile.getName();
}
}
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
First Check if the permission is granted for Application.. Below method is used to check run-time permission'
public void onClick(View v) {
//Checks if the permission is Enabled or not...
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_PERMISSION);
} else {
Intent galleryIntent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, USER_IMG_REQUEST);
}
}
and below method is used to find the uri path name of the file
private String getRealPathFromUri(Uri uri) {
String[] projection = {MediaStore.Images.Media.DATA};
CursorLoader cursorLoader = new CursorLoader(thisActivity, uri, projection, null, null, null);
Cursor cursor = cursorLoader.loadInBackground();
int column = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String result = cursor.getString(column);
cursor.close();
return result;
}
and the above method can be used as
if (requestCode == USER_IMG_REQUEST && resultCode == RESULT_OK && data != null) {
Uri path = data.getData();
try {
String imagePath = getRealPathFromUri(path);
File file = new File(imagePath);
RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part imageFile = MultipartBody.Part.createFormData("userImage", file.getName(), reqFile);
You can try this,m I hope it will help u:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.i("inside", "onActivityResult");
if(requestCode == FILE_MANAGER_REQUEST_CODE)
{
// Check if the user actually selected an image:
if(resultCode == Activity.RESULT_OK)
{
// This gets the URI of the image the user selected:
Uri selectedFileURI = data.getData();
File file = new File(getRealPathFromURI(selectedFileURI));
// Create a new Intent to send to the next Activity:
}
}
}
private String getRealPathFromURI(Uri contentURI) {
String result;
Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
if (cursor == null) { // Source is Dropbox or other similar local file path
result = contentURI.getPath();
} else {
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
result = cursor.getString(idx);
cursor.close();
}
return result;
}
Here is the complete solution:
Pass your context and URI object from onActivityResult to below function to get the correct path:
it gives the path as /storage/emulated/0/APMC Mahuva/Report20-11-2017.pdf (where I've selected this Report20-11-2017.pdf file)
String getFilePath(Context cntx, Uri uri) {
Cursor cursor = null;
try {
String[] arr = { MediaStore.Images.Media.DATA };
cursor = cntx.getContentResolver().query(uri, arr, 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();
}
}
}

Picking an image from the new Photos application

I am using the following Intent to allow the user to choose a picture
Intent pictureIntent = new Intent();
pictureIntent.setType("image/*");
pictureIntent.setAction(Intent.ACTION_PICK);
startActivityForResult(pictureIntent, GALLERY_PICK_IMAGE_REQUEST);
After getting the result, I am using the following approach (using this method)
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == GALLERY_PICK_IMAGE_REQUEST) {
if (resultCode == mActivity.RESULT_OK) {
Uri selectedImage = data.getData();
Log.d(TAG, "Gallery image path = " + selectedImage.getPath());
launchUploadImageActivity(getRealPathFromURI(mActivity, selectedImage));
}
}
}
private 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();
}
}
}
When I use the new Photos application to choose the picture, I can choose a photo that I presume is on google's servers, since it returns a url to a picture, instead of the file path:
Log output:
Gallery image path = /0/https://lh6.googleusercontent.com/lRkls4SQwi_afJvjO5QChsWqRwTpDjg-....
Is there any way I can force the user to choose pictures that are local on the phone?
Try with following code to chose picture
Intent pictureIntent = new Intent(MediaStore.ACTION_PICK, Images.Media.INTERNAL_CONTENT_URL);
startActivityForResult(pictureIntent, REQUEST_CHOOSE_IMAGE);
instead of
Intent pictureIntent = new Intent();
pictureIntent.setType("image/*");
pictureIntent.setAction(Intent.ACTION_PICK);
startActivityForResult(pictureIntent, GALLERY_PICK_IMAGE_REQUEST);
Add this line to your intent:
pictureIntent.setData(Images.Media.INTERNAL_CONTENT_URI);

Android - Image Picker, Wrong Image

I am starting a request for an image pick:
Intent intent = new Intent();
intent.setType( "image/*" );
intent.setAction( Intent.ACTION_GET_CONTENT );
startActivityForResult( Intent.createChooser( intent, "Choose"), PHOTO_GALLERY );
And getting the data back out in onActivityResult:
if( resultCode == Activity.RESULT_OK && requestCode == PHOTO_GALLERY )
{
U.log( data.getData() );
Bitmap bm = ... // built from the getData() Uri
this.postImagePreview.setImageBitmap( bm );
}
When I launch the Intent, I see some folders, such as sdcard, Drop Box, MyCameraApp, and so on.
If I chose a picture from sdcard, when I load the preview, it is the completely wrong image. The other folders don't seem to be giving me this problem.
Does anyone know why it'd let me pick one image, then give me the Uri for another?
EDIT: Here are some exampled logged getData()s:
Good:
content://com.google.android.gallery3d.provider/picasa/item/5668377679792530210
Bad:
content://media/external/images/media/28
EDIT: I'm still having issues, when picking from the sdcard folder of gallery.
Here is a bit more expansion of what I'm doing in onActivityResult:
// cursor
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = mContext.getContentResolver().query( selectedImage, filePathColumn, null, null, null );
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex( filePathColumn[0] );
String filePath = cursor.getString( columnIndex );
cursor.close();
// Cursor: /mnt/sdcard/Pic.jpg : /mnt/sdcard/Pic.jpg
U.log( "Cursor: " + filePath + " : " + Uri.parse( filePath ) );
// "regular"
// Regular: content://media/external/images/media/28 : content://media/external/images/media/28
U.log( "Regular: " + data.getDataString() + " : " + Uri.parse( data.getDataString() ) );
// Regular 2: content://media/external/images/media/28 : content://media/external/images/media/28
U.log( "Regular 2: " + data.getData() + " : " + data.getData() );
mPostImagePreview.setImageBitmap( BitmapFactory.decodeFile( filePath ) );
mPostImagePreview.setVisibility( View.VISIBLE );
They still set the wrong image. If I go into the Gallery, long press the image, and view its details I get:
TItle: Pic
Time: May 2, 2012
Width: 720
Height: 1280
Orientation: 0
File size: 757KB
Maker: Abso Camera
Model: Inspire 4G
Path: /mnt/sdcard/Pic.jpg
So, the Gallery is telling me the path is the same as the pick action, and the Gallery is rendering it correctly. So why on earth is it not rendering if I set it from onActivityResult?
Also, this is the code I'm using to fire the Intent now:
private void selectPhoto()
{
Intent intent = new Intent( Intent.ACTION_GET_CONTENT );
intent.setType( "image/*" );
( ( Activity )mContext ).startActivityForResult( Intent.createChooser( intent, "Select Picture" ), PHOTO_GALLERY );
}
Sometimes the thumbnails in the gallery app can be outdated and show thumbnails for a different image. This can happen when the image ids are reused, for example when an image gets deleted and a new one is added using the same id.
Manage Apps > Gallery > Clear Data can fix this problem then.
This is the code to open gallery. However this the same what you have done. Also see the onActivityResult code which I used to retrive the selected image.
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"),
PHOTO_GALLERY);
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case PHOTO_GALLERY:
if (resultCode == RESULT_OK) {
Uri selectedImageUri = Uri.parse(data.getDataString());
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(
getApplicationContext().getContentResolver(),
selectedImageUri);
this.postImagePreview.setImageBitmap( bitmap);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
}
}
private static int RESULT_LOAD_IMAGE = 1;
Intent i = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RESULT_LOAD_IMAGE);
OnActivity Result
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
ImageView imageView = (ImageView) findViewById(R.id.imgView);
imageView.setImageBitmap(BitmapFactory.decodeFile(picturePath));
}
}
try this one
//Put this code on some event
Intent intent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, REQUEST_CODE);
// When above event fire then its comes to this
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode==RESULT_OK && requestCode==1){
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
filePath = cursor.getString(columnIndex);
cursor.close();
// Use it as per recruitment
actualBitmap =BitmapFactory.decodeFile(filePath);
}
}
Try this,
public class SelectPhotoActivity extends Activity {
private static final int SELECT_PICTURE = 1;
private String selectedImagePath="";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivityForResult(intent, SELECT_PICTURE);
}
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE)
{
Uri selectedImageUri = data.getData();
selectedImagePath = getPath(selectedImageUri);
// here you can set the image
}
}
}
}

Categories

Resources