I had a code in pre-Marshmallow application that selected only some of the installed applications that implement the Intent.ACTION_SEND and the show a Intent.createChooser with only those. This is the full code:
Intent actionSendIntent = new Intent();
actionSendIntent.setAction(Intent.ACTION_SEND);
actionSendIntent.setType("text/plain");
List<ResolveInfo> resInfos = getPackageManager().queryIntentActivities(actionSendIntent, 0);
List<Intent> shareIntents = new ArrayList<Intent>();
if(!resInfos.isEmpty()){
for(ResolveInfo res : resInfos){
final String packageName = res.activityInfo.packageName;
if (packageName.contains("com.twitter.android") ||
packageName.contains("com.facebook.katana") ||
packageName.contains("com.facebook.lite") ||
packageName.contains("com.whatsapp")) {
final Intent intent = new Intent();
intent.setComponent(new ComponentName(packageName, res.activityInfo.name));
intent.setAction(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, "text");
intent.putExtra(Intent.EXTRA_SUBJECT, "subject");
intent.setPackage(packageName);
shareIntents.add(intent);
}
}
}
Intent chooserIntent = Intent.createChooser(shareIntents.remove(0), shareText);
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, shareIntents.toArray(new Parcelable[]{}));
startActivity(Intent.createChooser(chooserIntent, shareText));
This code does not work in Marshmallow and show Android System as the only available option... does anyone know why?
Related
I've successfully created an intent chooser which lists Gallery, Documents and Camera. But when I try to select Camera from the chooser, nothing happens on clicking it.
I tried creating a chooser with just Camera Intent, even then the result was the same.
This exact code was working before the Marshmallow update. I suspect it has something to do with it. Have you come across a similar problem? And How did you solve it?
Following is my code to create an intent chooser.
public Intent getPickImageChooserIntent() {
// Determine Uri of camera image to save.
fileUri = getCaptureImageOutputUri();
List<Intent> allIntents = new ArrayList<>();
PackageManager packageManager = getPackageManager();
// collect all camera intents
Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
for (ResolveInfo res : listCam) {
Intent intent = new Intent(captureIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(res.activityInfo.packageName);
if (fileUri != null) {
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
}
allIntents.add(intent);
}
// collect all gallery intents
Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT);
galleryIntent.setType("image/*");
List<ResolveInfo> listGallery = packageManager.queryIntentActivities(galleryIntent, 0);
for (ResolveInfo res : listGallery) {
Intent intent = new Intent(galleryIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(res.activityInfo.packageName);
allIntents.add(intent);
}
// the main intent is the last in the list (fucking android) so pickup the useless one
Intent mainIntent = allIntents.get(allIntents.size() - 1);
for (Intent intent : allIntents) {
if (intent.getComponent().getClassName().equals("com.android.documentsui.DocumentsActivity")) {
mainIntent = intent;
break;
}
}
allIntents.remove(mainIntent);
// Create a chooser from the main intent
Intent chooserIntent = Intent.createChooser(mainIntent, "Select source");
// Add all other intents
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, allIntents.toArray(new Parcelable[allIntents.size()]));
return chooserIntent;
}
As #Tynn pointed out, The problem is because of the new Permission Model. I had to setup runtime checks for the permission status for each of the permissions.
I need to share an image via only Tweet.
Here is my code
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/*");
if (mInsertableToGallery) {
mInsertableToGallery = false;
mInsertedImagePath = MediaStore.Images.Media.insertImage(getContentResolver(), mShareImage,
getResources().getString(R.string.app_name) + System.currentTimeMillis(), getResources().getString(R.string.app_name));
}
// share only 5 specific apps:
List<Intent> targetedShareIntents = new ArrayList<>();
List<ResolveInfo> resInfos = getPackageManager().queryIntentActivities(shareIntent, 0);
if (!resInfos.isEmpty()) {
for (ResolveInfo resolveInfo : resInfos) {
String packageName = resolveInfo.activityInfo.packageName;
Intent targetedShareIntent = new Intent(Intent.ACTION_SEND);
targetedShareIntent.setType("image/*");
targetedShareIntent.setPackage(packageName);
targetedShareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(mInsertedImagePath));
if (TextUtils.equals(packageName, "com.facebook.katana") //fb
||TextUtils.equals(packageName, "com.instagram.android") //instagram
||TextUtils.equals(packageName, "jp.naver.line.android") //line
||TextUtils.equals(packageName, "com.google.android.apps.plus") // plus
||TextUtils.equals(packageName, "com.twitter.android")) // twitter
{
targetedShareIntents.add(targetedShareIntent);
}
}
}
Intent chooser = Intent.createChooser(targetedShareIntents.remove(0), "");
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[]{}));
startActivity(chooser);
and I get the result:
When click "Android System", Twitter share popup:
What I want:
How to share via Twitter only by Tweet or Direct Message ?
How to change title & icon of share item. Ex Twitter share item from "Android System" to "Tweet"?
I couldn't manage to get both Tweet and Direct Message to the front but the following code will get you either one there. Actually you can get both to the front but both appears with same name "Tweet" so its kind of unusable.
I have also included facebook, insta and tumblr.
To get Direct Message in place of tweet replace com.twitter.android.composer.ComposerActivity with com.twitter.android.DMActivity. To get both add another ' if ' for DMActivity.
Can't say surely but I don't think you can change the Icon of the package for your app.
List<Intent> targetedShareIntents = new ArrayList<Intent>();
Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
shareIntent.setType("image/jpeg");//("text/plain");
Uri uri = Uri.fromFile(outFile);
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(shareIntent, 0);
for (ResolveInfo resolveInfo : resInfo) {
String packageName = resolveInfo.activityInfo.packageName;
Intent targetedShareIntent = new Intent(android.content.Intent.ACTION_SEND);
targetedShareIntent.setType("image/jpeg");
targetedShareIntent.putExtra(Intent.EXTRA_STREAM, uri);
if(TextUtils.equals(packageName,"com.facebook.katana")|TextUtils.equals(packageName,"com.instagram.android")
|TextUtils.equals(packageName,"com.tumblr")) {
targetedShareIntent.setPackage(packageName);
targetedShareIntents.add(targetedShareIntent);
}
if(TextUtils.equals(resolveInfo.activityInfo.name,"com.twitter.android.composer.ComposerActivity")) {
targetedShareIntent.setPackage(packageName);
targetedShareIntent.setClassName(
resolveInfo.activityInfo.packageName,
resolveInfo.activityInfo.name);
targetedShareIntents.add(targetedShareIntent);
}
}
Intent chooserIntent = Intent.createChooser(targetedShareIntents.remove(0), "Select app to share");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[]{}));
startActivity(chooserIntent);
For composing new Tweet:
public static Intent getTwitterShareIntent(Context context) {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
shareIntent.setClassName("com.twitter.android",
"com.twitter.composer.ComposerShareActivity");
return shareIntent;
}
I want to share dynamic text fields for Facebook, Twitter, email and SMS apps. For email, I want to include hyperlinks, so I'd need to use "text/html" instead of "text/plain". Is this impossible? The following code does not work:
List<Intent> targetedShareIntents = new ArrayList<Intent>();
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
PackageManager pm = getActivity().getPackageManager();
List<ResolveInfo> activityList = pm.queryIntentActivities(sharingIntent, 0);
for(final ResolveInfo app : activityList) {
String packageName = app.activityInfo.packageName;
Intent targetedShareIntent = new Intent(Intent.ACTION_SEND);
targetedShareIntent.setType("text/plain");
targetedShareIntent.putExtra(Intent.EXTRA_TEXT, getTextToShare(data));
targetedShareIntent.setPackage(packageName);
targetedShareIntents.add(targetedShareIntent);
}
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setType("text/html");
List<ResolveInfo> emailList = pm.queryIntentActivities(emailIntent, 0);
for(final ResolveInfo app : emailList) {
String packageName = app.activityInfo.packageName;
Intent targetedShareIntent = new Intent(Intent.ACTION_SEND);
targetedShareIntent.setType("text/html");
if (packageName.contains("android.email") || packageName.contains("android.gm")) {
targetedShareIntent.putExtra(Intent.EXTRA_SUBJECT, data.getHeadline());
targetedShareIntent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(getTextToShare(data, "Email")));
}
targetedShareIntent.setPackage(packageName);
targetedShareIntents.add(targetedShareIntent);
}
Intent chooserIntent = Intent.createChooser(targetedShareIntents.remove(targetedShareIntents.size() - 1), "Share this story");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[]{}));
startActivity(chooserIntent);
EDIT: This does work for Facebook, email -- however, for some reason Twitter does NOT show up. Does anyone know why?
I want to create an image share intent with the same options that appear in the Google's Androidify app:
I tested with Intent.ACTION_SEND and with Intent.ACTION_ATTACH_DATA, and have obtained the same results but separately, and I want them to appear together, for this I tried using Intent.EXTRA_INITIAL_INTENTS:
Intent sendIntent = new Intent(Intent.ACTION_SEND);
Intent attachIntent = new Intent(Intent.ACTION_ATTACH_DATA);
sendIntent.setDataAndType(getTempImageUri(), "image/jpg");
attachIntent.setDataAndType(getTempImageUri(), "image/jpg");
Intent chooserIntent = Intent.createChooser(
attachIntent, getString(R.string.share) + ":");
chooserIntent.putExtra(
Intent.EXTRA_INITIAL_INTENTS, new Intent[] { sendIntent });
startActivity(chooserIntent);
But the second Intent results appears as Android System:
Obviously, the method used by the Androidify app is a mix of Intent.ACTION_SEND and Intent.ACTION_ATTACH_DATA. Anyone know how to do it?
Thanks for the help!
Finally I found how to do it, thanks to this answer:
https://stackoverflow.com/a/11038348/710274
This is my final code, I'm sure someone will find it useful:
PackageManager pm = getPackageManager();
Intent sendIntent = new Intent(Intent.ACTION_SEND);
Intent attachIntent = new Intent(Intent.ACTION_ATTACH_DATA);
sendIntent.setDataAndType(getTempImageUri(), "image/jpeg");
attachIntent.setDataAndType(getTempImageUri(), "image/jpeg");
Intent openInChooser = Intent.createChooser(sendIntent, "Share with:");
List<ResolveInfo> resInfo = pm.queryIntentActivities(attachIntent, 0);
Intent[] extraIntents = new Intent[resInfo.size()];
for (int i = 0; i < resInfo.size(); i++) {
ResolveInfo ri = resInfo.get(i);
String packageName = ri.activityInfo.packageName;
Intent intent = new Intent();
intent.setComponent(new ComponentName(packageName, ri.activityInfo.name));
intent.setAction(Intent.ACTION_ATTACH_DATA);
intent.setDataAndType(getTempImageUri(), "image/jpeg");
extraIntents[i] = new Intent(intent);
}
openInChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents);
startActivity(openInChooser);
String message = "Text I want to share";
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("text/plain");
share.putExtra(Intent.EXTRA_TEXT, message);
startActivity(Intent.createChooser(share,"Share on"));
right now it shows the default options like: Bluetooth, Email, Facebook, Gmail, LinkedIn, Messaging, Share Via Barcode.
or are these the installed apps?
what i want is to know, how i can remove few from this list. like i want to remove Share Via Barcode.
and add something else?
Thank You
Use below code to add a new Item to the Chooser Screen.
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("text/plain");
share.putExtra(Intent.EXTRA_TEXT, message);
Intent addIntent = ;//whatever you want
Intent chooser = new Intent(Intent.ACTION_CHOOSER);
chooser.putExtra(Intent.EXTRA_INTENT, share );
chooser.putExtra(Intent.EXTRA_TITLE, "title");
Intent[] intentArray = {addIntent };
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivity(chooser);
But removing specific items is not possible. So you could resolve the intent using Packagemanager.resolveActivity and create your own custom list view
I used the following code to get a list of all eMail and SMS apps installed on the device:
Intent shareSMS = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("smsto", "12346556", null));
shareSMS.addCategory(Intent.CATEGORY_DEFAULT);
shareSMS.putExtra("sms_body", message);
Intent shareEmail = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto", "", null));
PackageManager pm = getPackageManager();
List<ResolveInfo> mailActivityList = pm.queryIntentActivities(shareEmail, PackageManager.MATCH_DEFAULT_ONLY);
List<Intent> mailIntents = new ArrayList<Intent>();
for (ResolveInfo resInfo : mailActivityList) {
Intent targetedOpenIntent = new Intent(android.content.Intent.ACTION_SENDTO, Uri.fromParts("mailto", "", null))
.setPackage(resInfo.activityInfo.packageName)
.putExtra(Intent.EXTRA_EMAIL, emails)
.putExtra(Intent.EXTRA_SUBJECT, subject)
.putExtra(Intent.EXTRA_TEXT, message);
mailIntents.add(targetedOpenIntent);
}
Intent chooser = new Intent(Intent.ACTION_CHOOSER);
chooser.putExtra(Intent.EXTRA_INTENT, shareSMS);
chooser.putExtra(Intent.EXTRA_TITLE, "Send request");
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, mailIntents.toArray(new Parcelable[] { }));
startActivity(chooser);
Adding Option to chooser
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("text/plain");
share.putExtra(Intent.EXTRA_TEXT, message);
Intent extraOptionToAdd = new Intent(this, ExtraOptionActivity.class);
extraOptionToAdd.putExtra(Intent.EXTRA_TEXT, "Text");
LabeledIntent labeledExtraOption = new LabeledIntent(extraOptionToAdd, getPackageName(), "Extra Option!", 0);
Intent chooser = Intent.createChooser(share, "Share Now!");
Intent[] intentArray = {labeledExtraOption};
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivity(chooser);