Google Photos vs Stock Gallery - Intent Picker - android

In my app, I allow the user to pick a profile image from their gallery, like so:
When You click the first option, on my Android 5.0 device, I get this:
If I use the normal Gallery app that is based off the AOSP project, everything works fine and dandy. However, the Photo's app appears to use a different intent.
Here is how I handle code for the normal gallery:
Intent photoPickerIntent = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
photoPickerIntent.setType("image/*");
photoPickerIntent.putExtra("crop", "true");
photoPickerIntent.putExtra("outputX", 300);
photoPickerIntent.putExtra("outputY", 300);
photoPickerIntent.putExtra("aspectX", 1);
photoPickerIntent.putExtra("aspectY", 1);
photoPickerIntent.putExtra("scale", true);
photoPickerIntent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri());
photoPickerIntent.putExtra("outputFormat",
Bitmap.CompressFormat.JPEG.toString());
startActivityForResult(photoPickerIntent, RESULT_LOAD_IMAGE);
And then the intent result handler:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RESULT_LOAD_IMAGE
&& resultCode == Activity.RESULT_OK) {
if (data != null) {
tempFile = getTempFile();
filePath = Environment.getExternalStorageDirectory() + "/"
+ "temporary_holder.jpg";
Log.d("LOAD REQUEST filePath", filePath);
Bitmap selectedImage = BitmapFactory.decodeFile(filePath);
iPP.setImageBitmap(selectedImage);
}
imagePath = filePath;
new UploadImage().execute();
}
}
Some of the helper functions from above:
private static Uri getTempUri() {
return Uri.fromFile(getTempFile());
}
private static File getTempFile() {
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
File file = new File(Environment.getExternalStorageDirectory(),
"temporary_holder.jpg");
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
return file;
}
return null;
}
Some of that is probably not needed to show but I included it all in case it is interfering.
When I use Google Photos to pick a photo, my ImageView is blank (instead of filling with selected pick). The image is not selected and I can't go to the manual cropping view like I have it set with the Gallery. So basically, nothing happens.
NEW CODE IN RESPONSE TO ANSWER
photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT);
photoPickerIntent.setType("image/*");
photoPickerIntent.putExtra("crop", "true");
photoPickerIntent.putExtra("outputX", 300);
photoPickerIntent.putExtra("outputY", 300);
photoPickerIntent.putExtra("aspectX", 1);
photoPickerIntent.putExtra("aspectY", 1);
photoPickerIntent.putExtra("scale", true);
photoPickerIntent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri());
photoPickerIntent.putExtra("outputFormat",
Bitmap.CompressFormat.JPEG.toString());
startActivityForResult(photoPickerIntent, RESULT_LOAD_IMAGE);
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
if (data != null) {
Log.i("data", data.toString());
switch (requestCode) {
case RESULT_LOAD_IMAGE:
Log.i("RESULT_LOAD_IMAGE", "MARK");
// Received an image from the picker, now send an Intent for cropping
final String CROP_ACTION = "com.android.camera.action.CROP";
Intent photoCropIntent = new Intent(CROP_ACTION);
photoCropIntent.putExtra("crop", "true");
photoCropIntent.putExtra("aspectX", 1);
photoCropIntent.putExtra("aspectY", 1);
photoCropIntent.putExtra("outputX", 300);
photoCropIntent.putExtra("outputY", 300);
photoCropIntent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri());
photoCropIntent.putExtra("outputFormat",
Bitmap.CompressFormat.JPEG.toString());
photoCropIntent.setData(data.getData());
startActivityForResult(photoPickerIntent, RESULT_CROP_IMAGE);
break;
case RESULT_CROP_IMAGE:
Log.i("RESULT_CROP_IMAGE", "MARK");
tempFile = getTempFile();
imagePath = Environment.getExternalStorageDirectory() + "/" + "temporary_holder.jpg";
Log.i("imagePath", imagePath);
Uri selectedImageURI = data.getData();
InputStream image_stream;
try {
image_stream = getActivity().getContentResolver().openInputStream(selectedImageURI);
Bitmap bitmap = BitmapFactory.decodeStream(image_stream);
iPP.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
new UploadImage().execute();
break;
default:
// Handle default case
}
}
}
}
The above code isn't working either. I tried to make it resemble the answer below. What happens is:
I click "Choose from Gallery". And it does not give me a choice anymore, now it opens directly from the stock Gallery (that is not a big deal). I click on the image, and it ... appears to start the same intent over again -- it brings back the gallery wanting me to pick another image: instead of the Cropping Activity. Then after the second time, it will set my ImageView with the selected file.

