android open gallery via intent ACTION_PICK vs ACTION_GET_CONTENT - android

in my app i would like to have the user choose an image from the gallery and retrieve the result (thumbnail + full image uri). i would also like the user to be able to choose which gallery app to open (i.e. default gallery app or some other gallery app).
initially, according to this guide by google i copied and pasted this code:
public void selectImage() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, REQUEST_IMAGE_GET);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_GET && resultCode == RESULT_OK) {
Bitmap thumbnail = data.getParcelable("data");
Uri fullPhotoUri = data.getData();
// Do work with photo saved at fullPhotoUri
...
}
}
while it does get me the thumbnail and the full Uri in onActivityResult(...), the problem is that it does not open a chooser for the user to select which gallery app to use and instead it opens this thing (see images below), which i assume is a default "image-chooser" thing where you could select another app via a menu.
i feel it's silly that the user would have to open this default "image chooser" first and once they are already in an "image chooser", select the gallery app that they actually want to use (sure, the user could just choose the image from this thing, but i want to give them a convenient choice).
so i changed my code to this and it does indeed display a proper chooser for the user and he can go straight to hes favorite gallery app:
Intent intent = new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
if (intent.resolveActivity(getActivity().getPackageManager()) != null)
{
startActivityForResult(intent, Utils.REQUEST_CODE_OPEN_GALLERY);
}
however now i have a new problem: in onActivityResult(...) the line data.getParcelable("data"); returns null. in other words, i don't get back a thumbnail.
i also tried
Bundle extras = data.getExtras();
Bitmap thumbnail = (Bitmap) extras.get("data");
but "extras" is null.
is it possible to have a proper "app chooser" AND get back a thumbnail?

however now i have a new problem: in onActivityResult(...) the line data.getParcelable("data"); returns null. in other words, i don't get back a thumbnail.
You do not get that from ACTION_GET_CONTENT, either. You can tell this by reading the documentation for ACTION_GET_CONTENT. It is certainly possible that there are some buggy ACTION_GET_CONTENT activities that happen to return a thumbnail Bitmap in a "data" extra, but you should not assume that any user will have such a buggy ACTION_GET_CONTENT activity, let alone choose it. Besides, ACTION_GET_CONTENT is not limited to images; what would a "thumbnail" be of application/json or text/csv be?
Likewise, if you read the documentation for ACTION_PICK, you will see that there is no discussion of a thumbnail.
is it possible to have a proper "app chooser" AND get back a thumbnail?
No, insofar as you do not get a thumbnail back from anything except ACTION_IMAGE_CAPTURE, and that is for taking photos.

Related

Impossible to take a picture from the app

I'm using different tab, almost the sames.
In my app, I want to take picture with the camera with this code
public void takePicture(View v) {
imageFilePath = file_path + "/" + "Photo_" + idFiche + ".png";
File imageFile = new File(imageFilePath);
Uri imageFileUri = Uri.fromFile(imageFile);
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageFileUri);
startActivityForResult(takePictureIntent, REQUEST_CODE_PICTURE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
InputStream stream = null;
if (requestCode == REQUEST_CODE_PICTURE && resultCode == Activity.RESULT_OK) {
//blablabla
}
}
It works well for some tab, but with others, it's impossible to click on the activation button of the photo app to save the picture, as indicated in below picture with the red border.
I think the camera app is wrong, even if I can take picture from the device directly (not from my app), but how to solve it? Can I delete the picture app and use another app with the same code? Or launch a specific app through new intent???
Thank for your help
I think the camera app is wrong
Most likely. Many camera apps seem to go through little testing of ACTION_IMAGE_CAPTURE.
how to solve it?
Stop using ACTION_IMAGE_CAPTURE. Use the camera APIs directly or through a third-party library.
Can I delete the picture app
If by "the picture app", you mean "the camera app", it is likely that the camera app is pre-installed and cannot be uninstalled. Plus, the user may not appreciate you attempting to uninstall their camera app.
and use another app with the same code?
Your code will already give the user a choice of camera apps, if there is more than one that supports ACTION_IMAGE_CAPTURE installed on the device.
Or launch a specific app through new intent?
It is highly unlikely that your desired "specific app" exists on the device.

Photo intent, don't understand the path

