AndroidとFacebookは意図を共有しています


84

私はAndroidアプリを開発していますが、Androidの共有インテントを使用してアプリ内からアプリユーザーのステータスを更新する方法を知りたいと思っています。

FacebookのSDKを見ると、これは簡単に実行できるように見えますが、ユーザーが通常の共有インテントポップアップウィンドウを介して実行できるようにしたいと思っていますか?ここで見られる:

現れる

通常の共有インテントコードを試しましたが、Facebookでは機能しなくなったようです。

public void invokeShare(Activity activity, String quote, String credit) {
    Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
    shareIntent.setType("text/plain");
    shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, activity.getString(R.string.share_subject));
    shareIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Example text");    

    activity.startActivity(Intent.createChooser(shareIntent, activity.getString(R.string.share_title)));
}

更新:さらに掘り下げてみると、Facebookのアプリのバグのように見えますが、まだ解決されていません!(Facebookのバグ)当面の間、「共有が機能しません!!!」というネガティブなことに我慢しなければならないようです。レビュー。乾杯Facebook:*(


複数の改訂で約1年が壊れましたなぜ彼らがそれを修正しないのか分かりません!!
Nathan Schwermann 2011

4
まだ壊れています。私は彼らがあなたに彼らの愚かなFacebookSDKを使わせるために故意にそれを修正しないと思い始めています。
UncleIstvan 2012年

5
うーん、Facebookは現在、動作が壊れているとは見なさず、変更しないと正式に回答したようです:developers.facebook.com/bugs/332619626816423
Scott W

1
それで、少なくとも修正や回避策はありませんか?私たちは空のメッセージと一緒に暮らす必要がありますか?:/
Ixx 2013年

1
残念ながら、唯一の修正または回避策は、SDKをアプリに統合することです。
ジョセフウッドワード

回答:


97

Facebookアプリケーションは、EXTRA_SUBJECTまたはEXTRA_TEXTフィールドのいずれも処理しません。

ここにバグリンクがあります:https//developers.facebook.com/bugs/332619626816423

ありがとう@billynomates:

問題は、EXTRA_TEXTフィールドにURLを入力すると、機能するという ことです。意図的にテキストを削除しているようなものです。


30
事はあなたがEXTRA_TEXT欄にURLを入れた場合、それは、ある仕事を。それは彼らが意図的にテキストを取り除くようなものです。
mSpeed 2013年

1
これがiOS(執筆時点)ではまだ機能しますが、Androidでは機能しないのは本当にばかげています。
Peter K.

Facebookで共有できるのはリンクのみです。
Misha Akopov 2014

2
ユーザーは手動でコンテンツを入力する必要があります:「ユーザーが編集できる提案されたコンテンツをメッセージパラメータに事前に入力することもポリシー違反であることに注意してください」youtube.com/watch?v=tGz48L0m5nc
kouretinho 2015年

1
@PeterK。Facebookでテキストを送信する方法を見つけましたか?
Karan Khurana 2016年

113

どうやらFacebookは(2014年の時点で)、sharer.php URLを開いているだけなのか、Androidインテントをより特殊な方法で使用しているのかに関係なく、共有画面をカスタマイズできなくなったようです。たとえば、次の回答を参照してください。

とにかく、プレーンインテントを使用すると、URLを共有できますビリーノメートがコメントしたようにデフォルトのテキストを共有することはできません。(また、共有するURLがない場合は、空の「投稿の書き込み」(つまりステータスの更新)ダイアログを使用してFacebookアプリを起動するだけでも同様に簡単です。以下のコードを使用しますが、省略しEXTRA_TEXTます。)

これが、FacebookSDKの使用を伴わない私が見つけた最良の解決策です。

このコードは、公式のFacebookアプリがインストールされている場合は直接開き、それ以外の場合はブラウザーでsharer.phpを開くことにフォールバックします。(この質問の他の解決策のほとんどは、まったく最適ではない巨大な「…を使用した完全なアクション」ダイアログ表示します!)

String urlToShare = "/programming/7545254";
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
// intent.putExtra(Intent.EXTRA_SUBJECT, "Foo bar"); // NB: has no effect!
intent.putExtra(Intent.EXTRA_TEXT, urlToShare);

// See if official Facebook app is found
boolean facebookAppFound = false;
List<ResolveInfo> matches = getPackageManager().queryIntentActivities(intent, 0);
for (ResolveInfo info : matches) {
    if (info.activityInfo.packageName.toLowerCase().startsWith("com.facebook.katana")) {
        intent.setPackage(info.activityInfo.packageName);
        facebookAppFound = true;
        break;
    }
}

// As fallback, launch sharer.php in a browser
if (!facebookAppFound) {
    String sharerUrl = "https://www.facebook.com/sharer/sharer.php?u=" + urlToShare;
    intent = new Intent(Intent.ACTION_VIEW, Uri.parse(sharerUrl));
}

startActivity(intent);

com.facebook.katanaパッケージ名については、MatheusJardimBのコメントを参照してください。)

