In my app I need to pick images from storage and display them on screen. I'm using an Intent to do this for me. I have posted my code to do this below.
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
try {
startActivityForResult(
Intent.createChooser(intent, "Select a File to Upload"),
FILE_SELECT_CODE);
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(this, "Please install a File Manager.",
Toast.LENGTH_SHORT).show();
}
The issue is that when the intent opens, I see a bunch of empty files of size 0 B. These files are not visible in the File Manager tool on my phone (where I'm testing my app). Is there any way to fix this - either by deleting those empty files or by having the intent ignore them?
Note: I don't know if this is helpful, but the images above are generated by my app, which uses Camera to capture and save images and later load them back through the file picker. The image with the preview is visible in the File Manager and is not 0 B, but the others are invisible.
Screenshot of file picker
Edit: Here's the code I'm using to capture images using camera and save them.
public void captureImageAction()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED ||
checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
String[] permission = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
requestPermissions(permission, PERMISSION_CODE);
} else {
openCamera();
}
} else {
openCamera();
}
}
private void openCamera() {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "New Picture");
values.put(MediaStore.Images.Media.DESCRIPTION, "From Camera");
image_uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri);
int IMAGE_CAPTURE_CODE = 1001;
startActivityForResult(cameraIntent, IMAGE_CAPTURE_CODE);
}
I am developing an android app and I need to send a message to specific contact from WhatsApp.
I tried this code:
Uri mUri = Uri.parse("smsto:+999999999");
Intent mIntent = new Intent(Intent.ACTION_SENDTO, mUri);
mIntent.setPackage("com.whatsapp");
mIntent.putExtra("sms_body", "The text goes here");
mIntent.putExtra("chat",true);
startActivity(mIntent);
The problem is that the parameter "sms_body" is not received on WhatsApp, though the contact is selected.
There is a way. Make sure that the contact you are providing must be passed as a string in intent without the prefix "+". Country code should be appended as a prefix to the phone number .
e.g.: '+918547264285' should be passed as '918547264285' . Here '91' in beginning is country code .
Note :Replace the 'YOUR_PHONE_NUMBER' with contact to which you want to send the message.
Here is the snippet :
Intent sendIntent = new Intent("android.intent.action.MAIN");
sendIntent.setComponent(new ComponentName("com.whatsapp","com.whatsapp.Conversation"));
sendIntent.putExtra("jid", PhoneNumberUtils.stripSeparators("YOUR_PHONE_NUMBER")+"#s.whatsapp.net");
startActivity(sendIntent);
Update:
The aforementioned hack cannot be used to add any particular message, so here is the new approach. Pass the user mobile in international format here without any brackets, dashes or plus sign. Example: If the user is of India and his mobile number is 94xxxxxxxx , then international format will be 9194xxxxxxxx. Don't miss appending country code as a prefix in mobile number.
private fun sendMsg(mobile: String, msg: String){
try {
val packageManager = requireContext().packageManager
val i = Intent(Intent.ACTION_VIEW)
val url =
"https://wa.me/$mobile" + "?text=" + URLEncoder.encode(msg, "utf-8")
i.setPackage("com.whatsapp")
i.data = Uri.parse(url)
if (i.resolveActivity(packageManager) != null) {
requireContext().startActivity(i)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
Note: This approach works only with contacts added in user's Whatsapp
account.
This new method, send message to a specific contact via whatsapp in Android. For more information look here
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_VIEW);
String url = "https://api.whatsapp.com/send?phone=" + number + "&text=" + path;
sendIntent.setData(Uri.parse(url));
activity.startActivity(sendIntent);here
I found the right way to do this and is just simple after you read this article: http://howdygeeks.com/send-whatsapp-message-unsaved-number-android/
phone and message are both String.
Source code:
try {
PackageManager packageManager = context.getPackageManager();
Intent i = new Intent(Intent.ACTION_VIEW);
String url = "https://api.whatsapp.com/send?phone="+ phone +"&text=" + URLEncoder.encode(message, "UTF-8");
i.setPackage("com.whatsapp");
i.setData(Uri.parse(url));
if (i.resolveActivity(packageManager) != null) {
context.startActivity(i);
}
} catch (Exception e){
e.printStackTrace();
}
Enjoy!
Great hack Rishabh, thanks a lot, I was looking for this solution since last 3 years.
As per the Rishabh Maurya's answer above, I have implemented this code which is working fine for both text and image sharing on WhatsApp. I have published this in my android app, so if you want to see it live try my app Bill Book
Note that in both the cases it opens a whatsapp conversation (if toNumber exists in users whatsapp contact list), but user have to click send button to complete the action. That means it helps in skipping contact selection step.
For text messages
String toNumber = "+91 98765 43210"; // contains spaces.
toNumber = toNumber.replace("+", "").replace(" ", "");
Intent sendIntent = new Intent("android.intent.action.MAIN");
sendIntent.putExtra("jid", toNumber + "#s.whatsapp.net");
sendIntent.putExtra(Intent.EXTRA_TEXT, message);
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.setPackage("com.whatsapp");
sendIntent.setType("text/plain");
startActivity(sendIntent);
For sharing images
String toNumber = "+91 98765 43210"; // contains spaces.
toNumber = toNumber.replace("+", "").replace(" ", "");
Intent sendIntent = new Intent("android.intent.action.MAIN");
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(imageFile));
sendIntent.putExtra("jid", toNumber + "#s.whatsapp.net");
sendIntent.putExtra(Intent.EXTRA_TEXT, message);
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.setPackage("com.whatsapp");
sendIntent.setType("image/png");
context.startActivity(sendIntent);
Enjoy WhatsApping!
We can share/send message to whats app. Below is Sample code to send text message on Whats-app
Single user
private void shareToOneWhatsAppUser(String message) {
/**
* NOTE:
* Message is shared with only one user at a time. and to navigate back to main application user need to click back button
*/
Intent whatsappIntent = new Intent(Intent.ACTION_SEND);
whatsappIntent.setType("text/plain");
whatsappIntent.setPackage("com.whatsapp");
whatsappIntent.putExtra(Intent.EXTRA_TEXT, message);
//Directly send to specific mobile number...
String smsNumber = "919900990099";//Number without with country code and without '+' prifix
whatsappIntent.putExtra("jid", smsNumber + "#s.whatsapp.net"); //phone number without "+" prefix
if (whatsappIntent.resolveActivity(getPackageManager()) == null) {
Toast.makeText(MainActivity.this, "Whatsapp not installed.", Toast.LENGTH_SHORT).show();
return;
}
startActivity(whatsappIntent);
}
Multiple user
private void shareToMultipleWhatsAppUser(String message) {
/**
* NOTE:
*
* If want to send same message to multiple users then have to select the user to whom you want to share the message & then click send.
* User navigate back to main Application once he/she select all desired persons and click send button.
* No need to click Back Button!
*/
Intent whatsappIntent = new Intent(Intent.ACTION_SEND);
whatsappIntent.setType("text/plain");
whatsappIntent.setPackage("com.whatsapp");
whatsappIntent.putExtra(Intent.EXTRA_TEXT, message);
if (whatsappIntent.resolveActivity(getPackageManager()) == null) {
Toast.makeText(MainActivity.this, "Whatsapp not installed.", Toast.LENGTH_SHORT).show();
return;
}
startActivity(whatsappIntent);
}
One more way to achieve the same
private void shareDirecctToSingleWhatsAppUser(String message) {
/**
* NOTE:
* Message is shared with only one user at a time. and to navigate back to main application user need to click back button
*/
//Directly send to specific mobile number...
String smsNumber = "919900000000";//Intended user`s mobile number with country code & with out '+'
PackageManager packageManager = getPackageManager();
Intent i = new Intent(Intent.ACTION_VIEW);
try {
String url = "https://api.whatsapp.com/send?phone="+ smsNumber +"&text=" + URLEncoder.encode("Test Message!", "UTF-8");
i.setPackage("com.whatsapp");
i.setData(Uri.parse(url));
if (i.resolveActivity(packageManager) != null) {
startActivity(i);
}
} catch (Exception e){
e.printStackTrace();
}
}
you can use this code:
Intent sendIntent = new Intent("android.intent.action.MAIN");
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.setPackage("com.whatsapp");
sendIntent.setType("text/plain");
sendIntent.putExtra("jid", "9194******22" + "#s.whatsapp.net");// here 91 is country code
sendIntent.putExtra(Intent.EXTRA_TEXT, "Demo test message");
startActivity(sendIntent);
This is the best way to send Message through Whatsapp to specific number or unsaved number
private void openWhatsApp() {
String smsNumber = "252634651588";
boolean isWhatsappInstalled = whatsappInstalledOrNot("com.whatsapp");
if (isWhatsappInstalled) {
Intent sendIntent = new Intent("android.intent.action.MAIN");
sendIntent.setComponent(new ComponentName("com.whatsapp", "com.whatsapp.Conversation"));
sendIntent.putExtra("jid", PhoneNumberUtils.stripSeparators(smsNumber) + "#s.whatsapp.net");//phone number without "+" prefix
startActivity(sendIntent);
} else {
Uri uri = Uri.parse("market://details?id=com.whatsapp");
Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri);
Toast.makeText(getContext(), "WhatsApp not Installed",
Toast.LENGTH_SHORT).show();
startActivity(goToMarket);
}
}
private boolean whatsappInstalledOrNot(String uri) {
PackageManager pm = Objects.requireNonNull(getContext()).getPackageManager();
boolean app_installed = false;
try {
pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);
app_installed = true;
} catch (PackageManager.NameNotFoundException e) {
app_installed = false;
}
return app_installed;
}
This is what works for me.
The parameter 'body' gets not red by the whatsapp app, use 'Intent.EXTRA_TEXT' instead.
By setting the 'phoneNumber' you specify the contact to open in whatsapp.
Intent sendIntent = new Intent(Intent.ACTION_SENDTO,
Uri.parse("smsto:" + "" + phoneNumber + "?body=" + encodedMessage));
sendIntent.putExtra(Intent.EXTRA_TEXT, message);
sendIntent.setPackage("com.whatsapp");
startActivity(sendIntent);
Uri mUri = Uri.parse("smsto:+90000900000");
Intent mIntent = new Intent(Intent.ACTION_SENDTO, mUri);
mIntent.setPackage("com.whatsapp");
mIntent.putExtra("chat",true);
startActivity(Intent.createChooser(mIntent, "Share with"));
Works great to send message to specific contact on WhatsApp from my android app
Try this code
Uri uri = Uri.parse("smsto:" + "+6281122xxx");
Intent i = new Intent(Intent.ACTION_SENDTO, uri);
i.putExtra(Intent.EXTRA_TEXT, getResources().getString(R.string.default_message_wa));
i.setPackage("com.whatsapp");
startActivity(Intent.createChooser(i, ""));
You can't put string directly on putExtra like this
i.putExtra(Intent.EXTRA_TEXT, "YOUR TEXT");
Change your code and get string from resource like this
i.putExtra(Intent.EXTRA_TEXT, getResources().getString(R.string.default_message_wa));
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_VIEW);
String url ="https://wa.me/your number";
sendIntent.setData(Uri.parse(url));
startActivity(sendIntent);
Here's my way to do it (more here):
First, if you want to be sure you can send the message, you can check if the person has a WhatsApp account on the address book:
#RequiresPermission(permission.READ_CONTACTS)
public String getContactMimeTypeDataId(#NonNull Context context, String contactId, #NonNull String mimeType) {
if (TextUtils.isEmpty(mimeType) || !PermissionUtil.hasPermissions(context, Manifest.permission.READ_CONTACTS))
return null;
ContentResolver cr = context.getContentResolver();
Cursor cursor = cr.query(ContactsContract.Data.CONTENT_URI, new String[]{Data._ID}, Data.MIMETYPE + "= ? AND "
+ ContactsContract.Data.CONTACT_ID + "= ?", new String[]{mimeType, contactId}, null);
if (cursor == null)
return null;
if (!cursor.moveToFirst()) {
cursor.close();
return null;
}
String result = cursor.getString(cursor.getColumnIndex(Data._ID));
cursor.close();
return result;
}
and if all seem well, you open it as if it's from the web:
final String contactMimeTypeDataId = getContactMimeTypeDataId(context, contactId, "vnd.android.cursor.item/vnd.com.whatsapp.profile");
if (contactMimeTypeDataId != null) {
final String whatsAppPhoneNumber = PhoneNumberHelper.normalizePhone(phoneNumber);
String url = "https://api.whatsapp.com/send?phone="+ whatsAppPhoneNumber ;
intent = new Intent(Intent.ACTION_VIEW,Uri.parse(url));
intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
.setPackage("com.whatsapp");
startActivity(intent);
}
You can also check if WhatsApp is even installed before of all of this (or remove the setPackage and check if any app can handle the Intent) :
final PackageManager packageManager = context.getPackageManager();
final ApplicationInfo applicationInfo = packageManager.getApplicationInfo("com.whatsapp", 0);
if (applicationInfo == null)
return;
EDIT: about preparing the Intent with the Uri, I think this way is better:
#JvmStatic
fun prepareWhatsAppMessageIntent(normalizedPhoneNumber: String?, message: String? = null): Intent {
// example url: "https://api.whatsapp.com/send?phone=normalizedPhoneNumber&text=abc"
val builder = Uri.Builder().scheme("https").authority("api.whatsapp.com").path("send")
normalizedPhoneNumber?.let { builder.appendQueryParameter("phone", it) }
message?.let { builder.appendQueryParameter("text", it) }
return Intent(Intent.ACTION_VIEW, builder.build())
}
or alternative (based on here):
fun prepareWhatsAppMessageIntent(normalizedPhoneNumber: String?, message: String? = null): Intent {
// example url: "https://wa.me/normalizedPhoneNumber&text=abc"
val builder = Uri.Builder().scheme("https").authority("wa.me")
normalizedPhoneNumber?.let { builder.appendPath(it) }
message?.let { builder.appendQueryParameter("text", it) }
return Intent(Intent.ACTION_VIEW, builder.build())
}
Try using Intent.EXTRA_TEXT instead of sms_body as your extra key. Per WhatsApp's documentation, this is what you have to use.
An example from their website:
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");
startActivity(sendIntent);
Their example uses Intent.ACTION_SEND instead of Intent.ACTION_SENDTO, so I'm not sure if WhatsApp even supports sending directly to a contact via the intent system. Some quick testing should let you determine that.
I would like the user to be able to click on a button and have the option of selecting the gallery or similar apps or a camera activity I have in my app not the build-in one . I read the related answers here and here . However, I don't want to include the build-in camera app, but I want to include my Camera Activity.
I have the following set up so far, taken from the two links I posted:
Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
Intent gallIntent = new Intent(Intent.ACTION_GET_CONTENT);
gallIntent.setType("image/*");
Intent camIntent = new Intent(UserEventsActivity.this,CameraActivity.class);
camIntent.setComponent(new ComponentName("MCamera", "Camera"));
List<Intent> yourIntentsList = new ArrayList<Intent>();
yourIntentsList.add(camIntent);
List<ResolveInfo> listGall = getApplicationContext().getPackageManager().queryIntentActivities(gallIntent, 0);
for (ResolveInfo res : listGall) {
final Intent finalIntent = new Intent(gallIntent);
finalIntent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
yourIntentsList.add(finalIntent);
}
pickIntent.putExtra(Intent.EXTRA_INTENT, yourIntentsList.toArray(new Parcelable[]{}));
pickIntent.putExtra(Intent.EXTRA_TITLE, "Select Source");
startActivityForResult(pickIntent, 1);
What results from this, is a large list of unrelated apps and services, most of which are actually repeated several times in the list. In addition, my camera activity is not among them. When I just do pickIntent.putExtra(Intent.EXTRA_INTENT,gallIntent) I do get the related gallery apps I want, but I can't add my activity.
Any ideas as to what I am doing wrong?
In addition, no service opens when I click on it. However, this may be related to the '1' arg in startActivityOnResult as I'm not exactly sure what to put for that arg.
I came up with a possible solution, that seemed to work for me. I used a custom Dialog:
final Dialog choosePicContent = new Dialog(UserEventsActivity.this);
ScrollView scrollContent = new ScrollView(UserEventsActivity.this);
choosePicContent.addContentView(scrollContent, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
LinearLayout scrollLayout = new LinearLayout(UserEventsActivity.this);
scrollContent.addView(scrollLayout);
scrollLayout.setOrientation(LinearLayout.VERTICAL);
TextView title = new TextView(UserEventsActivity.this);
title.setText(R.string.selectsource);
scrollLayout.addView(title);
Intent gallIntent = new Intent(Intent.ACTION_GET_CONTENT);
gallIntent.setType("image/*");
final Intent camIntent = new Intent(UserEventsActivity.this,CameraActivity.class);
ImageButton camButton = new ImageButton(UserEventsActivity.this);
camButton.setImageDrawable(getApplicationContext().getDrawable(R.drawable.ic_menu_camera));
camButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
camIntent.putExtra("User",current_user);
startActivity(camIntent);
}
});
scrollLayout.addView(camButton);
List<ResolveInfo> listGall = getApplicationContext().getPackageManager().queryIntentActivities(gallIntent, 0);
for (ResolveInfo res : listGall) {
final Intent finalIntent = new Intent(gallIntent);
finalIntent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
ImageButton iconButton = new ImageButton(UserEventsActivity.this);
iconButton.setImageDrawable(res.activityInfo.loadIcon(getPackageManager()));
iconButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivityForResult(finalIntent,1);
}
});
scrollLayout.addView(iconButton);
}
choosePicContent.show();
I have the following code for cropping images. It's working perfectly in android version 4 or OS Kitkat, but its not working on Android version 5 or OS Lollipop.
I've already searched the whole world but couldn't find the answer...
Here's my code:
In OS Kitkat: this list variable return a value. but,
In OS Lollipop: this list variable return a empty arraylist.
final ArrayList<CropOption> cropOptions = new ArrayList<CropOption>();
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setType("image/*");
List<ResolveInfo> list = getPackageManager().queryIntentActivities( intent, 0 );
PackageManager test = getPackageManager();
int size = list.size();
if (size == 0) {
Toast.makeText(this, "Can not find image crop app", Toast.LENGTH_SHORT).show();
return;
} else {
intent.setData(mCapturedImageURI);
intent.putExtra("outputX", 110);
intent.putExtra("outputY", 110);
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
intent.putExtra("return-data", true);
if (size == 1) {
Intent i = new Intent(intent);
ResolveInfo res = list.get(0);
i.setComponent( new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
startActivityForResult(i, CROP_FROM_CAMERA);
} else {
for (ResolveInfo res : list) {
final CropOption co = new CropOption();
co.title = getPackageManager().getApplicationLabel(res.activityInfo.applicationInfo);
co.icon = getPackageManager().getApplicationIcon(res.activityInfo.applicationInfo);
co.appIntent= new Intent(intent);
co.appIntent.setComponent( new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
cropOptions.add(co);
}
CropOptionAdapter adapter = new CropOptionAdapter(getApplicationContext(), cropOptions);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Choose Crop App");
builder.setAdapter( adapter, new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dialog, int item ) {
startActivityForResult( cropOptions.get(item).appIntent, CROP_FROM_CAMERA);
}
});
builder.setOnCancelListener( new DialogInterface.OnCancelListener() {
#Override
public void onCancel( DialogInterface dialog ) {
if (mCapturedImageURI != null ) {
getContentResolver().delete(mCapturedImageURI, null, null );
mCapturedImageURI = null;
}
}
} );
AlertDialog alert = builder.create();
alert.show();
}
}
I had already given android.permission.MANAGE_DOCUMENTS permission. But facing the same issue. After searching a lot, i found the solution.
Here's a workaround, for the time being:
Intent mIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(mIntent, CHOOSE_IMAGE);
This forces the older image gallery to open instead of the new Kitkat documents view.
Now, you can get the Uri by calling the following in your onActivityResult:
Uri selectedImageURI = data.getData();
Hope this help to solve your problem.
I want to share multi images with caption on Facebook using Intent. I tried some ways but it doesn't work. I can share photos but not the caption. Can you help me, please? Thanks!!!
My share function
private void share(String nameApp, ArrayList<String> imagePath, String text) {
try {
List<Intent> targetedShareIntents = new ArrayList<Intent>();
Intent share = new Intent(android.content.Intent.ACTION_SEND_MULTIPLE);
share.setType("image/*");
List<ResolveInfo> resInfo = getActivity().getPackageManager().queryIntentActivities(share, 0);
if (!resInfo.isEmpty()) {
for (ResolveInfo info : resInfo) {
Intent targetedShare = new Intent(
android.content.Intent.ACTION_SEND_MULTIPLE);
targetedShare.setType("image/*");
if (info.activityInfo.packageName.toLowerCase().contains(nameApp)
|| info.activityInfo.name.toLowerCase().contains(nameApp)) {
ArrayList<Uri> uris = new ArrayList<Uri>();
for (int i = 0; i < nImageCount; i++){
uris.add(Uri.parse("file://" + imagePath.get(i)));
}
targetedShare.putExtra(Intent.EXTRA_TITLE, text);
targetedShare.putExtra(Intent.EXTRA_TEXT, text);
targetedShare.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
targetedShare.setPackage(info.activityInfo.packageName);
targetedShareIntents.add(targetedShare);
}
}
Intent chooserIntent = Intent.createChooser(
targetedShareIntents.remove(0), "Select app to share");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,
targetedShareIntents.toArray(new Parcelable[] {}));
startActivity(chooserIntent);
}
} catch (Exception e) {
}
}
First, you are not using EXTRA_SUBJECT, which is where I would expect a "caption" to go.
Second, there is no EXTRA_TITLE in the documentation for ACTION_SEND_MULTIPLE.
Third, there is no requirement for any app to necessarily honor EXTRA_SUBJECT for ACTION_SEND_MULTIPLE.
I got the answer from Facebook developers. They don't support it anymore because of their policy.
They say "This issue is going to be closed by design because our API does not support pre-filling the message for users as seen in our Policy Documentation here (https://developers.facebook.com/docs/guides/policy/application_integration_points/) under Platform Policy IV.2"
https://developers.facebook.com/x/bugs/332619626816423/