Solution
First, update the photoPickerIntent to use ACTION_GET_CONTENT, and remove the extras related to cropping, since cropping will be handled by another Intent later:
Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT);
photoPickerIntent.setType("image/*");
// Do not include the extras related to cropping here;
// this Intent is for selecting the image only.
startActivityForResult(photoPickerIntent, RESULT_LOAD_IMAGE);
Then, onActivityResult() will have to handle two results: RESULT_LOAD_IMAGE will send another intent for the crop, and RESULT_CROP_IMAGE will continue processing as you did before:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
if (data != null) {
switch (requestCode) {
case RESULT_LOAD_IMAGE:
// Received an image from the picker, now send an Intent for cropping
final String CROP_ACTION = "com.android.camera.action.CROP";
Intent photoCropIntent = new Intent(CROP_ACTION);
photoCropIntent.setData(data.getData());
// TODO: first get this running without extras, then test each one here
startActivityForResult(photoCropIntent, RESULT_CROP_IMAGE);
break;
case RESULT_CROP_IMAGE:
// Received the cropped image, continue processing. Note that this
// is just copied and pasted from your question and may have
// omissions.
tempFile = getTempFile();
filePath = Environment.getExternalStorageDirectory() + "/"
+ "temporary_holder.jpg";
Log.d("LOAD REQUEST filePath", filePath);
Bitmap selectedImage = BitmapFactory.decodeFile(filePath);
iPP.setImageBitmap(selectedImage);
imagePath = filePath;
new UploadImage().execute();
break;
default:
// Handle default case
}
}
}
Note that although I've tested parts of this code, I haven't tested this entire block of code at runtime. If it doesn't work right out-of-the-box, though, it should be pretty close. Please comment if you have any questions or issues, and I'll update my answer accordingly.
Background
On an Android 5.0.1 (API 21) device with both AOSP Gallery2 (com.android.gallery3d) and Photos installed, I ran your Intent. I was prompted to choose between Gallery or Photos.
When I chose Photos, a picker was presented, and I picked an image. I was immediately returned to my Activity, with no cropping options.
When I chose Gallery, a picker was presented, and I picked an image. I was then prompted to choose an app for cropping. Both Photos and Gallery were presented as options for cropping.
Here's the interesting log output when choosing Gallery:
// Send the Intent
3-07 15:20:10.347 719-817/? I/ActivityManager﹕ Displayed android/com.android.internal.app.ResolverActivity: +127ms
// Choose Gallery
03-07 15:20:27.762 719-735/? I/ActivityManager﹕ START u0 {act=android.intent.action.PICK typ=image/* flg=0x3000000 cmp=com.android.gallery3d/.app.GalleryActivity (has extras)} from uid 10084 on display 0
// (fixing highlighting after MIME type on previous line) */
03-07 15:20:27.814 22967-22967/? W/GalleryActivity﹕ action PICK is not supported
03-07 15:20:27.814 22967-22967/? V/StateManager﹕ startState class com.android.gallery3d.app.AlbumSetPage
03-07 15:20:27.967 719-817/? I/ActivityManager﹕ Displayed com.android.gallery3d/.app.GalleryActivity: +190ms
// Pick an image
3-07 15:21:45.993 22967-22967/? V/StateManager﹕ startStateForResult class com.android.gallery3d.app.AlbumPage, 1
03-07 15:21:46.011 22967-22967/? D/AlbumPage﹕ onSyncDone: ********* result=0
03-07 15:21:46.034 22967-24132/? I/GLRootView﹕ layout content pane 1080x1701 (compensation 0)
03-07 15:21:48.447 719-1609/? I/ActivityManager﹕ START u0 {act=com.android.camera.action.CROP dat=content://media/external/images/media/1000 flg=0x2000000 cmp=android/com.android.internal.app.ResolverActivity (has extras)} from uid 10100 on display 0
First, note W/GalleryActivity﹕ action PICK is not supported. I'm not sure why it works, but according to Dianne Hackborn, "...you should consider ACTION_PICK deprecated. The modern action is ACTION_GET_CONTENT which is much better supported..." I've addressed this in my solution above.
The good news is, however, it seems that after picking an image, .putExtra("crop", "true"); causes Gallery to send another Intent for cropping. And the log clearly shows the action and data to use.
I tested this cropping intent, and I was prompted to choose an app for cropping, just like before. And again, both Photos and Gallery were presented as options, and they both brought up cropping interfaces.
It seems that although Photos supports cropping by Intent, it just ignores the extras relating to cropping in ACTION_PICK, whereas Gallery responds by sending another Intent after picking an image. Regardless, having the details of a working cropping Intent leads to the solution above.

I have solved this problem this way.
Pick image:
private void pickUserImage() {
if (doHavePermission()) {
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
photoPickerIntent.setType("image/*");
photoPickerIntent.putExtra("crop", "true");
photoPickerIntent.putExtra("scale", true);
photoPickerIntent.putExtra("outputX", 256);
photoPickerIntent.putExtra("outputY", 256);
photoPickerIntent.putExtra("aspectX", 1);
photoPickerIntent.putExtra("aspectY", 1);
photoPickerIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
photoPickerIntent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri());
startActivityForResult(photoPickerIntent, PICK_FROM_GALLERY);
}
}
used method getTempUri() is
private Uri getTempUri() {
return Uri.fromFile(getTempFile());
}
private File getTempFile() {
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
File file = new File(Environment.getExternalStorageDirectory(),TEMP_PHOTO_FILE);
try {
file.createNewFile();
} catch (IOException e) {
Log.printStackTrace(e);
}
return file;
} else {
return null;
}
}
get the picked image
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
if (requestCode == PICK_FROM_GALLERY) {
if (data!=null) {
Uri selectedImageUri = data.getData();
//String tempPath = getPath(selectedImageUri, UserProfileActivity.this);
String url = data.getData().toString();
if (url.startsWith("content://com.google.android.apps.photos.content")){
try {
InputStream is = getContentResolver().openInputStream(selectedImageUri);
if (is != null) {
Bitmap selectedImage = BitmapFactory.decodeStream(is);
//You can use this bitmap according to your purpose or Set bitmap to imageview
if (selectedImage != null) {
isImageUpdated = true;
isImageUpdated = true;
Bitmap resizedBitmap = null;
if (selectedImage.getWidth() >= 256 && selectedImage.getHeight() >= 256) {
resizedBitmap = Bitmap.createBitmap(selectedImage,
selectedImage.getWidth() - 128,
selectedImage.getHeight() - 128,
256, 256);
}
if (resizedBitmap != null) {
imageViewUserImage.setImageDrawable(ImageHelper.getRoundedCornerImage(resizedBitmap, 20));
} else {
imageViewUserImage.setImageDrawable(ImageHelper.getRoundedCornerImage(selectedImage, 20));
}
}
}
} catch (FileNotFoundException e) {
Log.printStackTrace(e);
}
} else {
File tempFile = getTempFile();
String filePath = Environment.getExternalStorageDirectory() + "/" + TEMP_PHOTO_FILE;
Log.d(TAG, "path " + filePath);
Bitmap selectedImage = BitmapFactory.decodeFile(filePath);
if (selectedImage != null) {
isImageUpdated = true;
imageViewUserImage.setImageDrawable(ImageHelper.getRoundedCornerImage(selectedImage, 20));
}
if (tempFile.exists()) {
tempFile.delete();
}
}
}
}
}
super.onActivityResult(requestCode, resultCode, data);
}
Image converted to rounded corner image as follows:
public class ImageHelper {
public static RoundedBitmapDrawable getRoundedCornerImage(Bitmap bitmap, int cornerRadius) {
RoundedBitmapDrawable dr = RoundedBitmapDrawableFactory.create(null, bitmap);
dr.setCornerRadius(cornerRadius);
return dr;
}
}
Its too late to answer but it can help someone else.