FacebookアプリがインストールされているNexus7(Android 4.4)での結果は次のようになります。

ここに画像の説明を入力してください


3
「com.facebook.katana」はFacebookアプリのパッケージ名、「com.facebook.orca」はFBメッセンジャーアプリのパッケージ名です。必要な適切なpckgに変更できます。指定しない場合、最初に見つかったものが使用されます(良くありません)
MatheusJardimB 2014

1
良いキャッチ、ありがとう!答えを更新しました。Facebookは、プレフィックスと一致する他のアプリ(HomeおよびPages Manager)もリリースしていることが判明しましたcom.facebook
Jonik 2014

helow ...投稿の編集テキストを入力したい場合は、Facebookの操作方法。
das

URLでテキストも設定する方法は?
Anand Savjani 2017

できません(最初の方で太字で述べたように)。答えを読んでください。
Jonik 2017

16

通常の方法

あなたが求めているものを作成する通常の方法は、単に以下を行うことです:

    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setType("text/plain");
    intent.putExtra(Intent.EXTRA_TEXT, "The status update text");
    startActivity(Intent.createChooser(intent, "Dialog title text"));

これは私にとって問題なく動作します。

別の方法(多分)

これを行う際の潜在的な問題は、メッセージを電子メールやSMSなどで送信することも許可していることです。次のコードは、アプリケーションで使用しているもので、ユーザーが電子メールを送信できるようにします。 -Gmailを使用したメール。Facebookでのみ機能するように変更してみてください。

エラーや例外にどのように応答するかわからないので(Facebookがインストールされていない場合に発生すると思います)、少しテストする必要があるかもしれません。

    try {
        Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
        String[] recipients = new String[]{"e-mail address"};
        emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, recipients);
        emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "E-mail subject");
        emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "E-mail text");
        emailIntent.setType("plain/text"); // This is incorrect MIME, but Gmail is one of the only apps that responds to it - this might need to be replaced with text/plain for Facebook
        final PackageManager pm = getPackageManager();
        final List<ResolveInfo> matches = pm.queryIntentActivities(emailIntent, 0);
        ResolveInfo best = null;
        for (final ResolveInfo info : matches)
            if (info.activityInfo.packageName.endsWith(".gm") ||
                    info.activityInfo.name.toLowerCase().contains("gmail")) best = info;
                if (best != null)
                    emailIntent.setClassName(best.activityInfo.packageName, best.activityInfo.name);
                startActivity(emailIntent);
    } catch (Exception e) {
        Toast.makeText(this, "Application not found", Toast.LENGTH_SHORT).show();
    }

