Send bitmap to image picker / gallery application - android

I'm trying to add an option in my app to send an image inside my app to other app like gallery or image picker/selectors. For example, a third-party launcher, which wants to select an icon that is inside my app.
I'm using a RecyclerView grid, to show the list of icons.
This is my code to load the icons:
icons = mContext.getResources().getStringArray(R.array.icons);
list = new ArrayList<String>(Arrays.asList(iconNames));
loadIcon(list);
private void loadIcon(List<String> list) {
mThumbs = new ArrayList<>();
for (String extra : list) {
int res = mContext.getResources().getIdentifier(extra, "drawable", p);
if (res != 0) {
final int thumbRes = mContext.getResources().getIdentifier(extra, "drawable", p);
if (thumbRes != 0)
mThumbs.add(thumbRes);
}
}
}
And this is the code in the OnClick of grid item:
Intent intent = new Intent();
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeResource(mContext.getResources(), mThumbs.get(position));
} catch (Exception e) {
Log.v("Icons Picker Error", "Picker error: " + Log.getStackTraceString(e));
}
if (bitmap != null) {
intent.putExtra("icon", bitmap);
mContext.setResult(Activity.RESULT_OK, intent);
} else {
mContext.setResult(Activity.RESULT_CANCELED, intent);
}
mContext.finish();
Apparently, icon bitmap is created properly, but when trying to send it to the selector, nothing is sent.
I'm not sure what could be wrong in the code, but I hope someone could help me with this. Thanks in advance.

you can display a chooser (all apps capable of performing the task are displayed for the user to select from). here is a code snippet to do that:
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
shareIntent.setType("image/*");
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(shareIntent, "Choose an app to share the image"));
For this to work, you need to pass the Uri of the bitmap. One way of achieving this is to save the bitmap in a temporary file and then use FileProvider.getUriForFile() to get the uri of the temp file.
good luck
clive

Related

Google+ share dialog show wrong image

I'm trying to share image and title on Google+ using this method:
share(com.google.android.apps.plus, img, title);
====================================
private void share(String type, int imgResId, String title) {
boolean found = false;
Intent share = new Intent(android.content.Intent.ACTION_SEND);
share.setType("image/jpeg");
// gets the list of intents that can be loaded.
List<ResolveInfo> resInfo = context.getPackageManager()
.queryIntentActivities(share, 0);
if (!resInfo.isEmpty()) {
for (ResolveInfo info : resInfo) {
if (info.activityInfo.packageName.toLowerCase(
Locale.ENGLISH).contains(type)
|| info.activityInfo.name.toLowerCase(
Locale.ENGLISH).contains(type)) {
Log.d("pack", info.toString());
share.putExtra(Intent.EXTRA_SUBJECT, "subject");
share.putExtra(Intent.EXTRA_TEXT, title);
share.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(Helper
.saveFile(context, imgResId))); // Optional,
// just if you
// wanna share
// an image.
share.setPackage(info.activityInfo.packageName);
found = true;
break;
}
}
if (!found)
return;
context.startActivity(Intent.createChooser(share, "Select"));
}
}
when Google+ share dialog comes up it shows wrong image(the image I try to share on Google+ the first time).I try to change the image resource id but still the same wrong image.
I ran into the same issue when trying to reuse a URI for different files, there appears to be an image cache somewhere that doesn't notice that the image changed.
I "fixed" it by generating a different URI for a new image (in your case, use a unique filename each time). A better solution would be to invalidate that cache, but I'm not aware of how (or if) that can be done.

Delete Image after using Share Intent

Hello I am new to android programming.
I have made an app in which images can be shared on various apps. Everything works fine but after the image is shared the images are saved in the phone. The images are saved in different folders on different devices.
I Want the images to be deleted after the images are shared.
Any help would be appreciated
Below is the onClick of the Share button.
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
ImageView Imgv = (ImageView)viewPager.findViewWithTag(viewPager.getCurrentItem());
Drawable mDrawable = Imgv.getDrawable();
Bitmap mBitmap = ((BitmapDrawable)mDrawable).getBitmap();
String path = Images.Media.insertImage(getContentResolver(),
mBitmap, "Image Description", null);
Uri uri = Uri.parse(path);
// Construct a ShareIntent with link to image
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
shareIntent.setType("image/*");
// Launch sharing dialog for image
startActivity(Intent.createChooser(shareIntent, "Share sticker via"));
}
});
This works for me,try this way to delete image
File fdlt = new File(file_path);
if (fdlt .exists()) {
if (fdlt .delete()) {
System.out.println("File Deleted :" + file_path);
} else {
System.out.println("File not Deleted :" + file_path);
}
}
Run a Asynctask which will wait for a Time and then it will delete the Image,
Execute this Asynctask when you will come to your app after sharing that Image.
For This use
startActivityForResult(Intent,int)
and Override
OnActivityResult
and Check if you are coming back from sharing the Image with Particular request code and then execute the asynctask.
It will delete image after a time or you also can delete image immediately on OnActivityResult.
Hope it Helps.

