Android Intent.ACTION_SEND, how to pre-fill phone number in message - android

Using Intent.ACTION_SEND to share plain text or image. Everything works fine, the third party apps bottom sheet opens and I choose the sms application but I am not able to pass in the contact number in the intent. If I use share.putExtra("address", "9839098390") the message body becomes blank, and without using this flag everything works fine except the number recipient field is empty.
I have tried share.putExtra("address", "smsto:9839098390") and share.putExtra("mmsto:address", "9839098390") in both these cases the recipient field is filled with "9839060055" but the message body becomes empty.
Here's the code
Intent share = new Intent(Intent.ACTION_SEND);
share.putExtra(Intent.EXTRA_TEXT, message);
share.setType("text/plain");
if (contentUri != null && MIME_TYPE != null) {
share.putExtra(Intent.EXTRA_STREAM, contentUri);
share.setType(MIME_TYPE);
}
if(phoneContact != null && !TextUtils.isEmpty(phoneContact.getId()))
share.putExtra("address", phoneContact.getId());
share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
mContext.startActivity(Intent.createChooser(share, title));

Related

Sending data with multiple attachments with email intent

I have a FeedbackActivity.java activity which takes feedback from user with multiple attachments (upto 3 images as attachments).
I am using following code:
Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
intent.setType("message/rfc822");
intent.putExtra(Intent.EXTRA_EMAIL, emails); //emails is an Array of 'String' type
intent.putExtra(Intent.EXTRA_SUBJECT, subject); //subject is a String
intent.putExtra(Intent.EXTRA_TEXT, text) //text is a String
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris); //uris is an ArrayList of 'Uri' type
//uris stores all Uri of images selected
if(intent.resolveActivity(getPackageManager()) != null){
startActivity(intent);
}
else {
Toast.makeText(this, "Not Good", Toast.LENGTH_SHORT).show();
}
Now this code works fine but the problem is that it shows all sorts of apps which support "message/rfc822" MIME type.
Image is shown below :
I only need to show the email client apps, I tried Uri.parse("mailto:"), but didn't workout and code always moves to else statement and shows the toast "not good".
I read the google documentation but it only shows simple cases.
I tried searching on the web. Many developers are using intent.setType("*/*") or intent.setType("text/plain"). But they all too show apps other than email clients.
Please guide me.
And I wanted to ask in general,
Google documentations show simple examples which is good in a way, but how to learn really in depth on these kind of topics?
Thank you.
So here, we will be using two intents: selectorIntent and emailIntent. selectorIntent is what the emailIntent will use as to show available apps. code:
Intent selectorIntent = new Intent(Intent.ACTION_SENDTO);
selectorIntent.setData(Uri.parse("mailto:"));
final Intent emailIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
emailIntent.putExtra(Intent.EXTRA_EMAIL, emails);
emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
emailIntent.setSelector(selectorIntent);
if(emailIntent.resolveActivity(getPackageManager()) != null){
startActivity(emailIntent);
}
else {
Snackbar.make(scrollView, "Sorry, We couldn't find any email client apps!", Snackbar.LENGTH_SHORT).show();
}
Now it will choose only apps which are email client.
If there is only one email-client app in your phone than it will directly open that. And if no such application is there, than the code will show Snackbar given in the else part.
Don't use Uri.parse, use Uri.fromParts
Do it like this:
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto","example#mail.com", null));

How to filter the apps that show up when sharing intent Android?

