Getting path to URI is always null? - android

So i am using retrofit to upload images to our server, and am using gallery chooser to choose the image. I am trying to get the path of the image, because uri.getPath() returns file not found exception. I have literally seen almost every stackoverflow article on this subject, and still have no answer. The following code that I have is similar to everything I have seen online, and it ALWAYS returns null, and I have no idea why. PLEASE HELP
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
try {
android.net.Uri selectedImage = data.getData();
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), selectedImage);
// Log.d(TAG, String.valueOf(bitmap));
ImageView imageView = (ImageView) findViewById(R.id.expandedProfilePic);
imageView.setImageBitmap(bitmap);
String[] filePathColumn = {MediaStore.Images.Media.DATA};
android.database.Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
if (cursor == null)
return;
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filePath = cursor.getString(columnIndex);
cursor.close();
// is always null
System.out.println("FILE PATH " + filePath);
} catch (IOException e) {
e.printStackTrace();
}
}
}

I am trying to get the path of the image, because uri.getPath() returns file not found exception
Assuming that by "gallery chooser", you mean ACTION_GET_CONTENT or possibly ACTION_PICK, there is no path, because a Uri is not a file.
I have literally seen almost every stackoverflow article on this subject
No, you have not. Specifically, you have not read any of the dozens that I have contributed to, such as this one or this one or this one or this one or this one or this one or this one or this one or this one or this one or this one or this one or this one. And those are just from 2017.
The following code that I have is similar to everything I have seen online
And that code will not work for most Uri values.
Use a ContentResolver and openInputStream() to get an InputStream on the content identified by the Uri. Ideally, you would just use the InputStream. In the case of Retrofit, while I have not tried uploading content with it, my guess is that it insists upon a file. In that case, use the InputStream and a FileOutputStream on some file that you control to make a copy of the content. Then, upload the copy, deleting it when you are done.

Related

Selecting image from gallery not working on Redmi Note 4

