Android:如何通过意图在Facebook上分享带有文本的图像?

49
我希望分享一张照片到Facebook,并通过共享意图从我的应用程序中预填写标题。
示例代码:

I'd like to share a photo with caption pre-filled from my app via a share intent, on facebook.

Example code


示例代码
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setType("image/*");      

intent.putExtra(Intent.EXTRA_TEXT, "eample");
intent.putExtra(Intent.EXTRA_TITLE, "example");
intent.putExtra(Intent.EXTRA_SUBJECT, "example");
intent.putExtra(Intent.EXTRA_STREAM, imageUri);

Intent openInChooser = new Intent(intent);
openInChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents);
startActivity(openInChooser);

这是我得到的屏幕截图:

文本未显示

如果将类型设置为image / *,则上传的照片不会预填文本。 如果将其设置为text / plain,则不会显示照片.....


1
请检查以下链接:https://dev59.com/72Ij5IYBdhLWcg3wq2xz#20015435 - kalyan pvs
我认为你正在使用 Facebook API。 - Zala Janaksinh
1
我认为你应该使用FacebookSdk来完成这个。 - George Thomas
可能是Facebook帖子未显示的重复问题。 - George Thomas
检查这个链接 http://stackoverflow.com/questions/33951442/how-to-share-image-using-facebook-android - Aditya Vyas-Lakhan
7个回答

47
最新版的Facebook不允许使用意图分享文本。你需要使用Facebook SDK来实现这个功能,为了更简单地实现它,可以使用Facebook SDK + Android Simple Facebook (https://github.com/sromku/android-simple-facebook)。使用该库,您的代码可能像下面这样(从Simple Facebook网站中提取):

发布动态

设置 OnPublishListener 并调用:

  • publish(Feed, OnPublishListener) 不带对话框。
  • publish(Feed, true, OnPublishListener) 带有对话框。

基本属性

  • message - 用户留言
  • name - 所链接附件的名称
  • caption - 链接的标题(出现在链接名称下方)
  • description - 链接的描述(出现在链接标题下方)
  • picture - 附加到此帖子的图片的URL。图片必须至少为200px x 200px
  • link - 附加到此帖子的链接

初始化回调监听器:

OnPublishListener onPublishListener = new OnPublishListener() {
    @Override
        public void onComplete(String postId) {
            Log.i(TAG, "Published successfully. The new post id = " + postId);
        }

     /* 
      * You can override other methods here: 
      * onThinking(), onFail(String reason), onException(Throwable throwable)
      */
};

构建动态源:

Feed feed = new Feed.Builder()
    .setMessage("Clone it out...")
    .setName("Simple Facebook for Android")
    .setCaption("Code less, do the same.")
    .setDescription("The Simple Facebook library project makes the life much easier by coding less code for being able to login, publish feeds and open graph stories, invite friends and more.")
    .setPicture("https://raw.github.com/sromku/android-simple-facebook/master/Refs/android_facebook_sdk_logo.png")
    .setLink("https://github.com/sromku/android-simple-facebook")
    .build();

发布不带对话框的反馈:

mSimpleFacebook.publish(feed, onPublishListener);

使用对话框发布动态:

mSimpleFacebook.publish(feed, true, onPublishListener);

2015年12月14日更新


根据新的Facebook SDK。

facebook-android-sdk:4.6.0

很简单。
1. 在 Android.manifest.xml 中创建提供程序。

<provider
            android:authorities="com.facebook.app.FacebookContentProvider{APP_ID}"
            android:name="com.facebook.FacebookContentProvider"
            android:exported="true" />

2. 创建包含数据的分享意图。

ShareHashtag shareHashTag = new ShareHashtag.Builder().setHashtag("#YOUR_HASHTAG").build();
ShareLinkContent shareLinkContent = new ShareLinkContent.Builder()
                .setShareHashtag(shareHashTag)
                .setQuote("Your Description")
                .setContentUrl(Uri.parse("image or logo [if playstore or app store url then no need of this image url]"))
                .build();
3. 展示分享对话框

ShareDialog.show(ShowNavigationActivity.this,shareLinkContent);


就是这样。


这个库还能适用于新的政策和FB SDK版本吗?在您的示例中,当我按下登录按钮时,出现了无法登录应用程序的错误。您能帮我吗?谢谢。 - Ehsan
9
我认为Facebook的SDK需要一个“简单的Facebook”库很讽刺。我实在忍不住,要笑破肚皮了。 - Someone Somewhere
1
关于讽刺的评论(我同意):我想这是关于“锁定”的问题,即Facebook希望您通过他们分享,而不是通过其他任何人分享。 - SteelBytes
什么是mSimpleFacebook?我该如何初始化它? - Abdul Wahab
它不起作用。始终显示“用户取消了权限对话框”。 - Vince Yuan
显示剩余4条评论

4
截至2017年,Facebook不允许直接从您的应用程序共享图像和文本。
解决方法
然而,Facebook可以通过URL获取标题和图像数据,并在共享帖子中使用它们。
作为一种解决方法,您可以创建一个单页应用程序*,动态加载您想要共享的文本/图像(在URL中指定),然后共享该URL。
注意:
确保您的单页应用程序生成静态页面,在Facebook的页面抓取之前设置其标题、开放式图元标签和图像。如果这些网页标签通过JavaScript动态更改,则Facebook将无法抓取这些值并在其共享帖子中使用它们。
使用开放式图元属性标签og:image:height和og:image:width,允许Facebook创建图像预览在其共享帖子中。
步骤
0)将最新Facebook SDK库添加到您的build.gradle文件中。
compile group: 'com.facebook.android', name: 'facebook-android-sdk', version: '4.25.0'