I know this has been asked before and I reference one of the answers but I can't get my code to work the way it should. I have a simple note-taking app, which allows the user to share notes through external applications. The code is supposed to filter the apps so the user can only share to facebook, twitter, mms, gmail, and email (so I thought). I took it from the top answer here How to filter specific apps for ACTION_SEND intent (and set a different text for each app). When I click on the button that launches the method to share intents, I do get mms, gmail, facebook twitter, and email, but I also get google drive, android beam, evernote, twitter direct message, facebook messenger and snapchat.
The only apps that the information gets sent correctly to are mms, email and gmail. Facebook doesn't work, there's some comments below on why, and twitter I'm not sure of because I don't have an account to test it out. I don't have the code to check if the packageName contains "drive" or "googledrive", but I can still share to drive and the data from my note gets passed along. I want to be able to send the note text and the note title however (2 editText fields in my app), but I don't know how to since I don't know what the package name is.
For the apps that don't work or I want to remove from the list of choices, how can I get rid of them? Here is the code:
public void sendNote(View view) {
Resources resources = getResources();
Intent emailIntent = new Intent();
emailIntent.setAction(Intent.ACTION_SEND);
// Native email client doesn't currently support HTML, but it doesn't hurt to try in case they fix it
emailIntent.putExtra(Intent.EXTRA_TEXT, titleEditor.getText().toString());
emailIntent.putExtra(Intent.EXTRA_SUBJECT, noteEditor.getText().toString());
emailIntent.setType("message/rfc822");
PackageManager pm = getPackageManager();
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setType("text/plain");
Intent openInChooser = Intent.createChooser(emailIntent, titleEditor.getText().toString() + ": " + noteEditor.getText().toString());
List<ResolveInfo> resInfo = pm.queryIntentActivities(sendIntent, 0);
List<LabeledIntent> intentList = new ArrayList<LabeledIntent>();
for (int i = 0; i < resInfo.size(); i++) {
// Extract the label, append it, and repackage it in a LabeledIntent
ResolveInfo ri = resInfo.get(i);
String packageName = ri.activityInfo.packageName;
if(packageName.contains("android.email")) {
emailIntent.setPackage(packageName);
} else if(packageName.contains("twitter") || packageName.contains("facebook") || packageName.contains("mms") || packageName.contains("android.gm")) {
Intent intent = new Intent();
intent.setComponent(new ComponentName(packageName, ri.activityInfo.name));
intent.setAction(Intent.ACTION_SEND);
intent.setType("text/plain");
if(packageName.contains("twitter")) {
intent.putExtra(Intent.EXTRA_TEXT, titleEditor.getText().toString() + ": " + noteEditor.getText().toString());
} else if(packageName.contains("facebook")) {
// Warning: Facebook IGNORES our text. They say "These fields are intended for users to express themselves. Pre-filling these fields erodes the authenticity of the user voice."
// One workaround is to use the Facebook SDK to post, but that doesn't allow the user to choose how they want to share. We can also make a custom landing page, and the link
// will show the <meta content ="..."> text from that page with our link in Facebook.
intent.putExtra(Intent.EXTRA_TEXT, titleEditor.getText().toString() + ": " + noteEditor.getText().toString());
} else if(packageName.contains("mms")) {
intent.putExtra(Intent.EXTRA_TEXT, titleEditor.getText().toString() + ": " + noteEditor.getText().toString());
} else if(packageName.contains("android.gm")) { // If Gmail shows up twice, try removing this else-if clause and the reference to "android.gm" above
intent.putExtra(Intent.EXTRA_TEXT, noteEditor.getText().toString());
intent.putExtra(Intent.EXTRA_SUBJECT, titleEditor.getText().toString());
intent.setType("message/rfc822");
}
//else if (packageName.contains("drive")) {
//intent.putExtra(Intent.EXTRA_TEXT, titleEditor.getText().toString() + ": " + noteEditor.getText().toString());
//}
else {
}
intentList.add(new LabeledIntent(intent, packageName, ri.loadLabel(pm), ri.icon));
}
}
// convert intentList to array
LabeledIntent[] extraIntents = intentList.toArray( new LabeledIntent[ intentList.size() ]);
openInChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents);
startActivity(openInChooser);
}
I have an else if near the bottom that is commented out. That was my attempt in finding the google drive packageName and sending the intent so the user can still use that application, it didn't work. Like I said earlier, drive gets information sent to it, but it's just the note text, not the title and text like I want it to be.
So I have 2 questions.
How can I filter out all of the apps that I don't want the user to be able to send information to so they don't even show up as an option, lets take twitter for example.
If the above is not possible, how can I find the package names for these different apps? For Google Drive, I tried using the commented out else if statement to send an intent to the app there but it never executed. I've searched everywhere to get intents for google drive but I can't get the package name to get my code working.
Thanks in advance

Whatsapp like invite via sms implementation, just sms, not via intent chooser

