官方称,Facebook不完全支持ACTION_SEND,也不使用提供的数据。 他们的政策是程序员应该使用他们的SDK在Facebook上发布。
发布意图时,生成的列表包含FB。这是一个问题,因为它需要不同格式的参数。 此外,它们似乎无法从弹出的列表中删除FB,即使它们实际上不能正确支持ACTION_SEND。
可以使用ActionChooser删除它,但这意味着我们必须有一个单独的按钮才能通过FB共享。
什么是最佳解决方案?
答案 0 :(得分:3)
一种可能的解决方案:
基本思想是“劫持”Facebook的意图并将其用于我自己的目的。
首先,我定义一个活动。此活动包含通过FB SDK发布消息的代码。
package il.co.anykey.apps.yavnehVeChachmaya.activities;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.FacebookSdk;
import com.facebook.share.Sharer;
import com.facebook.share.model.ShareLinkContent;
import com.facebook.share.widget.ShareDialog;
/**
* Created by jonathan.b on 22/07/2015.
*/
public class PostToFBActivity extends Activity {
public static final String EXTRA_CONTENT_URL = "content_url";
public static final String EXTRA_IMAGE_URL = "image_url";
private CallbackManager _fbCallbackManager;
private ShareDialog _fbShareDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String contentTitle = getIntent().getStringExtra(android.content.Intent.EXTRA_SUBJECT);
String contentDescription = getIntent().getStringExtra(Intent.EXTRA_TEXT);
String contentURL = getIntent().getStringExtra(EXTRA_CONTENT_URL);
String imageURL = getIntent().getStringExtra(EXTRA_IMAGE_URL);
try {
FacebookSdk.sdkInitialize(getApplicationContext());
_fbCallbackManager = CallbackManager.Factory.create();
_fbShareDialog = new ShareDialog(this);
// this part is optional
_fbShareDialog.registerCallback(_fbCallbackManager, new FacebookCallback<Sharer.Result>() {
/**
* Called when the dialog completes without error.
* @param result Result from the dialog
*/
@Override
public void onSuccess(Sharer.Result result) {
finish();
}
/**
* Called when the dialog is canceled.
*/
@Override
public void onCancel() {
finish();
}
/**
* Called when the dialog finishes with an error.
*
* @param error The error that occurred
*/
@Override
public void onError(FacebookException error) {
finish();
}
});
if (ShareDialog.canShow(ShareLinkContent.class)) {
ShareLinkContent.Builder builder = new ShareLinkContent.Builder();
if (contentTitle != null)
builder.setContentTitle(contentTitle);
if (contentDescription != null)
builder.setContentDescription(contentDescription);
if (contentURL != null)
builder.setContentUrl(Uri.parse(contentURL));
if (imageURL != null)
builder.setImageUrl(Uri.parse(imageURL));
_fbShareDialog.show(builder.build());
}
}
catch(Exception ex){
ex.printStackTrace();
}
}
@Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
_fbCallbackManager.onActivityResult(requestCode, resultCode, data);
}
}
可以看出,活动接收来自标准ACTION_SEND附加内容的数据以及一些“额外附加内容”。 然后它调用FB SDK发布它。 活动没有布局,一旦帖子完成就会退出。
下一步是将活动添加到清单中:
<activity android:name=".activities.PostToFBActivity" android:noHistory="true" android:screenOrientation="portrait"
android:icon="@drawable/facebook_icon" android:label="Facebook" android:exported="false">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
</activity>
现在活动将能够响应ACTION_SEND意图。为了只允许在此应用程序中访问此意图,我们添加了attribute android:exported="false"
。
此外,我们还添加了两个属性:
android:icon="@drawable/facebook_icon" android:label="Facebook"
这些定义了弹出应用程序选择器时将显示的图标和文本。 (@ drawable / facebook_icon是FB图标的副本)。 完整的意义将在下面解释。
下一步是创建一个排除Facebook软件包的IntentChooser(如果已安装)。
private Intent generateCustomChooserIntent(Intent prototype, String[] forbiddenChoices) {
List<Intent> targetedShareIntents = new ArrayList<Intent>();
List<HashMap<String, String>> intentMetaInfo = new ArrayList<HashMap<String, String>>();
Intent chooserIntent;
Intent dummy = new Intent(prototype.getAction());
dummy.setType(prototype.getType());
List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(dummy, 0);
if (!resInfo.isEmpty()) {
for (ResolveInfo resolveInfo : resInfo) {
if (resolveInfo.activityInfo == null || Arrays.asList(forbiddenChoices).contains(resolveInfo.activityInfo.packageName))
continue;
HashMap<String, String> info = new HashMap<String, String>();
info.put("packageName", resolveInfo.activityInfo.packageName);
info.put("className", resolveInfo.activityInfo.name);
info.put("simpleName", String.valueOf(resolveInfo.activityInfo.loadLabel(getPackageManager())));
intentMetaInfo.add(info);
}
if (!intentMetaInfo.isEmpty()) {
// sorting for nice readability
Collections.sort(intentMetaInfo, new Comparator<HashMap<String, String>>() {
@Override
public int compare(HashMap<String, String> map, HashMap<String, String> map2) {
return map.get("simpleName").compareTo(map2.get("simpleName"));
}
});
// create the custom intent list
for (HashMap<String, String> metaInfo : intentMetaInfo) {
Intent targetedShareIntent = (Intent) prototype.clone();
targetedShareIntent.setPackage(metaInfo.get("packageName"));
targetedShareIntent.setClassName(metaInfo.get("packageName"), metaInfo.get("className"));
targetedShareIntents.add(targetedShareIntent);
}
chooserIntent = Intent.createChooser(targetedShareIntents.remove(targetedShareIntents.size() - 1), getString(R.string.share));
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[]{}));
return chooserIntent;
}
}
return Intent.createChooser(prototype, getString(R.string.share));
}
这段代码不是我的,来到这里:https://gist.github.com/mediavrog/5625602
最后,我以正常的方式调用了ACTION_SEND意图,并添加了额外的额外内容:
intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "You Subject");
intent.putExtra(Intent.EXTRA_TEXT, "You Text.");
intent.putExtra(PostToFBActivity.EXTRA_CONTENT_URL,"http://your.site.url");
intent.putExtra(PostToFBActivity.EXTRA_IMAGE_URL,"you.image.url");
String[] blacklist = new String[]{"com.facebook.orca", "com.facebook.katana"};
startActivity(generateCustomChooserIntent(intent, blacklist));
这将显示一个意图选择Facebook的条目。
然而,这不是真正的FB意图。相反,它是我们的清单中添加的那个。 由于我们已经设置了FB的图标和标签,因此用户看起来好像在调用FB,而实际上他们正在使用PostToFBActivity。
我测试了它,它确实有效。 足够多,它甚至可以在没有安装FB的设备上运行。
我只用它来发布带有图片链接的邮件。 应该可以添加允许从设备发布图像的代码。