I have seen a couple of other questions on S/O related to this, but the one that was closest to my issue doesn't seem to have got many responses (Xiaomi MI device not picking image from Gallery). Hoping this question will have better luck.
I am trying to select an image from the gallery of the phone, and pass the image path to another activity where it get previewed for the user.
I've tested this on two other devices (Moto E and something called Coolpad?) and they both seem to be working just fine.
(Debugging Android source code doesn't seem to be a practical option.)
In the main activity, on a UI trigger, I launch the gallery picker with the following code:
private void dispatchPickPictureIntent() {
Intent pickPictureIntent = new Intent(Intent.ACTION_PICK);
pickPictureIntent.setType("image/*");
startActivityForResult(pickPictureIntent, REQUEST_IMAGE_PICK);
}
I handle the result like so:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_PICK && resultCode == RESULT_OK) {
Uri selectedImage = data.getData();
mCurrentPhotoPath = getRealPathFromURI(this, selectedImage);
launchUploadActivity();
}
}
private String getRealPathFromURI(Context context, Uri uri) {
Cursor cursor = null;
try {
String [] proj = {MediaStore.Images.Media.DATA};
cursor = context.getContentResolver().query(uri, 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();
}
}
Once I have got the file path stored in the global variable mCurrentPhotoPath the following method gets called:
private void launchUploadActivity() {
Intent intent = new Intent(HomeActivity.this, UploadActivity.class);
intent.putExtra(getString(R.string.photo_path), mCurrentPhotoPath);
startActivityForResult(intent, REQUEST_IMAGE_UPLOAD);
}
Even on the Redmi, up until here, things run smoothly. On the onCreate method of the UploadActivity, I receive the image file path string successfully.
But, then, I try to preview the image:
private void previewPhoto() {
imageView.setVisibility(View.VISIBLE);
BitmapFactory.Options options = new BitmapFactory.Options();
// Avoid OutOfMemory Exception
options.inSampleSize = 8;
// This line returns a null, only on the Xiaomi device
final Bitmap bitmap = BitmapFactory.decodeFile(photopath, options);
imageView.setImageBitmap(bitmap);
}
Now I have tried to debug this issue, but once I step into BitmapFactory's source code, I run in to a seemingly unresolved issue with Android Studio (https://stackoverflow.com/a/40566459/3438497) which renders it useless.
Any pointers on how I can proceed from here would be greatly appreciated.
So I was able to narrow down the issue to an incorrect file path. The Uri to filepath function did not get the desired result on all devices.
I used the approach suggested here:https://stackoverflow.com/a/7265235/3438497
and tweaked the code a little bit so that when picking images from gallery, I use the Uri of the image directly.
The reason is that you get file:// uri back. not content:// so content resolver doesn't work.
I am facing the similar issue in Redmi 5A. And solve the problem using following way.
Add below entities in your manifest file
android:hardwareAccelerated="false"
android:largeHeap="true"
It will work in some environments.
Refer answer at https://stackoverflow.com/a/32245018/2706551

Pick image from gallery, including Picasa/AutoBackup images

I am dealing with Pick gallery images and show them in app also save their Path for some references in future.
I was able to Pick those images from gallery which are stored on device like in some folder like Downloads by this code:
Intent intent = new Intent (Intent.ActionPick, Android.Provider.MediaStore.Images.Media.ExternalContentUri);
intent.SetType ("image/*");
StartActivityForResult (Intent.CreateChooser (intent, "Select photo"), 0);
and in Result:
public override void OnActivityResult (int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult (requestCode, resultCode, data);
case 0:
string FilePath = GetPathToImage (data.Data);
}
private string GetPathToImage(Android.Net.Uri uri)
{
string path = null;
string[] projection = new[] { Android.Provider.MediaStore.Images.Media.InterfaceConsts.Data };
using (ICursor cursor = this.Activity.ManagedQuery(uri, projection, null, null, null))
{
if (cursor != null)
{
int columnIndex = cursor.GetColumnIndexOrThrow(Android.Provider.MediaStore.Images.Media.InterfaceConsts.Data);
cursor.MoveToFirst();
path = cursor.GetString(columnIndex);
}
else
{
return uri.Path;
}
}
}
My question is : I am able to get paths of images those are placed in some local folder in gallery, but for folders like Picasa/Autobackup I am not able to get Path.
Note:For local images path starts from content://
For Other com.android....like that.
So, Is there any workaround to get paths of those images.
I don't want to do like this to just display image:
final InputStream is = getContentResolver().openInputStream(imageUri);
I need a Path.
If there is no solution, then How can we skip those images being displayed while Picking from Gallery/Photos.
PS: Known Issue
Any Suggestion is appreciated.
Thanks

Android crashing when i take a picture on a real samsung galaxy s3

i made an application that will allow the user to take a camera shot and edit it using my application. I own a samsung galaxy stellar and it works fine on it. I had my friend download the application and when she tested it on her phone, my application crashes whenever she takes a picture and hit "save". shes using a galaxy s3.
Heres my code when im taking a picture
case R.id.ibTakePic:
i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)+File.sep arator + fileName2 + ".jpg");
i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
rotatePic = true;
startActivityForResult(i,cameraData);
break;
and heres my result code..
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
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 };
pictake = true;
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
rotatePic = false;
bmpReceive = rotate(picturePath);
bmpOriginal = bmpReceive;
picTaken.setImageBitmap(bmpReceive);
// ImageView imageView = (ImageView) findViewById(R.id.imgView);
// imageView.setImageBitmap(BitmapFactory.decodeFile(picturePath));
}
I had a similar problem so I switched to this:
Uri uri= data.getData();
InputStream in = context.getContentResolver().openInputStream(uri);
Bitmap b = BitmapFactory.decodeStream(in);
hope it helps
Well, Logs help. But here is my guess.
If you check the Documentation.
http://developer.android.com/reference/android/content/ContentResolver.html
A query can return a Cursor object or null.
In your code you are not checking for the null. I suggest you try with that. In any case you should always put null checks wherever there is a chance for a null to be returned.
If you can provide the logs then we can tell you the exact problem.
Maybe the bitmap is too big and you get an out of memory. Check that page to know how to deal with that situation:
http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

Retrieve Picasa Image for Upload from Gallery