Unable to launch default sms activity in my application stack. Issue seen in nexus 6 lollipop and android one marshmallow.
I have tried to send intent of ACTION_VIEW, and set the smsto: and sms body.
I am able to launch sms application.
I have the following behaviour of my app.
I have list of contact numbers in my app
When user says invite, i want to launch default sms app, fill in to and sms body and default sms app should be in my activity task.
On pressing back, I want to close messaging app.
Please see the reference images below
1. My app invite
2. on invite, launch sms
send sms, press back, check recent app list
What I am able to achieve.
I am able to achieve above mentioned in kitkat. (default sms app finishes)
but, not in lollipop and marshmallow. Default sms app goes to background.
Launch default sms app and fill in data.
On pressing back, messaging app goes to background.
Now I will be able to launch sms app from recent app list, which again fills recipient with same number and body, which is not intended.
The problem is, app is launched in new activity task. I am unable to get that messaging app in my activity task. If I press back on that messaging app, I am able to come back to my app. But if I choose the messaging app from recent list, it shows the sms recipient and body filled activity every time.
Please find the code snippet below
private void sendTextMessage(String to)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) // At least KitKat
{
String defaultSmsPackageName = Telephony.Sms.getDefaultSmsPackage(mActivity); // Need to change the build to API 19
Logger.log_error(TAG + "sendTextMessage() above KITKAT");
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setType("text/plain");
sendIntent.putExtra("address", to);
sendIntent.putExtra("sms_body", "sms body");
sendIntent.putExtra(Intent.EXTRA_TEXT, "sms body");
if (defaultSmsPackageName != null)// Can be null in case that there is no default, then the user would be able to choose
// any app that support this intent.
{
sendIntent.setPackage(defaultSmsPackageName);
Logger.log_error(TAG + "sendTextMessage() defaultSmsPackageName = " + defaultSmsPackageName);
}
getContext().startActivity(sendIntent);
}
else // For early versions, do what worked for you before.
{
Intent smsIntent = new Intent(android.content.Intent.ACTION_VIEW);
Logger.log_error(TAG + "sendTextMessage() below KITKAT");
smsIntent.setType("vnd.android-dir/mms-sms");
smsIntent.putExtra("address", to);
smsIntent.putExtra("sms_body", getString(R.string.str_share_app_short_text));
startActivity(smsIntent);
}
}
This way of launching is messing with messaging app.
I have tried launching intent with no history, single instance, exclude from recents.
For reference I am attaching the whatsapp screenshots, which I am trying to have in my activity.
I am not able to post more than 2 links in stack overflow, so keeping recent app list only.
Launch whatsapp, go to contacts, scroll down, look for invite in green
and invite.
It will launch sms app.
Check recents.
check in recent list
I think, i found answer. May not be ideal but works.
private void shareEx() {
List<Intent> targetShareIntents=new ArrayList<Intent>();
PackageManager packageManager = getContext().getPackageManager();
Intent shareIntent=new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
List<ResolveInfo> resInfos= getContext().getPackageManager().queryIntentActivities(shareIntent, 0);
if(!resInfos.isEmpty()){
Logger.log_error( TAG + "sharenew Have package");
for(ResolveInfo resInfo : resInfos){
String packageName = resInfo.activityInfo.packageName;
Intent intent = new Intent();
intent.setComponent(new ComponentName(packageName, resInfo.activityInfo.name));
intent.setAction(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.setPackage(resInfo.activityInfo.parentActivityName);
//ignore list
if(packageName.contains("wifi") || packageName.contains("bluetooth") || packageName.contains("nfc") || packageName.contains("connect") || packageName.contains("memo") || packageName.contains("translate") || packageName.contains("gps")
|| packageName.contains("file") || packageName.contains("File") || packageName.contains("drive") || packageName.contains("office") || packageName.contains("docs") || packageName.contains("dropbox") || packageName.contains("beam")
|| packageName.contains("keep")) {
Logger.log_error( TAG + "sharenew IGNORE Package packageName = " + packageName);
continue;
}
Logger.log_error( TAG + "sharenew Package packageName = " + packageName);
if (packageName.contains("sms") || packageName.contains("mms") || packageName.contains("talk") || packageName.contains("messaging") || packageName.contains("twitter") || packageName.contains("com.facebook.orca")) {
intent.putExtra(Intent.EXTRA_TEXT, getString(R.string.str_share_app_short_text));
intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.str_share_app_subject));
} else if(packageName.contains("whatsapp")) {
// dont add subject for whatsapp
intent.putExtra(Intent.EXTRA_TEXT, getString(R.string.str_share_app_long_text));
} else {
intent.putExtra(Intent.EXTRA_TEXT, getString(R.string.str_share_app_long_text));
intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.str_share_app_subject));
}
targetShareIntents.add(new LabeledIntent(intent, packageName, resInfo.loadLabel(packageManager), resInfo.icon));
}
if(!targetShareIntents.isEmpty()){
Logger.log_error( TAG +"sharenew Have Intent");
Intent chooserIntent=Intent.createChooser(targetShareIntents.remove(0), "Choose app to share");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetShareIntents.toArray(new Parcelable[]{}));
startActivity(chooserIntent);
}else{
Logger.log_error( TAG +"sharenew nothing");
}
}
}
Reference:
How to filter specific apps for ACTION_SEND intent (and set a different text for each app)
I request people to improve answer. Thanks.

