Intent for selecting wallpaper with wallpaper region highlighting
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 actionATTACH_DATA
and componentcom.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 theIntent
a URI that specifies the image to set as the wallpaper, this class will inevitably execute the following code (see the class'sonResume
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 theCropImage
Activity... this is where you specify the cropped area using the soft-rectangle. When you specify the crop, the result is set toRESULT_OK
withrequestCode = CROP_DONE
. ThePhotographs
Activity switch-cases over these two constants and then sets the wallpaper accordingly (see thePhotographs
class'sonActivityResult
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