1)在AndroidManifest.xml中,在<application>部分内添加一个meta-data标签:

<application android:label="@string/app_name" ...>
...
    <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>
...
</application>

在strings.xml文件中添加一个facebook_app_id字符串(带有您的APP ID):
<string name="facebook_app_id">12341234</string>

YOURFBAPPID是您在https://developers.facebook.com/apps/找到的Facebook应用程序ID号码。

2)还需要在AndroidManifest.xml中的<application>标签外添加一个<provider>标签。

<provider android:authorities="com.facebook.app.FacebookContentProviderYOURFBAPPID"
          android:name="com.facebook.FacebookContentProvider"
          android:exported="true"/>

3) 使用ShareLinkContent构建器创建一个ShareLinkContent对象:

ShareLinkContent fbShare = new ShareLinkContent.Builder()
            .setContentUrl(Uri.parse("http://yourdomain.com/your-title-here/someimagefilename"))
            .build();

4) 从您的片段(或活动等)共享它:

ShareDialog.show(getActivity(), fbShare);

Facebook文档

https://developers.facebook.com/docs/android/getting-started


2

Facebook不再允许您预填分享消息。

为了绕过这个问题,您需要使用SDK通过Graph请求发布。为此,您需要publish_actions权限。自上个月以来,您需要提交您的应用程序进行审核以获得对publish_actions的访问权限。如果您的应用程序预先填写了共享文本,则会失败。相信我-我曾经尝试过。

因此,看起来我们必须遵守规定。

顺便说一句,在iOS中,您仍然可以使用FB SDK预填文本。谁知道还能坚持多久。


那么既然没有选项,你是如何预填的呢? - ingsaurabh

1
在这个公式中,你可以在不使用任何提供程序的情况下,在Messenger和Instagram(com.instagram.android)之间共享图像,而无需在“AndroidManifest”中进行任何设置。
public void shareMessenger(View v) {
    // showToast("checking");

    File dir = new File(Environment.getExternalStorageDirectory(), "MyFolder");

    File imgFile = new File(dir, "Image.png");

    Intent sendIntent = new Intent(Intent.ACTION_VIEW);
    sendIntent.setType("image/*");
    sendIntent.setAction(Intent.ACTION_SEND);
    sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + imgFile));
    sendIntent.putExtra(Intent.EXTRA_TEXT, "<---MY TEXT--->.");
    sendIntent.setPackage("com.facebook.orca");
    sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    try {
        startActivity(Intent.createChooser(sendIntent, "Share images..."));
    } catch (android.content.ActivityNotFoundException ex) {
        Toast.makeText(SaveAndShareActivity.this, "Please Install Facebook Messenger", Toast.LENGTH_LONG).show();
    }

}

在onCreate方法中添加以下两行代码。
 StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
    StrictMode.setVmPolicy(builder.build());