3
お返事ありがとうございます。これは私を混乱させるものですが、あなたが投稿したコードの最初のスニペットは、共有インテントが利用可能な他のすべてのアプリに投稿するのに問題なく機能しますが、Facebookのインテントでは、ユーザーは送信していないかのように空白の「何かを書く」Facebookページに移動します(またはおそらく受信)EXTRA_TEXTフィールド内のテキスト。
ジョセフウッドワード

うーん、それは私のタブレットの最初のものでうまく動作します。前述のように、EXTRA_SUBJECTフィールドなしで試してください。それが違いを生んでいるようです。
ミシェルバク2011

1
実際、私はそれをチェックしただけで、ええ、壊れています。働いていた。
ミシェルバク2011

ええ、私の編集した最初の投稿で述べたように、2011年4月から存在しているFacebookアプリのバグのようです(!)。とにかく、私の質問に答えるために時間を割いていただきありがとうございます。
ジョセフウッドワード

4
@TomSuselうん、Facebookは彼らのたわごとをまとめる必要があります。ただし、URLを含める場合は機能します。反対票をありがとう;
Michell Bak

5

Lollipop(21)では、Intent.EXTRA_REPLACEMENT_EXTRASFacebookのインテントを具体的にオーバーライドするために使用できます(リンクのみを指定します)

https://developer.android.com/reference/android/content/Intent.html#EXTRA_REPLACEMENT_EXTRAS

private void doShareLink(String text, String link) {
  Intent shareIntent = new Intent(Intent.ACTION_SEND);
  shareIntent.setType("text/plain");
  Intent chooserIntent = Intent.createChooser(shareIntent, getString(R.string.share_via));

  // for 21+, we can use EXTRA_REPLACEMENT_EXTRAS to support the specific case of Facebook
  // (only supports a link)
  // >=21: facebook=link, other=text+link
  // <=20: all=link
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    shareIntent.putExtra(Intent.EXTRA_TEXT, text + " " + link);
    Bundle facebookBundle = new Bundle();
    facebookBundle.putString(Intent.EXTRA_TEXT, link);
    Bundle replacement = new Bundle();
    replacement.putBundle("com.facebook.katana", facebookBundle);
    chooserIntent.putExtra(Intent.EXTRA_REPLACEMENT_EXTRAS, replacement);
  } else {
    shareIntent.putExtra(Intent.EXTRA_TEXT, link);
  }

  chooserIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  startActivity(chooserIntent);
}

5

私はあなただけのいずれかを共有することができますが分かったテキスト 画像を、両方とも使用していませんIntents。コードシェアのみ下の画像が存在する場合のみ、またはテキストあれば画像が終了しません。両方を共有したい場合は、ここからFacebookSDKを使用する必要があります。

以下のコードの代わりに他のソリューションを使用する場合は、FacebookLiteのパッケージ名であるパッケージ名com.facebook.liteも指定することを忘れないでください。私はテストしていませんが、それもターゲットにしたい場合は、com.facebook.orcaFacebookMes​​sengerのパッケージ名です。

WhatsAppTwitterと共有するためのメソッドをさらに追加できます...

public class IntentShareHelper {

    /**
     * <b>Beware,</b> this shares only image if exists, or only text if image does not exits. Can't share both
     */
    public static void shareOnFacebook(AppCompatActivity appCompatActivity, String textBody, Uri fileUri) {
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.setType("text/plain");
        intent.putExtra(Intent.EXTRA_TEXT,!TextUtils.isEmpty(textBody) ? textBody : "");

        if (fileUri != null) {
            intent.putExtra(Intent.EXTRA_STREAM, fileUri);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.setType("image/*");
        }

        boolean facebookAppFound = false;
        List<ResolveInfo> matches = appCompatActivity.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
        for (ResolveInfo info : matches) {
            if (info.activityInfo.packageName.toLowerCase().startsWith("com.facebook.katana") ||
                info.activityInfo.packageName.toLowerCase().startsWith("com.facebook.lite")) {
                intent.setPackage(info.activityInfo.packageName);
                facebookAppFound = true;
                break;
            }
        }

        if (facebookAppFound) {
            appCompatActivity.startActivity(intent);
        } else {
            showWarningDialog(appCompatActivity, appCompatActivity.getString(R.string.error_activity_not_found));
        }
    }

