I want to get emails from users. I am trying to filter the chooser intent but i am stuck at some point.
Chooser intent brings the user's contacts. I just want to show the installed email apps, with 'to' field auto filled of course.
How can I remove user's contacts and show email apps only?
any help would be greatly appreciated.
here is my code so far:
List<Intent> emailAppLauncherIntents = new ArrayList<>();
Intent emailAppIntent = new Intent(Intent.ACTION_SENDTO);
emailAppIntent.setData(Uri.parse("mailto:test#mail.com"));
emailAppIntent.putExtra(Intent.EXTRA_EMAIL, "");
emailAppIntent.putExtra(Intent.EXTRA_SUBJECT, "Feedback on "+getContext().getPackageName());
emailAppIntent.putExtra(Intent.EXTRA_TEXT, mailBody);
PackageManager packageManager = getActivity().getPackageManager();
List<ResolveInfo> emailApps = packageManager.queryIntentActivities(emailAppIntent, PackageManager.MATCH_ALL);
for (ResolveInfo resolveInfo : emailApps) {
String packageName = resolveInfo.activityInfo.packageName;
Intent launchIntent = packageManager.getLaunchIntentForPackage(packageName);
emailAppLauncherIntents.add(launchIntent);
}
Intent chooserIntent = Intent.createChooser(new Intent(), "Select email app:");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, emailAppLauncherIntents.toArray(new Parcelable[emailAppLauncherIntents.size()]));
startActivity(chooserIntent);
Changing the MIME type is the answer
Use
intent.setType("message/rfc822");
this is how i made it.
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri data = Uri.parse("mailto:"
+ "xyz#abc.com"
+ "?subject=" + "Feedback" + "&body=" + "");
intent.putExtra(Intent.EXTRA_SUBJECT, "Feedback";
intent.putExtra(Intent.EXTRA_EMAIL, new String[] { "xyz#abc.com" });
intent.putExtra(Intent.EXTRA_TEXT, mailBody);
intent.setData(data);
startActivity(intent);
Related
There are two requirements:
Email with attachment
In the Intent chooser, there should be only Email apps.
What I have known/done:
Intent.ACTION_SENDTO with intent.setData(Uri.parse("mailto:")) can make sure that there are only Email apps in Intent chooser but it will not bring attachment(For some apps like Gmail it will, but there are also many apps that will ignore attachment).
Intent.ACTION_SEND can send Email with attachment. However, in Intent chooser, there will be apps that are actually not Email apps but can response to Intent.ACTION_SEND. Using intent.setType("message/rfc822") can reduce number of those apps but not all.
References this answer: https://stackoverflow.com/a/8550043/3952691 and nearly succeed in my goals. My code is as below:
private static void sendFeedbackWithAttachment(Context context, String subject) {
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:"));
PackageManager packageManager = context.getPackageManager();
List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(intent, 0);
if (resolveInfos.isEmpty()) {
Toast.makeText(context, context.getString(R.string.error_activity_not_found),
Toast.LENGTH_SHORT).show();
} else {
// ACTION_SEND may be replied by some apps that are not email apps. However,
// ACTION_SENDTO doesn't allow us to choose attachment. As a result, we use
// an ACTION_SENDTO intent with email data to filter email apps and then send
// email with attachment by ACTION_SEND.
List<LabeledIntent> intents = new ArrayList<>();
Uri uri = getLatestLogUri();
for (ResolveInfo info : resolveInfos) {
Intent i = new Intent(Intent.ACTION_SEND);
i.setPackage(info.activityInfo.packageName);
i.setClassName(info.activityInfo.packageName, info.activityInfo.name);
i.putExtra(Intent.EXTRA_EMAIL, new String[] { Def.Meta.FEEDBACK_EMAIL });
i.putExtra(Intent.EXTRA_SUBJECT, subject);
i.putExtra(Intent.EXTRA_STREAM, uri);
intents.add(new LabeledIntent(i, info.activityInfo.packageName,
info.loadLabel(context.getPackageManager()), info.icon));
}
Intent chooser = Intent.createChooser(intents.remove(0),
context.getString(R.string.send_feedback_to_developer));
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS,
intents.toArray(new LabeledIntent[intents.size()]));
context.startActivity(chooser);
}
}
However, on some devices(For example, Xiaomi 2S with MIUI V5, I don't know if this can be influenced by a third-party rom), the result is an empty Intent chooser. And it seems that above Android 6.0, Intent.EXTRA_INITIAL_INTENTS has some bugs(Custom intent-chooser - why on Android 6 does it show empty cells?, and another one: https://code.google.com/p/android/issues/detail?id=202693).
As a result, I don't know how to achieve my goals. Please help me, thank you in advance.
Try the below code to Send a mail
String filename="filename.vcf";
File filelocation = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), filename);
Uri path = Uri.fromFile(filelocation);
Intent emailIntent = new Intent(Intent.ACTION_SEND);
// set the type to 'email'
emailIntent .setType("vnd.android.cursor.dir/email");
String to[] = {"asd#gmail.com"};
emailIntent .putExtra(Intent.EXTRA_EMAIL, to);
// the attachment
emailIntent .putExtra(Intent.EXTRA_STREAM, path);
// the mail subject
emailIntent .putExtra(Intent.EXTRA_SUBJECT, "Subject");
startActivity(Intent.createChooser(emailIntent , "Send email..."));
There are two ways to do this
OPTION 1
Intent emailIntent = new Intent(
android.content.Intent.ACTION_VIEW);
//Option 1
Uri data = Uri.parse("mailto:?subject=" + "blah blah subject"
+ "&body=" + "blah blah body" + "&to=" + "sendme#me.com");
emailIntent.setData(data);
startActivity(Intent.createChooser(emailIntent, ""));
Result
OPTION 2
It works perfactly except it wont filter out FTP
//Option 2
emailIntent = new Intent(
android.content.Intent.ACTION_SEND);
emailIntent.setType("message/rfc822");
final String[] toRecipients = new String[] { "sendme#me.com", "", };
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, toRecipients);
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "blah blah subject");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT,
Html.fromHtml("blah blah body"));
startActivity(Intent.createChooser(emailIntent, ""));
Result
Both ways have minor flaws I show you both ways it is now upto you to pick one.
I am trying to share some data from my app. I have to send different text in case of Email and different text in case user chooses other app.
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setType("ye");
PackageManager pm = getPackageManager();
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setType("text/plain");
Intent openInChooser = Intent.createChooser(emailIntent, "Share via");
List<ResolveInfo> resInfo = pm.queryIntentActivities(sendIntent, 0);
List<LabeledIntent> intentList = new ArrayList<>();
for(int i=0;i<resInfo.size();i++)
{
ResolveInfo ri = resInfo.get(i);
String packageName = ri.activityInfo.packageName;
Log.d("package", i + " " + packageName);
if(packageName.contains("android.email")){
emailIntent.setPackage(packageName);
emailIntent.putExtra(Intent.EXTRA_TEXT, "This is email");
}
else
{
Intent intent = new Intent();
intent.setComponent(new ComponentName(packageName,ri.activityInfo.packageName));
intent.setAction(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, "Sharing via other app");
intent.setPackage(packageName);
intentList.add(new LabeledIntent(intent, packageName, ri.loadLabel(pm), ri.icon));
}
}
LabeledIntent [] extraIntents = new LabeledIntent[intentList.size()];
extraIntents = intentList.toArray(extraIntents);
openInChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents);
startActivity(openInChooser);
I have given a random string in my original intent in setType so that it displays only the chosen apps.However when I click on share an empty window comes up.
I have checked with debugger and my extraIntents contains 24 intents. Its after startActivity that nothing comes up in my choosing options.
Update (Sept 9, 2020):
It seems the intents passed with EXTRA_INITIAL_INTENTS does not work the same on Android OS 10 and above. On the share sheet, it shows a new section with text, "Direct share not available", and share sheet does not show apps like WhatsApp that supports direct share.
Original Answer
In your case, emailIntent returns 0 apps because of random Type you have set. In
Intent openInChooser = Intent.createChooser(emailIntent, "Share via");
if the intent you pass returns 0 apps then it ignores EXTRA_INITIAL_INTENTS flag.
Possible solution,
......
extraIntents = intentList.toArray(extraIntents);
Intent firstIntent = extraIntents.remove(0); // assuming you will have at least one Intent
Intent openInChooser = Intent.createChooser(firstIntent, "Share via");
openInChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents);
startActivity(openInChooser);
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?
Intent.ACTION_SENDTO in shows two options but my clent is asking to remove the gmail option and i don't see a way out please help me
Intent emailIntent =
new Intent(Intent.ACTION_SENDTO,
Uri.fromParts( "mailto",userInput.getText().toString(), null));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Press Release");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Please view this press release");
startActivity(Intent.createChooser(emailIntent,"Send mail using..."));
Use
emailIntent.setPackage(PackageName of Email app); before calling startActivity.
You need to set email client package name but, in Samsung devices com.sec.android.email is the default In-Built Mail client, but in HTC it is com.htc.android.mail and so on. So first you need to filter that application and then set to intent. I am adding the solution
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(
"mailto", userInput.getText().toString(), null));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Press Release");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT,
"Please view this press release");
// Identify the package name of email client and set to intent
List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(emailIntent, 0);
if (!resInfo.isEmpty()) {
for (ResolveInfo info : resInfo) {
if (info.activityInfo.packageName.toLowerCase().contains(".android.email")
|| info.activityInfo.name.toLowerCase().contains(".android.email")) {
emailIntent.setPackage(info.activityInfo.packageName);
// And now call
startActivity(Intent.createChooser(emailIntent, "Send mail using..."));
}
}
}
You should read Android: How to get the native Email clients package name
IF YOU WANT TO REMOVE GMAIL CLIENT FROM LIST create a custom cooser
List<Intent> intents = new ArrayList<Intent>();
Intent sendIntent = new Intent(android.content.Intent.ACTION_SEND);
sendIntent.setType("text/plain");
List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(sendIntent, 0);
if (!resInfo.isEmpty()){
for (ResolveInfo resolveInfo : resInfo) {
String packageName = resolveInfo.activityInfo.packageName;
Intent neededShareIntent = new Intent(android.content.Intent.ACTION_SEND);
neededShareIntent.setType("text/plain");
neededShareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Subject");
neededShareIntent.setPackage(packageName);
if (!StringUtils.equals(packageName, "com.google.android.gm")){
intents.add(neededShareIntent);
}
}
Intent chooserIntent = Intent.createChooser(intents.remove(0), "Select app to share");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intents.toArray(new Parcelable[]{}));
startActivity(chooserIntent);
}
Pls test this code and check