Sharing content

I have a gridview, clicking any image in the gridview expands it to a bigger image view, in this image view i can swipe left and right to change my images, i have added a method that would let me share the image to other apps like facebook watsapp etc. But the method seems to be not quite right, i cant figure out my mistake. It opens the popup window showing options to share the image but when i choose any option to send the image it says, Couldn't Load The Image.
Have a look at my code:
else {
if (e2.getY() - e1.getY() > SWIPE_MIN_DISTANCE
&& Math.abs(velocityY) > SWIPE_THRESHOLD_VELOCITY) {
URL url2 = new URL((thumb[j]));
Bitmap bimage = BitmapFactory.decodeStream(url2
.openConnection().getInputStream());
shareImage();
Toast.makeText(getApplicationContext(),
"Saving to Favorites", Toast.LENGTH_LONG)
.show();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
private void shareImage() {
Intent share = new Intent(Intent.ACTION_SEND);
// If you want to share a png image only, you can do:
// setType("image/png"); OR for jpeg: setType("image/jpeg");
share.setType("image/*");
// Make sure you put example png image named myImage.png in your
// directory
String bimage = Environment.getExternalStorageDirectory()
+ thumb[j];
File imageFileToShare = new File(bimage);
Uri uri = Uri.fromFile(imageFileToShare);
share.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(share, "Share Image!"));
}
}
Whereas thumb is the array having all the resource ids of the image, "j" is the int who's value initiated to 0.
Using the gesture to initiate the code.
I am ready to share my full code for greater understanding.
Any help would highly be appreciated.
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
Uri screenshotUri = Uri.parse(Images.Media.EXTERNAL_CONTENT_URI + "/" + imageIDs);
sharingIntent.setType("image/jpeg");
sharingIntent.putExtra(Intent.EXTRA_STREAM, screenshotUri);
startActivity(Intent.createChooser(sharingIntent, "Share image using"));

Intent filter for receiving intents

I have one question about android programming. I have an file explorer app and I want to implement various functions like open photos music etc. But in app itself, not sending intents to other apps! So, my question is, what intent filter I should use for "plugin" app for receiving "opening" intent ?
This is my code
public static void openFile(final Context context, final File target) {
final String mime = MimeTypes.getMimeType(target);
final Intent i = new Intent(Intent.ACTION_VIEW);
if (mime != null) {
i.setDataAndType(Uri.fromFile(target), mime);
} else {
i.setDataAndType(Uri.fromFile(target), "*/*");
}
if (context.getPackageManager().queryIntentActivities(i, 0).isEmpty()) {
Toast.makeText(context, R.string.cantopenfile, Toast.LENGTH_SHORT)
.show();
return;
}
try {
context.startActivity(i);
} catch (Exception e) {
Toast.makeText(context,
context.getString(R.string.cantopenfile) + e.getMessage(),
Toast.LENGTH_SHORT).show();
}
}
ok let's assume you want to open an image from your own explorer
create a new Activity let's say ImageActivity, then you simply implement an ImageViewer inside your activity and from the calling Activity simply send an intent with an Extra Bundle containing your image Bytes
EDIT
SENDING ACTIVITY
Intent intent = new Intent(MainActivity.this, ImageActivity.class);
ImageView imageView = findViewById(R.id.image).getDrawable();
imageView.buildDrawingCache();
Bitmap image = imageView.getDrawingCache();
Bundle extras = new Bundle();
extras.putParcelable("imagebitmap", image);
intent.putExtras(extras);
startActivity(intent);
Receiving Activity ImageActivity
Bundle extras = getIntent().getExtras();
Bitmap bmp = (Bitmap) extras.getParcelable("imagebitmap");
ImageView image = findViewById(R.id.image);
image.setImageBitmap(bmp );

Single intent to let user take picture OR pick image from gallery in Android