Tabs in StringBuilder don't work when sending an e-mail (Android)!

Bit of a weird on this; I my app I am using StringBuilder to build Strings to create an e-mail.
Now what I am trying to do is send the e-mail with parts of text tabbed (the text is to be transferred into a Word Document and this would save a lot of editing).
So in my code I am writing code to include the tabs, for example:
message.append(component).append("\t\t\t\t\t\t\t\t\t\t\t\t").append(risk).append("\r\n");
I use following code to construct the e-mail:
private void sendEmail(String recipient, String subject, String message) {
try {
final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("text/html");
emailIntent.setType("message/rfc822");
if (recipient != null) emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{recipient});
if (subject != null) emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
if (message != null) emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, message);
startActivity(Intent.createChooser(emailIntent, "Send mail..."));
} catch (ActivityNotFoundException e) {
// cannot send email for some reason
}
}
So when I look at the e-mail before sending, the tabs seem to have worked, but when I receive the e-mail, they are not there. Boo.
Any ideas why this might be?
Just have tried your code, it seems tab symbols trimmed while email sends.
Also tried this way and it works fine (in gmail), but it ugly solution
private String tab(){
return " "; // return four space characters
}
message.append(tab()+tab+tab());

How to send a picture via email in Android, previewed but NOT attached..?

I want to send a picture preview in my mail Intent.
I dont want to attach it, i just want it to be shown.
This is my intent:
String textToSend = getString(R.string.mailHi)+"<br><br>"+getString(R.string.mailText)+getTextToSendViaMail();
Uri pngUri = null;
File currentShopImage = new File(Environment.getExternalStorageDirectory().toString()+"/OpenGuide/"+Integer.toString(keyId)+"_1_normal.pn_");
if(currentShopImage.exists()){
File pngFile = new File(currentShopImage.toString());
pngUri = Uri.fromFile(pngFile);
}
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("text/plain");
//i.putExtra(Intent.EXTRA_EMAIL, new String[] { emailCim });
i.putExtra(Intent.EXTRA_SUBJECT, "OpenGuide");
i.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(textToSend));
if(pngUri!= null)
i.putExtra(Intent.EXTRA_STREAM, pngUri);
try {
startActivity(Intent.createChooser(i, getString(R.string.SendMail)));
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(ShopActivity.this, getString(R.string.MailClientNotFound), Toast.LENGTH_SHORT).show();
}
How can i achive such a thing ?
As far as I understood your problem, you want to place the image inside the mail with other text. In the words of Email protocol it's called an INLINE Attachment.
You would not be able to do this with intents as none of the email clients installed on the device supports creating html messages.
If it's really a core part of your app, you should consider a third party api to do this. One of the such library is JavaMail. You would be able to send html messages through this library but will take some time in setting up.
Here's a link that may give you some hint, how it's done.
Then you need to send a HTML generated email afaik.

Categories

Resources