Related

Android cannot open photo with intent

I'm trying to open my photo with intent to view it in my phone's default gallery app, but when I do so, my app flashes and reloads without providing any errors. I'm trying to open my photo like this:
Uri uri = FileProvider.getUriForFile(context, "www.markwen.space.fileprovider", file);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, "image/jpg");
startActivity(intent);
I cannot find anything wrong in here. I'm thinking if it would be when I save my photo, which is taken using the camera, I didn't encode it correctly. When I save my photo, I simply follow the instructions here: https://developer.android.com/training/camera/photobasics.html
So how do you guys save your photo after you take the photo with your phone's camera app? What can I do to open up my photo? Thanks
Update:
here is how I take the photo:
private void startPhotoIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Create photo file
File photo = new File(getFileDirectory(".jpg"));
// Save intent result to the file
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(getContext(), "www.markwen.space.fileprovider", photo));
if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
// Start intent to take the picture
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
here is the way I am saving the photos I took:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// Photo
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == -1) {
Uri imageUrl = data.getData();
if (imageUrl != null) {
// Announce picture to let other photo galleries to update
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mediaScanIntent.setData(imageUrl);
getActivity().sendBroadcast(mediaScanIntent);
try {
MediaStore.Images.Media.insertImage(getContext().getContentResolver(), directory + filename, "Multimedia-Image", "Multimedia-Image");
Toast.makeText(getContext(), "Image saved to gallery", Toast.LENGTH_LONG).show();
filename = "";
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
}
Get the absolut path of your image
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(file.getAbsolutePath())));
i'm not sure what your trying to do,
saving the picture to the phone is easy,
deepending on what intent you are using.
i would look for a way to change the intent so to specify the saving location for the image itself
Google for EXTRA_STREAM EXTRA_OUTPUT