I'm developing an app for Android 2.1 upwards. I want to enable my users to select a profile picture within my app (I'm not using the contacts framework).
The ideal solution would be to fire an intent that enables the user to select an image from the gallery, but if an appropriate image is not available then use the camera to take a picture (or vice-versa i.e. allow user to take picture but if they know they already have a suitable image already, let them drop into the gallery and pick said image).
Currently I can do one or the other but not both.
If I go directly into camera mode using MediaStore.ACTION_IMAGE_CAPTURE then there is no option to drop into the gallery.
If I go directly to the gallery using Intent.ACTION_PICK then I can pick an image but if I click the camera button (in top right hand corner of gallery) then a new camera intent is fired. So, any picture that is taken is not returned directly to my application. (Sure you can press the back button to drop back into the gallery and select image from there but this is an extra unnecessary step and is not at all intuitive).
So is there a way to combine both or am I going to have to offer a menu to do one or the other from within my application? Seems like it would be a common use case...surely I'm missing something?
You can try doing something like this:
// ...
// Within your enclosing Class
// ...
private static final int SELECT_PICTURE = 1;
// ...
Intent pickIntent = new Intent();
pickIntent.setType("image/*");
pickIntent.setAction(Intent.ACTION_GET_CONTENT);
Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
String pickTitle = "Select or take a new Picture"; // Or get from strings.xml
Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle);
chooserIntent.putExtra
(
Intent.EXTRA_INITIAL_INTENTS,
new Intent[] { takePhotoIntent }
);
startActivityForResult(chooserIntent, SELECT_PICTURE);
To see how to handle the activitiy's result, please refer to this question
Note: a critical point is how to determine whether the camera or gallery was used. That is shown in this code example: https://stackoverflow.com/a/12347567/294884
UPDATE: The other answer, using EXTRA_INITIAL_INTENTS, is a better one at this point. At the time I wrote my answer, EXTRA_INITIAL_INTENTS did not yet exist, as it was added in API Level 5.
So is there a way to combine both or
am I going to have to offer a menu to
do one or the other from within my
application?
Write your own gallery that has the features you desire.
I would think a menu would be simpler.
Seems like it would be a common use
case...surely I'm missing something?
The developer next to you will think the gallery should allow you to pick from the local gallery or else hop out to Flickr to make a selection from there. Another developer will think the camera should not only allow to "take a picture" via the camera but to "take a picture" via choosing something from the gallery, inverting things from the way you envision it. Yet another developer will think that the gallery should allow picking from the local gallery, or Flickr, or the camera, or a network-attached webcam. Still another developer will think that the gallery is stupid and users should just pick files via a file explorer. And so on.
All of this in an environment (mobile phones) where flash for the OS is at a premium.
Hence, IMHO, it is not completely shocking that the core Android team elected to provide building blocks for you to assemble as you see fit, rather than trying to accommodate every possible pattern.
You can proceed in this way in your Activity:
private static final int REQUEST_CODE_PICTURE= 1;
/**
* Click on View to change photo. Sets into View of your layout, android:onClick="clickOnPhoto"
* #param view View
*/
public void clickOnPhoto(View view) {
Intent pickIntent = new Intent();
pickIntent.setType("image/*");
pickIntent.setAction(Intent.ACTION_GET_CONTENT);
Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
String pickTitle = "Take or select a photo";
Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle);
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { takePhotoIntent });
startActivityForResult(chooserIntent, REQUEST_CODE_PICTURE);
}
Then, add always in your Activity the method onActivityResult:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_PICTURE && resultCode == Activity.RESULT_OK) {
if (data == null) {
return;
}
try {
InputStream inputStream = getContentResolver().openInputStream(data.getData());
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
imgPhoto.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
My Answer is almost identical to #Macarse solution but I also add an additional intent to show gallery apps (Ex: Google Photos) and is written in Kotlin:
val REQUEST_CODE_GET_IMAGE = 101
private fun addProfileImage() {
val pickImageFileIntent = Intent()
pickImageFileIntent.type = "image/*"
pickImageFileIntent.action = Intent.ACTION_GET_CONTENT
val pickGalleryImageIntent = Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
val captureCameraImageIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
val pickTitle = "Capture from camera or Select from gallery the Profile photo"
val chooserIntent = Intent.createChooser(pickImageFileIntent, pickTitle)
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, arrayOf(captureCameraImageIntent, pickGalleryImageIntent))
startActivityForResult(chooserIntent, REQUEST_CODE_GET_IMAGE)
}
Extract image from result intent:
private var imageTempFile: File? = null
private var imageMimeType: String? = null
private fun extractImage(intent: Intent?) {
val imageUri = intent?.data
imageUri?.let {
Glide.with(this)
.load(imageUri)
.into(profileImageCiv)
imageTempFile = MediaUtils.copyContentFromUriToCacheFile(this, imageUri, Settings.DIRECTORY_CACHE_TEMP_PROFILE_IMAGE)
imageMimeType = MediaUtils.getMimeType(this, imageUri)
} ?: run {
intent?.extras?.get("data")?.let { bitmap -> // Bitmap was returned as raw bitmap
Glide.with(this)
.load(bitmap)
.into(profileImageCiv)
imageTempFile = MediaUtils.writeBitmapToCacheFile(this, bitmap as Bitmap, Settings.DIRECTORY_CACHE_TEMP_PROFILE_IMAGE)
imageMimeType = "image/jpeg" // The bitmap was compressed as JPEG format. The bitmap itself doesn't have any format associated to it
} ?: run {
imageTempFile = null
imageMimeType = null
Log.e("Intent data is null.")
Log.d("Error during photo selection")
}
}
}

Categories

Resources