    public static void shareOnWhatsapp(AppCompatActivity appCompatActivity, String textBody, Uri fileUri){...}

    private static void showWarningDialog(Context context, String message) {
        new AlertDialog.Builder(context)
                .setMessage(message)
                .setNegativeButton(context.getString(R.string.close), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                })
                .setCancelable(true)
                .create().show();
    }
}

ファイルからURIを取得するには、以下のクラスを使用します。

public class UtilityFile {
    public static @Nullable Uri getUriFromFile(Context context, @Nullable File file) {
        if (file == null)
            return null;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            try {
                return FileProvider.getUriForFile(context, "com.my.package.fileprovider", file);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        } else {
            return Uri.fromFile(file);
        }
    }

    // Returns the URI path to the Bitmap displayed in specified ImageView       
    public static Uri getLocalBitmapUri(Context context, ImageView imageView) {
        Drawable drawable = imageView.getDrawable();
        Bitmap bmp = null;
        if (drawable instanceof BitmapDrawable) {
            bmp = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
        } else {
            return null;
        }
        // Store image to default external storage directory
        Uri bmpUri = null;
        try {
            // Use methods on Context to access package-specific directories on external storage.
            // This way, you don't need to request external read/write permission.
            File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "share_image_" + System.currentTimeMillis() + ".png");
            FileOutputStream out = new FileOutputStream(file);
            bmp.compress(Bitmap.CompressFormat.PNG, 90, out);
            out.close();

            bmpUri = getUriFromFile(context, file);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bmpUri;
    }    
}

書き込み用FileProviderを:、このリンクを使用https://github.com/codepath/android_guides/wiki/Sharing-Content-with-Intentsを


4

これが私がしたことです(テキスト用)。コードでは、クリップボードに必要なテキストをすべてコピーします。個人が初めて共有インテントボタンを使用しようとすると、Facebookに共有するかどうかを説明する通知がポップアップ表示されます。ユーザーは、[Facebook]をクリックしてから、長押しして貼り付ける必要があります(これは、Facebookを認識させるためです。アンドロイドインテントシステムが壊れています)。次に、関連情報がフィールドにあります。ユーザーも文句を言うことができるように、この投稿へのリンクを含めることもできます...

private void setClipboardText(String text) { // TODO
    int sdk = android.os.Build.VERSION.SDK_INT;
    if(sdk < android.os.Build.VERSION_CODES.HONEYCOMB) {
        android.text.ClipboardManager clipboard = (android.text.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
        clipboard.setText(text);
    } else {
        android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); 
        android.content.ClipData clip = android.content.ClipData.newPlainText("text label",text);
        clipboard.setPrimaryClip(clip);
    }
}

以下は、以前のバージョンを処理する方法です。

public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.menu_item_share:
        Intent shareIntent = new Intent(Intent.ACTION_SEND);
        shareIntent.setType("text/plain");
        shareIntent.putExtra(Intent.EXTRA_TEXT, "text here");

        ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); //TODO
         ClipData clip = ClipData.newPlainText("label", "text here");
         clipboard.setPrimaryClip(clip);

        setShareIntent(shareIntent); 

        break;
    }
        return super.onOptionsItemSelected(item);
}

2