Getting exception for image cropping using intent in android lollipop version. How to crop an image using crop intent in above 5.0 versions?

I have the following code for cropping images. It's working perfectly in android version 4 or OS Kitkat, but its not working on Android version 5 or OS Lollipop.
I have searched in google but I didn't find perfect answer.
//Cropping image using intent
private void doCrop() {
#SuppressWarnings("unused")
final ArrayList<CropOptionAdapter.CropOption> cropOptions = new ArrayList<CropOptionAdapter.CropOption>();
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setType("image/*");
List<ResolveInfo> list = context.getPackageManager().queryIntentActivities(intent, 0);
int size = list.size();
//if no crop applications are available return the process
if (size == 0) {
return;
} else {
intent.setData(mImageCaptureUri);
intent.putExtra("outputX", 200);
intent.putExtra("outputY", 200);
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
intent.putExtra("return-data", true);
if (size > 0) {
Intent i = new Intent(intent);
ResolveInfo res = list.get(0);
i.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
context.startActivityForResult(i, CROP_PHOTO_SELECTED);
}
}
}
In above method i am calling cropping intent, and handling result in onActivityResult(). Below 5.0 versions I am getting crop image result datam But in above 5.0.1 versions I am getting data as null.
Below is my onActivityResult().
//OnActivityResult
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case ACTION_PHOTO:
case PICK_FROM_CAMERA:
case PICK_FROM_GALLERY:
case CROP_PHOTO_SELECTED:
myPhotoCaptureOnResult(requestCode, resultCode, data);
}
//Cropping image based on requestcode
public void myPhotoCaptureOnResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
switch (requestCode) {
case ACTION_PHOTO: {
if (resultCode == Activity.RESULT_OK) {
//setting image from singleton class which is store at time of capture in PhoneIntentActivity
if (Singleton.getSingletonObj().getBitmap() != null) {
mCapture_photo.setImageBitmap(Singleton.getSingletonObj().getBitmap());
mCapture_photo.setPadding(5, 5, 5, 5);
}
}
}
break;
case PICK_FROM_CAMERA:
if (resultCode == Activity.RESULT_OK) {
// getting image uri from sharedpreferences
mImageCaptureUri = Uri.parse(context.getSharedPreferences(StringUtils.APP_PREFFS, Context.MODE_PRIVATE).getString(StringUtils.IMAGE_URI_KEY, null));
if (mImageCaptureUri != null) {
doCrop();
} else {
// showing toast when unable to capture the image
Debug.toastValid(context, "Unable to Capture Image Please Try again ...");
}
}
break;
case PICK_FROM_GALLERY:
if (resultCode == Activity.RESULT_OK) {
if (data.getData() != null) {
mImageCaptureUri = data.getData();
doCrop();
} else {
// showing toast when unable to capture the image
Debug.toastValid(context, "Unable to Capture Image Please Try again ...");
}
}
break;
case CROP_PHOTO_SELECTED:
if (resultCode == Activity.RESULT_OK) {
Bundle extras = data.getExtras();
if (extras != null) {
//getting the photo data from the crop intent
Bitmap photo = extras.getParcelable("data");
if (photo != null) {
mResizedBitMap = getResizedBitmap(photo, newHeight, newWidth);
Singleton.getSingletonObj().setBitmap(mResizedBitMap);
setBitMap(mResizedBitMap);
mCapture_photo.setImageBitmap(Singleton.getSingletonObj().getBitmap());
mCapture_photo.setPadding(5, 5, 5, 5);
}
}
}
break;
}
}
}
Below is my Logcat....
10-15 14:41:06.250 8332-8332/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.google.android.apps.photos, PID: 8332
java.lang.RuntimeException: Unable to resume activity {com.google.android.apps.photos/com.google.android.apps.photos.photoeditor.intents.EditActivity}: java.lang.UnsupportedOperationException: No 'output' extra specified and can not save to specified inputUri: content://com.google.android.apps.photos.contentprovider/-1/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F2236/ACTUAL/1186776521
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3017) at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3048)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1365)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5289)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
Caused by: java.lang.UnsupportedOperationException: No 'output' extra specified and can not save to specified inputUri: content://com.google.android.apps.photos.contentprovider/-1/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F2236/ACTUAL/1186776521
at com.google.android.apps.photos.photoeditor.intents.EditActivity.a(PG:13312)
at gpy.a(PG:88)
at mgf.a(PG:5197)
at mgg.a(PG:169)
at mgf.W_(PG:4114)
at ofw.a(PG:213)
at oft.a(PG:98)
at oft.l(PG:209)
at ogs.onResume(PG:68)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1257)
at android.app.Activity.performResume(Activity.java:6076)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3006)
            