I am working on an activity and associated tasks that allow users to select an image to use as their profile picture from the Gallery. Once the selection is made the image is uploaded to a web server via its API. I have this working regular images from the gallery. However, if the image selected is from a Picasa Web Album nothing is returned.
I have done a lot of debugging and narrowed the problem down to this method.
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
//cursor is null for picasa images
if(cursor!=null)
{
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
else return null;
}
Picasa images return a null cursor. MediaStore.Images.Media.DATA is not null for them, however. It only returns an #id, so I am guessing that there is no actual bitmap data at the address. Are Picasa images stored locally on the device at all?
I also noticed from the documentation that MediaStore.Images.ImageColumns.PICASA_ID exists. This value exists for selected picasa images but not other gallery images. I was thinking I could use this value to get a URL for the image if it is not store locally but I can not find any information about it anywhere.
I have faced the exact same problem,
Finally the solution I found, was to launch an ACTION_GET_CONTENT intent instead of an ACTION_PICK, then make sure you provide a MediaStore.EXTRA_OUTPUT extra with an uri to a temporary file.
Here is the code to start the intent :
public class YourActivity extends Activity {
File mTempFile;
int REQUEST_CODE_CHOOSE_PICTURE = 1;
(...)
public showImagePicker() {
mTempFile = getFileStreamPath("yourTempFile");
mTempFile.getParentFile().mkdirs();
Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
intent.setType("image/*");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTempFile));
intent.putExtra("outputFormat",Bitmap.CompressFormat.PNG.name());
startActivityForResult(intent,REQUEST_CODE_CHOOSE_PICTURE);
}
(...)
}
You might need to mTempFile.createFile()
Then in onActivityResult, you will be able to get the image this way
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
case REQUEST_CODE_CHOOSE_PICTURE:
Uri imageUri = data.getData();
if (imageUri == null || imageUri.toString().length() == 0) {
imageUri = Uri.fromFile(mTempFile);
file = mTempFile;
}
if (file == null) {
//use your current method here, for compatibility as some other picture chooser might not handle extra_output
}
}
Hope this helps
Then you should delete your temporary file on finish (it is in internal storage as is, but you can use external storage, I guess it would be better).
Why are you using the managedQuery() method? That method is deprecated.
If you want to convert a Uri to a Bitmap object try this code:
public Bitmap getBitmap(Uri uri) {
Bitmap orgImage = null;
try {
orgImage = BitmapFactory.decodeStream(getApplicationContext().getContentResolver().openInputStream(uri));
} catch (FileNotFoundException e) {
// do something if you want
}
return orgImage;
}

Picking images from gallery (SD Card) on my app… ¿How to allow only max 500kb photos?

WHAT I HAVE DONE NOW:
i am picking images on my app with android, and showing them on a ImageView of my layout, and sometimes i got an exception java.lang.OutOfMemoryError: bitmap size exceeds VM budget. This happens when the photos are higher than 500kb.
WHAT I NEED TO DO (AND I DONT KNOW HOW TO DO IT):
then, what i want to do is to allow the user only to select photos of maximum 500kb. And if the user selects a photo Higher than 500kb, then, my app should show a toast telling the user that only can select photos of max 500kb.... ¿how to do it?
this is my code:
changeImageButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI);
startActivityForResult(i, ACTIVITY_SELECT_IMAGE);
}
});
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch(requestCode) {
case 1:
{
setResult(1);
finish();
}
case ACTIVITY_SELECT_IMAGE:
if(resultCode == RESULT_OK){
Uri selectedImage = imageReturnedIntent.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 filePath = cursor.getString(columnIndex);
cursor.close();
selectedPhoto = BitmapFactory.decodeFile(filePath);
//profileImage.setImageBitmap(selectedPhoto);
profileImage.setImageBitmap(Bitmap.createScaledBitmap(selectedPhoto, 80, 80, false));
}
}
}
profileImage is a ImageView of my layout. and i use scaled butmap to resice the image to 80x80
please give me some help to do that, im searching on google and i can't find nothing
Can't you just use some standard Java to get the file size, then check against your limit?
private long getFileSize(String path) {
File file = new File(path);
if (file.exists() && file.isFile()) {
return file.length();
} else {
return 0L;
}
}
Why do you hate your users so much? You are asking the wrong question... you don't need to cap the file size at all. It's the decompressed image size that's the problem, and you can control that.
Use the version of BitmapFactory.decodeFile() which takes a BitmapFactory.Options parameter, and then set the inSampleSize field of the options parameter to an appropriate value (2 or 4 or something). You may even want to use inJustDecodeBounds first to work out a reasonable value.

Categories

Resources