I want in my app to share multiple photos. I am able to upload one photo using facebook graph API but how can I share multiple photos
Thanx.
Android does not provide an out-of-the-box Intent for selecting multiple images/pictures, or any other media type. Source: https://stackoverflow.com/a/12919585/450534 (And I usually will take Mark Murphy's word as Gospel unless someone can challenge it)
The closest Intent is the ACTION_SEND_MULTIPLE. That. however, is not an option for you.
You will need to create a custom selector similar to how Facebook does in it's own mobile app.
You will get a full functioning example for implementing your own multiple image selector here: http://vikaskanani.wordpress.com/2011/07/20/android-custom-image-gallery-with-checkbox-in-grid-to-select-multiple/
And finally, to upload multiple image to Facebook in one go, you will need to send Batch Requests.
But there certainly is no ready made solution for what you are looking for for. Combine all the above, and then you will. But nothing straightforward I'm afraid.
I managed to share multiple photos in Facebook using intents.
The variable "caminhos" is an ArrayList < String > with the paths of the images you want to share.
protected void share(String nameApp, String imagePath, String text) {
// TODO Auto-generated method stub
try {
List<Intent> targetedShareIntents = new ArrayList<Intent>();
Intent share = new Intent(android.content.Intent.ACTION_SEND_MULTIPLE);
share.setType("image/jpeg");
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/png"); // put here your mime
// type
if (info.activityInfo.packageName.toLowerCase().contains(
nameApp)
|| info.activityInfo.name.toLowerCase().contains(
nameApp)) {
targetedShare.putExtra(Intent.EXTRA_SUBJECT, text);
targetedShare.putExtra(Intent.EXTRA_TEXT, text);
ArrayList<Uri> files = new ArrayList<Uri>();
for(int j= 0;j<caminhos.size();j++){
if(!caminhos.get(j).isEmpty()){
File file = new File(caminhos.get(j));
Uri uri = Uri.fromFile(file);
files.add(uri);
}
}
targetedShare.putParcelableArrayListExtra(Intent.EXTRA_STREAM,
files);
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) {
}
}
Related
I'm implementing custom share feature for ACTION_SEND intent. I want to exclude my own app from sharing list. To achieve this I'm getting all suitable activities using getPackageManager().queryIntentActivityOptions(...) and then checking the package.
The problem is that getPackageManager().queryIntentActivityOptions(...) returns me a list of ResolveInfo objects where priority is always 0 and apps are ordered wrong - not like in the default share dialog. Thus apps don't have a proper order in a list and it's not convenient for user.
Here is a code which does sharing:
public void shareExcludingApp(String packageNameToExclude, Uri imagePath) {
List<Intent> targetedShareIntents = new ArrayList<>();
Intent share = new Intent(android.content.Intent.ACTION_SEND);
share.setType("image/*");
List<ResolveInfo> resInfo = mContext.getPackageManager().queryIntentActivities(createShareIntent(imagePath), 0);
if (!resInfo.isEmpty()) {
for (ResolveInfo info : resInfo) {
Intent targetedShare = createShareIntent(imagePath);
if (!info.activityInfo.packageName.equalsIgnoreCase(packageNameToExclude)) {
targetedShare.setPackage(info.activityInfo.packageName);
targetedShareIntents.add(targetedShare);
}
}
Intent chooserIntent = Intent.createChooser(targetedShareIntents.remove(0), mContext.getString(R.string.choose_an_app));
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[]{}));
mContext.startActivity(chooserIntent);
}
}
private Intent createShareIntent(Uri uri) {
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("image/*");
share.putExtra(Intent.EXTRA_STREAM, uri);
return share;
}
Am I configuring the intent wrong? Do I need to supply more data somewhere?
Thanks
Update:
Thanks to #CommonsWare I realized that I shouldn't use priority to order the list myself, instead the list should be sorted already (queryIntentActivities):
Returns a List of ResolveInfo objects containing one entry for each matching activity, ordered from best to worst.
But it's not sorted properly in my case and I'm getting activities mixed up. Can you please help me?
I want to use the directshare feature, but i need to exclude apps.
The excluding part works pretty well, i am just giving an array of intents to the chooser, while the intents are only including one specific application.
But doing this directshare does not work.
Directshare only seems to be working when giving exactly one intent to the chooser.
Is it possible to exclude apps and use directshare?
Code Snippets:
Sharing with a list of intents (How to filter specific apps for ACTION_SEND intent (and set a different text for each app)) :
final Intent chooserIntent = Intent.createChooser(targetShareIntents.remove(0), "Share with: ");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetShareIntents.toArray(new Parcelable[]{}));
activity.startActivity(chooserIntent);
Sharing with directshare, but no excluding:
final Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");
activity.startActivity(Intent.createChooser(sendIntent, "Share with:"));
I ran into the same problem with Direct Share, and found that it only seems to work for the target intent passed to createChooser().
My kludgy work-around was to lookup "com.android.mms" and pass that intent to createChooser() and the others in the targetedShareIntents array, which means that at least Direct Share works for text messages.
Note for some apps, not setting the class name in targetedShareIntents means you end up with Android System appearing in chooser instead.
For me this solution isn't good enough, and I'm leaning towards not excluding my own app from the list. Hopefully my efforts will lead someone to something better.
Code below is a variation on examples found here:
Custom filtering of intent chooser based on installed Android package name
I see here: http://stackoverflow.com/a/23036439 that saulpower may have a better solution, but I can't get it to work with my UI.
private void shareExludingApp(Intent intent, String packageNameToExclude, String title) {
List<Intent> targetedShareIntents = new ArrayList<Intent>();
List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(intent, 0);
Intent directShare = null;
if (!resInfo.isEmpty()) {
for (ResolveInfo info : resInfo) {
Intent targetedShare = new Intent(intent);
if (!info.activityInfo.packageName.startsWith(packageNameToExclude)) {
targetedShare.setPackage(info.activityInfo.packageName);
targetedShare.setClassName(info.activityInfo.packageName,
info.activityInfo.name);
if (directShare == null && info.activityInfo.packageName.equals("com.android.mms")) {
directShare = targetedShare;
} else {
targetedShareIntents.add(targetedShare);
}
}
}
}
if (targetedShareIntents.size() > 0) {
if (directShare == null) {
directShare = targetedShareIntents.remove(0);
}
Intent chooserIntent = Intent.createChooser(directShare, title);
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,
targetedShareIntents.toArray(new Parcelable[] {}));
startActivity(chooserIntent);
}
else {
startActivity(Intent.createChooser(intent, title));
}
}
Usage:
shareExludingApp(intent, getPackageName(), "Share via");
Background
I wish to show the native intent-chooser, while having the ability to customize it a bit.
For this, I've found the next StackOverflow thread:
How to customize share intent in Android?
The problem
Thing is, when I use the suggested code on Android 5.x and below, everything seems to be fine, but when I use it on Android 6.0.1 (tested on Nexus 5 and emulator, when having multiple apps to share content with) , I get empty cells and sometimes even empty app names, as such:
This doesn't appear when using the non-customized intent-chooser:
startActivity(Intent.createChooser(intent, "default chooser"));
The code
Seeing the solutions, I've created the next code:
private void test(Intent shareIntent) {
List<Intent> targetedShareIntents = new ArrayList<>();
final List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(shareIntent, 0);
if (!resInfo.isEmpty()) {
for (ResolveInfo resolveInfo : resInfo) {
Intent targetedShareIntent = new Intent(shareIntent);
targetedShareIntent.setClassName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name);
targetedShareIntents.add(targetedShareIntent);
}
Intent chooserIntent = Intent.createChooser(targetedShareIntents.remove(targetedShareIntents.size() - 1), "Select app to share");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[targetedShareIntents.size()]));
startActivity(chooserIntent);
}
}
private void prepareIntentToShare(Intent intent) {
intent.setAction(android.content.Intent.ACTION_SEND);
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_STREAM, mUri);
intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "title");
intent.putExtra(android.content.Intent.EXTRA_TEXT, "body");
}
And the way to test it:
Intent intent = new Intent();
prepareIntentToShare(intent);
test(intent);
What I've tried
I've tried to change various things in the intents, but without any luck. I've also tried to find out what is the order that the intents are supposed to be in (because maybe it's important), but I didn't find it.
Lastly, I've decided to post about it to Google, assuming this is a bug:
https://code.google.com/p/android/issues/detail?id=202693
The questions
Why does it occur? Can I fix it somehow, while still using the native intent-chooser? How come it occurs only on Android 6 and above?
How can I put the correct name for each item there, as I see "twitter" twice, for example, yet other apps do show the correct name (like the one of the qr-code-scanner)?
Is it possible to keep the native behavior of how to order of apps, as shown using the simple way of showing the intent-chooser? Maybe get the list of apps the way they are supposed to be ordered ?
I spend some time to read ChooserActivity and ResolverActivity and kind of solving thoese problems.
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
List<ResolveInfo> resolveInfos = context.getPackageManager().queryIntentActivities(intent, 0);
if (resolveInfos != null && !resolveInfos.isEmpty()) {
List<Intent> targetIntents = new ArrayList<>();
for (ResolveInfo resolveInfo : resolveInfos) {
ActivityInfo activityInfo = resolveInfo.activityInfo;
// remove activities which packageName contains 'ttt' for example
if (activityInfo.packageName.contains("ttt")) {
continue;
}
Intent targetIntent = new Intent(Intent.ACTION_SEND);
targetIntent.setType("text/plain");
targetIntent.putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.setting_share_app_subject));
targetIntent.putExtra(Intent.EXTRA_TEXT, context.getString(R.string.setting_share_app_body));
targetIntent.setPackage(activityInfo.packageName);
targetIntent.setComponent(new ComponentName(activityInfo.packageName, activityInfo.name));
// wrap with LabeledIntent to show correct name and icon
LabeledIntent labeledIntent = new LabeledIntent(targetIntent, activityInfo.packageName, resolveInfo.labelRes, resolveInfo.icon);
// add filtered intent to a list
targetIntents.add(labeledIntent);
}
Intent chooserIntent;
// deal with M list seperate problem
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// create chooser with empty intent in M could fix the empty cells problem
chooserIntent = Intent.createChooser(new Intent(), context.getString(R.string.setting_share_app_title));
} else {
// create chooser with one target intent below M
chooserIntent = Intent.createChooser(targetIntents.remove(0), context.getString(R.string.setting_share_app_title));
}
if (chooserIntent == null) {
return;
}
// add initial intents
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents.toArray(new Parcelable[targetIntents.size()]));
try {
context.startActivity(chooserIntent);
} catch (ActivityNotFoundException e) {
Logger.e(TAG, e, e);
}
}
EDIT: seems on Android Q (10 - API 29) this is broken, and will show just up to 2 items instead of all of them. Asked about this again here.
EDIT: made a sample of choosing which items to exclude from sharing, here, which should work for all Android versions.
I am doing an android share intent for Pinterest but is not fully working. I am able to attach the image but I can't send text to the "description" field in the share window. I've tried different types (text/plain, image/*, image/png) and also tried the ACTION_SEND_MULTIPLE intent type but still no luck. Google chrome share intent works perfectly so I'm sure Pinterest supports this functionality. Here is my code:
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("*/*");
intent.putExtra(Intent.EXTRA_TEXT, text);
if(file != null) intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
intent.setClassName(packageName, name);
this.startActivity(intent);
Any idea? thanks!
I found a way to share to Pinterest with plain Android intents (without using the Pinterest SDK), with help from Pin It button developer docs.
Basically you just open an URL like this with Intent.ACTION_VIEW; the official Pinterest app kindly supports these URLs. (I've earlier used a very similar approach for sharing to Twitter.)
https://www.pinterest.com/pin/create/button/
?url=http%3A%2F%2Fwww.flickr.com%2Fphotos%2Fkentbrew%2F6851755809%2F
&media=http%3A%2F%2Ffarm8.staticflickr.com%2F7027%2F6851755809_df5b2051c9_z.jpg
&description=Next%20stop%3A%20Pinterest
And for smoother user experience, set the intent to open directly in Pinterest app, if installed.
A complete example:
String shareUrl = "https://stackoverflow.com/questions/27388056/";
String mediaUrl = "http://cdn.sstatic.net/stackexchange/img/logos/so/so-logo.png";
String description = "Pinterest sharing using Android intents"
String url = String.format(
"https://www.pinterest.com/pin/create/button/?url=%s&media=%s&description=%s",
urlEncode(shareUrl), urlEncode(mediaUrl), urlEncode(description));
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
filterByPackageName(context, intent, "com.pinterest");
context.startActivity(intent);
Util methods used above:
public static void filterByPackageName(Context context, Intent intent, String prefix) {
List<ResolveInfo> matches = context.getPackageManager().queryIntentActivities(intent, 0);
for (ResolveInfo info : matches) {
if (info.activityInfo.packageName.toLowerCase().startsWith(prefix)) {
intent.setPackage(info.activityInfo.packageName);
return;
}
}
}
public static String urlEncode(String s) {
try {
return URLEncoder.encode(s, "UTF-8");
}
catch (UnsupportedEncodingException e) {
Log.wtf("", "UTF-8 should always be supported", e);
return "";
}
}
This is the result on a Nexus 5 with Pinterest app installed:
And if Pinterest app is not installed, sharing works just fine via a browser too:
for some reason pinterest app doesn't comply to the standard (Intent.EXTRA_TEXT) so we have to add it separately
if(appInfo.activityInfo.packageName.contains("com.pinterest"){
shareIntent.putExtra("com.pinterest.EXTRA_DESCRIPTION","your description");
}
File imageFileToShare = new File(orgimagefilePath);
Uri uri = Uri.fromFile(imageFileToShare);
Intent sharePintrestIntent = new Intent(Intent.ACTION_SEND);
sharePintrestIntent.setPackage("com.pinterest");
sharePintrestIntent.putExtra("com.pinterest.EXTRA_DESCRIPTION", text);
sharePintrestIntent.putExtra(Intent.EXTRA_STREAM, uri);
sharePintrestIntent.setType("image/*");
startActivityForResult(sharePintrestIntent, PINTEREST);
I am new on progamming android and I have some problems on sharing contents.
I did an android app that involves a test. In the last activity I'd like to offer the opportunity to share the users results via shareintent, here a frame of the code:
display= (TextView) findViewById (R.id.tvDisplay);
display.setText("Well Done, your score is" + score ); //score is an int
sharebutton= (Button)findViewById(R.id.sharebutton);
sharebutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
results = display.getText().toString();
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT,"My score in the test is" + results);
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "TEST");
startActivity(Intent.createChooser(shareIntent, "Share.."));
}
});
The problem is that when I click on the button, I can share the exact text in all of sharer tools (email, wapp, etc..), but not through Facebook. Why?
I tried to allow to post image and text on the FB wall but I can't give the exact path of the image that is on the drawable Folder.
Thank you for all the advices.
It depends upon Facebook app whether they are accepting text or not via intent,I know they accept images and bitmap files but for text they don't accept it.I've already tried this earlier in one of my own project but couldn't supply text via intent.
The Facebook application does not handle either the EXTRA_SUBJECT or EXTRA_TEXT fields.
I have already answer this question here.May be you can follow this link in case you need reference.
first store image in sdcard then share image on facebook
File filePath = new File(Environment
.getExternalStorageDirectory(),
"/foldername/imagename.jpg");
// share("facebook", filePath.toString());
System.out.println(filePath);
List<Intent> targetedShareIntents = new ArrayList<Intent>();
Intent share = new Intent(android.content.Intent.ACTION_SEND);
share.setType("image/jpeg");
List<ResolveInfo> resInfo = getActivity().getPackageManager()
.queryIntentActivities(share, 0);
if (!resInfo.isEmpty()) {
for (ResolveInfo info : resInfo) {
Intent targetedShare = new Intent(
android.content.Intent.ACTION_SEND);
targetedShare.setType("image/jpeg"); // put here your
// mime
// type
if (info.activityInfo.packageName.toLowerCase()
.contains("facebook")
|| info.activityInfo.name.toLowerCase()
.contains("facebook")) {
targetedShare.putExtra(Intent.EXTRA_SUBJECT,
"Sample Photo");
targetedShare.putExtra(Intent.EXTRA_TEXT,
"This photo is created by App Name");
targetedShare.putExtra(Intent.EXTRA_STREAM,
Uri.fromFile(filePath));
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);
}