By default, files saved to the internal storage are private to your
application and other applications cannot access them (nor can the
user).
Referenced from Storage Options on Android Developers Website.
ACTION_CROP launches an "other application" that supports cropping, and passes it the URI of the file to crop. If that file is in internal storage, it is not directly accessible to the cropping application.
Using a [FileProvider][1] to provide an internal file to other apps requires some configuration. Referenced From Setting Up File Sharing on Android Developers Website.
For more information and ideal solution that worked for me on Android 5.1.1, Please see this solution.
On Lollipop, the cropped image is returned as a String reference to a uri in the result data action value rather than the extras part. For example:
final String action = data.getAction();
Uri imageUri = Uri.parse(action)

I am making an application to take pic, save and display but intent is return null in above version and in android 1.6 its working fine

I am using this code it is working fine in 1.6 but it is crashing in 4.4?
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = new ExternalStorage(getApplicationContext()).getAlbumStorageDir(); // create a file to save the image
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
// start the image capture Intent
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
/*in onActivityResult*/
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
Uri uri = data.getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
ImageView imageView = (ImageView) findViewById(R.id.image);
imageView.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
} else if (resultCode == RESULT_CANCELED) {
} else {
}
}
I have gone through several post but all I didn't find correct one.
There is no requirement for ACTION_IMAGE_CAPTURE to return a Uri via onActivityResult().
You know where the image should be stored, as you are providing that via EXTRA_OUTPUT. Use the value you put into EXTRA_OUTPUT, rather than data.getData().

Open an image saved in SD card with option to crop it as in Gallery to apply as wallpaper