When I launch a Photo Capture intent, the photo path that is gave to me in return is : content://media/external/images/media/40209 but when I look in my device, the photo path should have been something like [..]/pictures/1456164469539.jpg
Do you know how to get the second path from the first ?
note I use the method described there Android ACTION_IMAGE_CAPTURE Intent by yanokwa.
Thanks,
-------------------- EDIT
I launch my intent like so :
private void launchPhotoIntent() {
Uri photoUri = getActivity().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new ContentValues());
Log.i("renaud","photoUri : "+mPhotoUri.toString());
SharedPreferences sharedPreferences = getActivity().getSharedPreferences(AppConstants.SP,Context.MODE_PRIVATE);
sharedPreferences.edit().putString("test",photoUri.toString()).commit();
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
getActivity().startActivityForResult(intent, ACTION_TAKE_PHOTO);
}
and In my Callback :
else if(requestCode == PostMessageWindowFragment.ACTION_TAKE_PHOTO && resultCode == Activity.RESULT_OK){
Uri uri = Uri.parse(sharedPreferences.getString("test",null)); // data.getData();
File file = new File(event.uri.getPath());
Log.i("PICTEST",""+file.length());
}
It logs "0"
When I launch a Photo Capture intent, the photo path that is gave to me in return is : content://media/external/images/media/40209
That is not a path. That is a Uri, pointing to content.
the photo path should have been something like [..]/pictures/1456164469539.jpg
Not necessarily.
First, there are thousands of Android device models and thousands of camera apps (both pre-installed and installed by users), some of which implement ACTION_IMAGE_CAPTURE. What one camera app does will not necessarily match what another camera app does.
Second, if you read the documentation for ACTION_IMAGE_CAPTURE, you will notice that there is no "photo path that is gave to me in return". If you supply EXTRA_OUTPUT, your photo should be in that location. If you do not, use getExtra("data") on the Intent passed to onActivityResult() to get a thumbnail bitmap. You appear to be assuming that the Intent will have a Uri, and few camera apps do that.
Do you know how to get the second path from the first ?
That is not possible in general, as a Uri does not have to point to a file, let alone a file that you can access. Use ContentResovler to work with Uri values, such as openInputStream() to read in the content pointed to by a Uri.
The path you get is the file URI. Try with converting it to path using this Convert file: Uri to File in Android

Get path of image from intent when using camera and putting EXTRA_OUPUT parameter

I'm currently creating a functionnality for the user to upload images to my server. He can either takes pictures with his camera or from his gallery.
I'm using this code to take a picture with the camera :
// create Intent to take a picture and return control to the calling application
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
tempFile = File.createTempFile(String.valueOf(System.currentTimeMillis()), ".jpeg", ContextCompat.getExternalCacheDirs(a)[0]);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(tempFile));
// start the image capture Intent
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
And then to manipulate the image I use onActivityResult as such :
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// use tempFile to recreate bitmap and do some heavy-wooshy-wishy stuff
...
}
}
It works totally fine but I'm confused with the Intent data parameter when using the camera. In this case it is null and to use the taken picture I need to re-create it from the path I gave to the ... intent.
What I find especially confusing is that if I don't put any EXTRA_OUTPUT parameter, then the Intent data isn't null and I can easily get the path of the picture with data.getData().
BUT THEN I just get a thumbnail from the original picture.
Is there any way to get the original picture from the camera and the path from the intent ? I don't have any real use case, but let's say the tempFile field gets modified or destroyed when you're taking the picture. Then on onActivityResult you will not be able to use the just taken picture.
What I find especially confusing is that if I don't put any EXTRA_OUTPUT parameter, then the Intent data isn't null and I can easily get the path of the picture with data.getData().
Not generally. There is no requirement for ACTION_IMAGE_CAPTURE to provide you a path to anything. Getting a thumbnail back via the data extra, if you do not provide EXTRA_OUTPUT, is the only "result" that you are supposed to get back in onActivityResult().
Is there any way to get the original picture from the camera and the path from the intent ?
No, because you never get the path from the Intent. It may be that a few camera apps leak this information. Not all will.
but let's say the tempFile field gets modified or destroyed when you're taking the picture
It is your job to not make that sort of mistake. For example, make sure that you retain this value across configuration changes and short-lived process termination, via onSavedInstanceState().

Android Intent.ACTION_PICK

This code successfully retrieves images from the (emulator) SDcard:
public void pickImage(View v) {
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, REQUEST_IMAGE_GET);
}
}
This returns a bunch of thumbnails titled Choose Picture. Is there any way I can intercept this and filter out certain images first?
Clicking any thumbnail image then runs the OnActivityResult which I can intercept, but then it is too late.
I am using Metadator-extractor and only need to display images containing certain tags, but do not know how to access each
thumbnail before it arrives on the screen.
Is there any way I can intercept this and filter out certain images first?
Not with ACTION_PICK. You are welcome to query MediaStore for available pictures and implement your own pick activity, in which you can filter out whatever you want.

Using Intent for taking photo and edit preview

I'm taking photo using following code:
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK)
{
Bitmap photo = (Bitmap) data.getExtras().get("data");
ImageView img = (ImageView) findViewById(R.id.imageView1);
img.setImageBitmap(photo);
}
}
I want to edit Preview before delivering to my app.
After taking photo a dialog shown that user must confirm photo. I want to edit image on this preview.
Update :
in fact I want to add a watermark to photo. When user click capture button, he must see an image with watermark and not original image!
Is it possible or I must use Camera API instead of Intent?
I want to edit Preview before delivering to my app.
There is no requirement that an ACTION_IMAGE_CAPTURE activity have any means to allow you to force the user to edit the image before it is returned to you in onActivityResult().
After taking photo a dialog shown that user must confirm photo.
There is no requirement that an ACTION_IMAGE_CAPTURE activity have any means to allow you to force the user to confirm the image before it is returned to you in onActivityResult().
The implementation of ACTION_IMAGE_CAPTURE activities is up to the developers of those activities, not you.
or I must use Camera API instead of Intent ?!
Using a native camera API will not help you, as the native camera API does not offer an image editor. If you want the user to edit an image, you will need to either try ACTION_EDIT on the image (which may or may not be supported on any given device) or add an image editor to your app.

Categories

Resources