你好,Khairun :) 请确保正确格式化您的代码,不要遗漏任何内容。如果您将代码分成几个部分,请清楚地说明它们的含义。 - Maciej Jureczko

-1

将以下代码添加到您的代码中

shareCaptionIntent.putExtra(Intent.EXTRA_TITLE, "my awesome caption in the EXTRA_TITLE field");

-1

如果不使用Facebook SDK,我们无法同时在Facebook上分享图像和文本。为了解决这个问题,我创建了一个图像和文本的位图,将该位图分享到Facebook上,它完美地工作。

您可以从这里下载源代码(在Android中使用意图分享图像和文本在Facebook上分享

以下是代码:

MainActivity.java

package com.shareimage;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class MainActivity extends AppCompatActivity implements 
View.OnClickListener {
EditText et_text;
ImageView iv_image;
TextView tv_share,tv_text;
RelativeLayout rl_main;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    init();

}

private void init(){
    et_text = (EditText)findViewById(R.id.et_text);
    iv_image = (ImageView)findViewById(R.id.iv_image);
    tv_share = (TextView)findViewById(R.id.tv_share);
    rl_main = (RelativeLayout)findViewById(R.id.rl_main);
    tv_text= (TextView) findViewById(R.id.tv_text);

    File dir = new File("/sdcard/Testing/");
    try {
        if (dir.mkdir()) {
            System.out.println("Directory created");
        } else {
            System.out.println("Directory is not created");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

    tv_share.setOnClickListener(this);

    et_text.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            tv_text.setText(et_text.getText().toString());

        }
    });


}




@Override
public void onClick(View v) {

    switch (v.getId()){
        case R.id.tv_share:
            Bitmap bitmap1 = loadBitmapFromView(rl_main, rl_main.getWidth(), rl_main.getHeight());
            saveBitmap(bitmap1);
            String str_screenshot = "/sdcard/Testing/"+"testing" + ".jpg";

            fn_share(str_screenshot);
            break;
    }

}

public void saveBitmap(Bitmap bitmap) {
    File imagePath = new File("/sdcard/Testing/"+"testing" + ".jpg");
    FileOutputStream fos;
    try {
        fos = new FileOutputStream(imagePath);
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
        fos.flush();
        fos.close();

        Log.e("ImageSave", "Saveimage");
    } catch (FileNotFoundException e) {
        Log.e("GREC", e.getMessage(), e);
    } catch (IOException e) {
        Log.e("GREC", e.getMessage(), e);
    }
}

public static Bitmap loadBitmapFromView(View v, int width, int height) {
    Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(b);
    v.draw(c);

    return b;
}

public void fn_share(String path) {

    File file = new File("/mnt/" + path);

    Bitmap bmp = BitmapFactory.decodeFile(file.getAbsolutePath());
    Uri uri = Uri.fromFile(file);
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setType("image/*");
    intent.putExtra(Intent.EXTRA_STREAM, uri);

    startActivity(Intent.createChooser(intent, "Share Image"));


}

}

-3
Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);

   shareIntent.setType("image/*");

   shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, (String) v.getTag(R.string.app_name));

   shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri); // put your image URI

   PackageManager pm = v.getContext().getPackageManager();

   List<ResolveInfo> activityList = pm.queryIntentActivities(shareIntent, 0);

     for (final ResolveInfo app : activityList) 
     {
         if ((app.activityInfo.name).contains("facebook")) 
         {

           final ActivityInfo activity = app.activityInfo;

           final ComponentName name = new ComponentName(activity.applicationInfo.packageName, activity.name);

          shareIntent.addCategory(Intent.CATEGORY_LAUNCHER);

          shareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);

          shareIntent.setComponent(name);

          v.getContext().startActivity(shareIntent);

          break;
        }
      }

1
你能解释一下你的解决方案吗? - superpuccio
当您想通过Facebook分享文本时,只有在点击分享按钮时才会触发startactivity并每次检查已安装应用程序的包名称,当它获取到Facebook的包名称时,其余代码将被执行并共享文本。 - Vaishali Sutariya
具有 .addCategory(Intent.CATEGORY_LAUNCHER) 的意图不起作用 - 只会在时间轴上启动主要的 FB,而不是启动用于发布新项目的 UI。 - Someone Somewhere

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接