I have a application where I have some downloaded images in a folder in SD Card. I want to save it as a wallpaper.
using the below code user can set it as wallpaper.
WallpaperManager myWallpaperManager = WallpaperManager.getInstance(context);
myWallpaperManager.setBitmap(loadedImage);
However this does not bring up any UI for user to select a part of the image like crop operation when selecting a image from Gallery app to set wallpaper. I would like my code to trigger such a operation. When users click a button in my app I want to take them to gallery app with crop option to set the wallpaper.
Please let me know how to do this. Thank you.
You may want to try this:
To select from your library (SD Card included) - void selectPhoto():
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Choose photo to upload"), PICK_FROM_FILE);
To start the crop action - void doCrop():
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setType("image/*");
// Check if there is image cropper application installed.
List<ResolveInfo> list = getPackageManager().queryIntentActivities( intent, 0 );
int size = list.size();
// If no cropper application is found, throw a message.
if (size == 0) {
Toast.makeText(this, "Can not find image crop app", Toast.LENGTH_SHORT).show();
return;
// If there're cropper applications found, use the first
} else {
// Specify image path and cropping parameters
intent.setData(mImageCaptureUri);
intent.putExtra("outputX", 0);
intent.putExtra("outputY", 0);
intent.putExtra("return-data", true);
Intent i = new Intent(intent);
ResolveInfo res = list.get(0);
i.setComponent( new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
startActivityForResult(i, CROPPED_IMAGE);
Handle Activity results - void onActivityResult(int requestCode, int resultCode, Intent data)
if (resultCode != RESULT_OK) return;
switch (requestCode) {
case PICK_FROM_FILE:
mImageCaptureUri = data.getData();
doCrop();
break;
case CROPPED_IMAGE:
Bundle extras = data.getExtras();
try{
if (extras != null) {
Bitmap myImage = extras.getParcelable("data");
}
}
catch(Exception e)
{
e.printStackTrace();
}
break;
This code will activate crop action right after you selected the image.
Note that mImageCaptureUri is the selected image URI, it would be pass to intent of cropping action.

Email a full sized photo

I'm working on an app that, among other things, uses the device's camera to take a photo and then share it through email.
The problem I'm having is that I can't get the app to take the full sized picture. It always sends a reduced in resolution version of the photo, although the camera is set to 5MP and quality when compressing is set to 100. Below you have my code:
private void takePicture(){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 1);
}
public void onActivityResult(int requestCode, int resultCode, Intent data){
if(requestCode == CAMERA_PIC_REQUEST && resultCode == Activity.RESULT_OK){
picture = (Bitmap) data.getExtras().get("data");
pictureView.setImageBitmap(picture);
ContentValues values = new ContentValues();
values.put(Images.Media.TITLE, "Picture");
values.put(Images.Media.BUCKET_ID, "picture_ID");
values.put(Images.Media.DESCRIPTION, "");
values.put(Images.Media.MIME_TYPE, "image/jpeg");
pictureUri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values);
OutputStream outstream;
try{
outstream = getContentResolver().openOutputStream(pictureUri);
picture.compress(Bitmap.CompressFormat.JPEG, 100, outstream);
outstream.close();
}catch(FileNotFoundException e){
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
.....
share.setOnClickListener(new OnClickListener(){
public void onClick(View view){
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_SUBJECT, selectedType);
intent.putExtra(Intent.EXTRA_TEXT,Notes + "\nLocation: " + selectedLocation+"\nOwner: " + selectedOwner
+ "\nStatus: " + selectedStatus);
intent.putExtra(Intent.EXTRA_STREAM, pictureUri);
try{
startActivity(Intent.createChooser(intent, "Send mail..."));
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(getApplicationContext(), "There are no email clients installed.", Toast.LENGTH_SHORT).show();
}
}
});
There is an extra for the ACTION_IMAGE_CAPTURE intent with the key MediaStore.EXTRA_OUTPUT which takes an URI to a file as the value. If you don't supply this extra, a size-reduced version of the taken image is returned to onActivityResult() with the data intent.
The reason for this is that a full-sized camera picture is simply too big for the intent system to handle (it might work in theory, but slows down the whole intent processing a lot - intents should be as small as possible in general). So it can't be delivered like the small-size version.
To use this extra modify your takePicture() method, e.g. like this:
private void takePicture() {
File outputFile = new File(Environment.getExternalStorageDirectory(),
"image.jpg");
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(outputFile));
startActivityForResult(intent, 1);
}
This does work like your method above, with the exception that the camera app has written a full-size copy of the image into the file you specified when onActivityResult() is called.
This means you don't have to write the image to the disk on your own, just open it from there when your onClickListener() is executed like you did already.

Categories

Resources