I am currently trying to share text to gmail, facebook and twitter. I am using share intent method to share. Below is the code i used to share
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
sharingIntent.setType("plain/text");
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, "My text");
startActivity(Intent.createChooser(sharingIntent,"Share using"));
The above code only show share options like gmail and skype. Why is facebook and twitter options not shown in the list even though i had the facebook and twitter application installed in my device?
I don't know if anybody still reads this, but if people are still looking I found an easier answer:
List<Intent> targetedShareIntents = new ArrayList<Intent>();
Intent facebookIntent = getShareIntent("facebook", "subject", "text");
if(facebookIntent != null)
targetedShareIntents.add(facebookIntent);
Intent twitterIntent = getShareIntent("twitter", "subject", "text");
if(twitterIntent != null)
targetedShareIntents.add(twitterIntent);
Intent gmailIntent = getShareIntent("gmail", "subject", "text");
if(gmailIntent != null)
targetedShareIntents.add(gmailIntent);
Intent chooser = Intent.createChooser(targetedShareIntents.remove(0), "Delen");
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[]{}));
startActivity(chooser);
And the getShareIntent method (this method searches through the mime type text/plain, you can use other mime types to search through those types or use /*/ to search through all types:
private Intent getShareIntent(String type, String subject, String text)
{
boolean found = false;
Intent share = new Intent(android.content.Intent.ACTION_SEND);
share.setType("text/plain");
// gets the list of intents that can be loaded.
List<ResolveInfo> resInfo = getActivity().getPackageManager().queryIntentActivities(share, 0);
System.out.println("resinfo: " + resInfo);
if (!resInfo.isEmpty()){
for (ResolveInfo info : resInfo) {
if (info.activityInfo.packageName.toLowerCase().contains(type) ||
info.activityInfo.name.toLowerCase().contains(type) ) {
share.putExtra(Intent.EXTRA_SUBJECT, subject);
share.putExtra(Intent.EXTRA_TEXT, text);
share.setPackage(info.activityInfo.packageName);
found = true;
break;
}
}
if (!found)
return null;
return share;
}
return null;
}
If you don't want to use this method you can just create Intents like this:
Intent normalIntent = new Intent(Intent.ACTION_SEND);
normalIntent.setType("text/plain");
normalIntent.setPackage("com.katana.facebook"); // I just know the package of Facebook, the rest you will have to search for or use my method.
normalIntent.putExtra(Intent.EXTRA_TEXT, "The text you want to share to Facebook");
Sharing with Facebook has the problem that it only accepts an url in the EXTRA_TEXT. The native FB app will then grab a text and an image from this url to compose the post. That's not a "bug" but the intended behaviour they give to the official app :-/
Take into account Twitter will only accept text/plain without any markup and with 144 chars at max.
I've made my own "Share" dialog to intercept all different behaviours and give to each target intent what they accepts: HTML, plain text, FB URL and Twitter short text.
Here comes the code:
public class ShareHelper implements AdapterView.OnItemClickListener {
private static final String TAG = ShareHelper.class.getSimpleName();
private Activity mContext;
private Dialog mDialog;
private LayoutInflater mInflater;
private GridView mGrid;
private ShareIntentAdapter mAdapter;
private int mMaxColumns;
private List<ResolveInfo> plainTextActivities;
private Set<String> htmlActivitiesPackages;
private String subject;
private String textbody;
private CharSequence htmlbody;
private String twitterBody;
private String facebookBody;
public ShareHelper(Activity context, String subject, String textbody, CharSequence htmlbody, String twitterBody, String facebookBody) {
this.mContext = context;
this.subject = subject;
this.textbody = textbody;
this.htmlbody = htmlbody;
this.twitterBody = twitterBody;
this.facebookBody = facebookBody;
}
@SuppressLint("NewApi")
public void share() {
this.mInflater = LayoutInflater.from(mContext);
final Intent sendIntent = new Intent(android.content.Intent.ACTION_SEND);
sendIntent.setType(HTTP.PLAIN_TEXT_TYPE);
plainTextActivities = mContext.getPackageManager().queryIntentActivities(sendIntent, 0);
if (plainTextActivities.size() > 0) {
htmlActivitiesPackages = new HashSet<String>();
sendIntent.setType("text/html");
final List<ResolveInfo> htmlActivities = mContext.getPackageManager().queryIntentActivities(sendIntent, 0);
for (ResolveInfo resolveInfo : htmlActivities) {
htmlActivitiesPackages.add(resolveInfo.activityInfo.packageName);
}
mAdapter = new ShareIntentAdapter();
final View chooserView = mInflater.inflate(R.layout.dialog_share_us_chooser, null);
mGrid = (GridView) chooserView.findViewById(R.id.resolver_grid);
mGrid.setAdapter(mAdapter);
mGrid.setOnItemClickListener(this);
mMaxColumns = mContext.getResources().getInteger(R.integer.maxResolverActivityColumns);
mGrid.setNumColumns(Math.min(plainTextActivities.size(), mMaxColumns));
AlertDialog.Builder builder;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
builder = new AlertDialog.Builder(mContext, AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
} else {
builder = new AlertDialog.Builder(mContext);
}
builder.setTitle(R.string.text_share_us_title);
builder.setView(chooserView);
mDialog = builder.create();
mDialog.show();
} else {
Toast.makeText(mContext, "No social apps installed to share ChurchLink!", Toast.LENGTH_LONG).show();
}
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ResolveInfo info = (ResolveInfo) mAdapter.getItem(position);
Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setClassName(info.activityInfo.packageName, info.activityInfo.name);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TITLE, subject);
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
if (info.activityInfo.packageName.contains("facebook")) {
intent.putExtra(Intent.EXTRA_TEXT, facebookBody);
} else if (info.activityInfo.packageName.contains("twitter")) {
intent.putExtra(Intent.EXTRA_TEXT, twitterBody);
} else if (htmlActivitiesPackages.contains(info.activityInfo.packageName)) {
intent.putExtra(Intent.EXTRA_TEXT, htmlbody);
} else {
intent.putExtra(Intent.EXTRA_TEXT, textbody);
}
Log.d(TAG, info.activityInfo.packageName);
((Activity) mContext).startActivity(intent);
mDialog.dismiss();
}
public class ShareIntentAdapter extends BaseAdapter {
public ShareIntentAdapter() {
super();
}
@Override
public int getCount() {
return plainTextActivities != null? plainTextActivities.size() : 0;
}
@Override
public ResolveInfo getItem(int position) {
return plainTextActivities.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
if (convertView == null) {
view = mInflater.inflate(R.layout.griditem_share_us, parent, false);
} else {
view = convertView;
}
bindView(view, plainTextActivities.get(position));
return view;
}
private final void bindView(View view, ResolveInfo info) {
TextView text = (TextView)view.findViewById(android.R.id.text1);
ImageView icon = (ImageView)view.findViewById(android.R.id.icon);
text.setText(info.activityInfo.applicationInfo.loadLabel(mContext.getPackageManager()).toString());
icon.setImageDrawable(info.activityInfo.applicationInfo.loadIcon(mContext.getPackageManager()));
}
}
}
Seems like some people wants the layout files too. Here are they:
dialog_share_us_chooser.xml
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/resolver_grid"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:clipToPadding="false"
android:columnWidth="128dp"
android:numColumns="4"
android:padding="16dp"
android:scrollbarStyle="outsideOverlay" />
griditem_share_us.xml (from own AOSP project):
<?xml version="1.0" encoding="utf-8"?>
<!--
/* //device/apps/common/res/any/layout/resolve_list_item.xml
**
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="center"
android:orientation="vertical"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:padding="16dp">
<!-- android:background="@android:drawable/activity_picker_bg" -->
<!-- Activity icon when presenting dialog
Size will be filled in by ResolverActivity -->
<ImageView android:id="@android:id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitCenter" />
<!-- Activity name -->
<TextView android:id="@android:id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:minLines="2"
android:maxLines="2"
android:paddingLeft="4dip"
android:paddingRight="4dip" />
<!-- android:textAppearance="android:attr/textAppearanceSmall" -->
</LinearLayout>
If you change the above line to:
sharingIntent.setType("text/plain");
, Would this problem be resolved?
I think it's text/plain
, not plain/text
.
Reference from Android Developers:
mimeType A MIME type (i.e. text/plain)