One user of my app reports that after upgrading to Android 10 my app on his device stopped displaying an image.
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setType("image/*");
intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setData(scannedUri);
startActivity(intent);
I have "targetSdkVersion 28" so the new Scoped Storage rules should not be operating.
Still I put "compileSdkVersion 29" and included in the Manifest file:
android:requestLegacyExternalStorage="true"
Still all my user has is an empty screen, while he could see an image before Android 10:
I had the same issue, and the combination of
<external-path name="pics" path="/" /> (used with FileProvider)
and
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
solved it for me (I am on SDK version 28).
Just wanted to say thank you for asking this question and providing the READ_URI_PERMISSION flag code, without that I couldn't get it working and I tried like 10 different things!
i think problem of image extension .jpeg,.jpg or other....
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setType("image/jpeg");
intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setData(scannedUri);
startActivity(intent);
If you pass Uri like this way, For example
Uri imageUri = Uri.parse("http://www.android.com");
Intent imageIntent = new Intent(Intent.ACTION_VIEW, imageUri);
By default, the system determines the appropriate MIME type required by an intent based on the Uri data that's included.
Setting the MIME type further specifies which kinds of activities should receive the intent.
For instance, If you want to display an image using the ACTION_VIEW Intent, you should specify a MIME type of image/*. This stop (someone) from doing something in apps that can "view" other types of data (like a map app) from being triggered by the intent.
I hope it'll help you.
I am using the ACTION_EDIT intent to launch the Android image editor in order to edit an image:
Intent editIntent = new Intent(Intent.ACTION_EDIT);
editIntent.setDataAndType(uri, "image/*");
When launching the intent with result, how do I retrieve the path of the edited / saved image?
I am using the ACTION_EDIT intent to launch the Android image editor in order to edit an image
Bear in mind that Android does not have an image editor. Some Android devices might ship with an image editor, and some users may have installed an image editor off of the Play Store or other distribution channels.
Also, since you know what the MIME type is of uri, you will have better results if you put the real MIME type into your Intent.
When launching the intent with result, how do I retrieve the path of the edited / saved image?
First, ACTION_EDIT does not support "launch the intent with result", which I am interpreting as meaning startActivityForResult(). As the ACTION_EDIT documentation states, there is no output. Just use startActivity().
Beyond that, you are the one who provided the Uri in the Intent for the editor, so at that point in time, you already knew what the Uri was that you handed to the editor. Hang onto that Uri in your saved instance state, so that you can ensure that you have the Uri even if Android terminates your process while the user is editing the image. While there is no requirement that an ACTION_EDIT Intent save the edited image back to the location specified by the Uri used to load the image, one hopes that most ACTION_EDIT activities do just that.
In my Android app, I use the following code to launch an image picker:
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/jpg");
startActivityForResult(intent, INTENT_PICK_IMAGE);
But unfortunately, the system gallery activity that is called by this also display videos. Is there a way to prevent this?
I use this to only allow image types:
intent.setType("image/*");
Edit: setType() is based on MIME type, not file extension (See here: http://developer.android.com/reference/android/content/Intent.html#setType(java.lang.String))
I would like to know if it's possible to create an Intent that makes the gallery cropper show wallpaper highlighting. This feature has been introduced in Honeycomb. To get an idea of what I'm looking for have a look at the tablet on the image (the three blue rectangles).
I had a look at the source code of the ICS gallery app, but I couldn't find what I'm looking for.
I would like to know if it's possible to create an Intent that makes
the gallery cropper show wallpaper highlighting.
Assuming you want your app to behave properly across all Android devices, the answer is no. Neither the cropping activity nor the highlighted crop-view is part of the public API; both are internal to the Gallery 3D app. In other words, you could spend all the time in the world trying to find an Intent action to get this to magically work for you, but the fact is that some devices simply won't support it. For example, many devices, such as the HTC Sense and Samsung Galaxy, have customized Android versions that have their own gallery app. Since these Gallery apps are specific to the companies that designed them, these devices won't necessarily have a CropImage class for you to launch.
That being said, in order to guarantee that your application works across all devices, you'll have to incorporate the cropping code directly into your project. And if for some reason you find a way to launch the crop activity with an Intent, you should test to see whether the com.android.gallery3d package exists at the very least, and handle it somehow.
I have included below a work-around that might help you incorporate the Android code into your project. I don't currently have access to a tablet running Honeycomb/ICS so I can't be more specific with regards to how to get it working on newer versions of Android, but I imagine it involves similar analysis and a bit of copying and pasting from the com.android.gallery3d package.
Reusing the "Crop Activity" on Android 2.x
I tested this on my Nexus One and just before the soft "crop-rectangle" popped up, I got the following logcat output:
I/ActivityManager( 94): Starting: Intent {
act=android.intent.action.CHOOSER
cmp=android/com.android.internal.app.ChooserActivity (has extras) } from pid 558
I/ActivityManager( 94): Starting: Intent {
act=android.intent.action.ATTACH_DATA
dat=content://media/external/images/media/648
typ=image/jpeg
flg=0x3000001
cmp=com.google.android.gallery3d/com.cooliris.media.Photographs (has extras) } from pid 558
I/ActivityManager( 94): Starting: Intent {
dat=content://media/external/images/media/648
cmp=com.google.android.gallery3d/com.cooliris.media.CropImage (has extras) } from pid 558
So from what I can tell, the sequence of events that occurs when you perform this action is as follows:
You navigate to an image in the gallery and select "set as...". An ActivityChooser pops up and you select "Wallpaper".
This selection fires an Intent with action ATTACH_DATA and component com.cooliris.media.Photographs, which is a class in the Android framework that serves as a "wallpaper picker" for the camera application; it just redirects to the standard pick action. Since we have given the Intent a URI that specifies the image to set as the wallpaper, this class will inevitably execute the following code (see the class's onResume method):
Intent intent = new Intent();
intent.setClass(this, CropImage.class);
intent.setData(imageToUse);
formatIntent(intent);
startActivityForResult(intent, CROP_DONE);
This fires another Intent that starts the CropImage Activity... this is where you specify the cropped area using the soft-rectangle. When you specify the crop, the result is set to RESULT_OK with requestCode = CROP_DONE. The Photographs Activity switch-cases over these two constants and then sets the wallpaper accordingly (see the Photographs class's onActivityResult method).
Unfortunately, for whatever reason the Android team decided to removed these functionalities from the SDK beginning with API 4 (Android v1.6)... so if you wanted to fire an Intent to perform these exact sequence of events, it would require you to sift through the com.cooliris.media package, and to copy and paste the relevant classes into your project. In my past experience, doing this is often more trouble than it is worth (unless it is to perform a relatively simple action) but it is definitely possible.
Here is a nice tutorial on how you might go about simplifying the process... it requires you to copy and paste 12 Java classes into your project as opposed to the entire com.cooliris.media package. These classes together should be enough to correctly fire up the CropImage Activity, but you will have to set the wallpaper manually upon the CropImage Activity's result.
Also note that the sample code provided assumes that you want to crop immediately after a picture is taken by the camera. In order to, for example, start the CropImage Activity with a pre-selected image from the gallery, you'd call,
Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, ACTIVITY_SELECT_IMAGE);
and then in onActivityResult, (if requestCode == ACTIVITY_SELECT_IMAGE and resultCode == RESULT_OK), launch the CropImage Activity with the Uri data given in the onActivityResult's third argument (see the sample code for an example on how to launch the Activity).
If anything, hopefully this will help point you in the right direction. Let me know how it goes and leave a comment if you want me to clarify anything.
I this will help:
public class CropSelectedImageActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, 1);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
final Bundle extras = data.getExtras();
Uri photoUri = data.getData();
if (photoUri != null) {
Intent intent = new Intent("com.android.camera.action.CROP");
//intent.setClassName("com.android.camera", "com.android.camera.CropImage");
intent.setData(photoUri);
intent.putExtra("outputX", 96);
intent.putExtra("outputY", 96);
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
intent.putExtra("return-data", true);
startActivityForResult(intent, 1);
}
}
}
}
taken from: ImageCropper
I haven't tried this but if you have a look here
Bundle newExtras = new Bundle();
// maybe that here - for more options see your source code link
newExtras.putString("circleCrop", "true");
Intent cropIntent = new Intent();
// Uri would be something from MediaStore.Images.Media.EXTERNAL_CONTENT_URI
cropIntent.setData(img.fullSizeImageUri());
// edit: it's inside com.android.gallery in case that is even installed.
// should work if you replace that with setClassName("com.android.gallery", "com.android.camera.CropImage")
cropIntent.setClass(this, CropImage.class);
cropIntent.putExtras(newExtras);
startActivityForResult(cropIntent, CROP_MSG);
Then this might work for you.
Via pick intent maybe that way:
Intent i = new Intent(Intent.ACTION_PICK);
i.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivity(i);
Just Do this!
Intent intent = new Intent(Intent.ACTION_ATTACH_DATA).setDataAndType(contentUri, "image/jpeg")
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
.putExtra("mimeType", "image/jpeg");
startActivity(Intent.createChooser(intent, getString(R.string.set_as)));
which "image/jpeg" is the image mimeType,
contentUri is the image uri
There is a nice library that's based on ICS's cropping screen (from the gallery app) , here .
You could modify it to your needs, to select the part to be cropped.
The code is based on Android's Gallery app (link here), under "/com/android/camera/gallery" , while the most important class is "CropImage" in "/com/android/camera/" . It's available for all even in case the library will be missing (Google's code is always available), as such:
git clone https://android.googlesource.com/platform/packages/apps/Gallery3D/
(and even if this won't be available, I'm sure there will be others)
Advantages over the other solutions here:
independent
customizable
cannot crash due the changes in the ROM. Other solutions assume the existance of exact classes and apps.
open source.
a real implementation, and not starting an intent to another app.
other solutions are highly non-recommended, just because of the usage of non-official intents, as written here . This is written by a very well known StackOverflow user called "CommonsWare" , who is very respectable user that you can count on in a lot of Android-related topics.
Again, the most recommended thing for cropping images is still a third party library. Not using workarounds of intents.
Try this
// Set Home wallpaper the image
public void setHomeWallpaper () {
BitmapDrawable bitmapDrawable = ((BitmapDrawable) imageView.getDrawable());
Bitmap bitmap = bitmapDrawable.getBitmap();
String bitmapPath = Images.Media.insertImage(getContentResolver(), bitmap, "", null);
Uri bitmapUri = Uri.parse(bitmapPath);
Intent intent = new Intent(Intent.ACTION_ATTACH_DATA).setDataAndType(bitmapUri, "image/jpeg")
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
.putExtra("mimeType", "image/jpeg");
startActivity(Intent.createChooser(intent, getString(R.string.background)));
Toast.makeText(PicassoDisplayImageAdapter.this, "قم بإختيار التطبيق المناسب لتعيين الصورة", Toast.LENGTH_SHORT).show();
}
I'm trying to use a standard Intent that will take a picture, then allow approval or retake. Then I want to save the picture into a file.
Here's the Intent I am using:
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE );
startActivityForResult( intent, 22 );
The documentation says:
The caller may pass an extra EXTRA_OUTPUT to control where this
image will be written. If the EXTRA_OUTPUT is not present, then a
small sized image is returned as a Bitmap object in the extra field. If
the EXTRA_OUTPUT is present, then the full-sized image will be
written to the Uri value of EXTRA_OUTPUT.
I don't pass extra output, I hope to get a Bitmap object in the extra field of the Intent passed into onActivityResult() (for this request). So where/how do you extract it? Intent has a getExtras(), but that returns a Bundle, and Bundle wants a key string to give you something back.
What do you invoke on the Intent to extract the bitmap?
Try calling getExtras().get("data") and casting the result to a Bitmap.
See here for an example.
On a related note, if you have the "crop" activity come up after taking the picture using intent.putExtra("crop", "true"), you'll get the cropped URI from getExtras().get("action").
I realize you've got this all fixed by now, just want to make sure no one tries to use this with crop and gets confused.
Reference: the apps-for-android LolCat activity.