Facebookのバージョン4.0.0では、多くのことが変更されたようです。これは正常に機能している私のコードです。それがあなたを助けることを願っています。

    /**
     * Facebook does not support sharing content without using their SDK however
     * it is possible to share URL
     *
     * @param content
     * @param url
     */
    private void shareOnFacebook(String content, String url)
    {
        try
        {
            // TODO: This part does not work properly based on my test
            Intent fbIntent = new Intent(Intent.ACTION_SEND);
            fbIntent.setType("text/plain");
            fbIntent.putExtra(Intent.EXTRA_TEXT, content);
            fbIntent.putExtra(Intent.EXTRA_STREAM, url);
            fbIntent.addCategory(Intent.CATEGORY_LAUNCHER);
            fbIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                    | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
            fbIntent.setComponent(new ComponentName("com.facebook.katana",
                    "com.facebook.composer.shareintent.ImplicitShareIntentHandler"));

            startActivity(fbIntent);
            return;
        }
        catch (Exception e)
        {
            // User doesn't have Facebook app installed. Try sharing through browser.
        }

        // If we failed (not native FB app installed), try share through SEND
        String sharerUrl = "https://www.facebook.com/sharer/sharer.php?u=" + url;
        SupportUtils.doShowUri(this.getActivity(), sharerUrl);
    }

1
SupportUtilsとは何ですか?
シルビアH

2

このソリューションも同様に機能します。Facebookがインストールされていない場合は、通常の共有ダイアログが実行されます。あり、ログインしていない場合は、ログイン画面に移動します。ログインしている場合は、共有ダイアログが開き、IntentExtraから「共有URL」が入力されます。

Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_TEXT, "Share url");
intent.setType("text/plain");

List<ResolveInfo> matches = getMainFragmentActivity().getPackageManager().queryIntentActivities(intent, 0);
for (ResolveInfo info : matches) {
    if (info.activityInfo.packageName.toLowerCase().contains("facebook")) {
        intent.setPackage(info.activityInfo.packageName);
    }
}

startActivity(intent);

0

これが私がFacebookアプリをリンクで開くためにしたことです

shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setComponent(new ComponentName("com.facebook.katana",
                    "com.facebook.katana.activity.composer.ImplicitShareIntentHandler"));

shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT,  videoUrl);

2
私にはうまくいきませんでした。おそらくFacebookはImplicitShareIntentHandlerの名前を変更しました。
ヘサム2015

0
    public void invokeShare(Activity activity, String quote, String credit) {
    Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
    shareIntent.setType("text/plain");
    shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, activity.getString(R.string.share_subject));
    shareIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Example text");    
    shareIntent.putExtra("com.facebook.platform.extra.APPLICATION_ID", activity.getString(R.string.app_id));                        
    activity.startActivity(Intent.createChooser(shareIntent, activity.getString(R.string.share_title)));
}

0

Facebookはプレーンテキストデータをと共有することを許可していませんがIntent.EXTRA_TEXT、これを使用してFacebookメッセンジャーとテキスト+リンクを共有することができます、これは私にとってはうまくいきます

            Intent sendIntent = new Intent();
            sendIntent.setAction(Intent.ACTION_SEND);
            sendIntent.putExtra(Intent.EXTRA_TEXT, text+url link);
            sendIntent.setType("text/plain");
            sendIntent.setPackage("com.facebook.orca");
            startActivity(sendIntent);

0

アプリからFacebookにメッセージを渡すために見つけることができる最も簡単な方法は、プログラムでクリップボードにコピーし、貼り付けるオプションがあることをユーザーに警告することでした。これにより、ユーザーが手動で行う必要がなくなります。私のアプリは貼り付けていませんが、ユーザーは貼り付けている可能性があります。

...
if (app.equals("facebook")) {
    // overcome fb 'putExtra' constraint;
    // copy message to clipboard for user to paste into fb.
    ClipboardManager cb = (ClipboardManager) 
            getSystemService(Context.CLIPBOARD_SERVICE);
    ClipData clip = ClipData.newPlainText("post", msg);
    cb.setPrimaryClip(clip);

    // tell the to PASTE POST with option to stop showing this dialogue
    showDialog(this, getString(R.string.facebook_post));
}
startActivity(appIntent);
...
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.