[android] Android와 Facebook 공유 의도

저는 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 bug ) 당분간은 “공유가 안 돼요 !!!”라는 부정적인 말을 참 아야 할 것 같습니다. 리뷰. 건배 페이스 북 : * (



답변

Facebook 애플리케이션은 EXTRA_SUBJECT또는 EXTRA_TEXT필드를 처리하지 않습니다 .

다음은 버그 링크입니다. https://developers.facebook.com/bugs/332619626816423

감사합니다 @billynomates :

문제는 당신이에 URL을 넣을 경우입니다 EXTRA_TEXT필드는 않는
일을. 의도적으로 텍스트를 제거하는 것과 같습니다.


답변

분명히 Facebook은 더 이상 (2014 년 현재) sharer.php URL을 열거 나 Android 인 텐트를보다 전문적인 방법으로 사용 하더라도 공유 화면을 사용자 정의 할 수 없습니다 . 예를 들어 다음 답변을 참조하십시오.

어쨌든, 일반 텐트를 사용하여, 당신은 할 수 있습니다 여전히 URL, 그러나 그것으로 모든 기본 텍스트를 공유 로, billynomates 댓글을 달았습니다 . (또한 공유 할 URL이없는 경우 빈 “Write Post”(즉, 상태 업데이트) 대화 상자를 사용하여 Facebook 앱을 실행하는 것도 똑같이 쉽습니다. 아래 코드를 사용하되 생략하십시오 EXTRA_TEXT.)

여기에 Facebook SDK를 사용 하지 않는 최고의 솔루션이 있습니다.

이 코드 는 공식 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 앱이 설치된 Nexus 7 (Android 4.4)에서 다음과 같습니다.

여기에 이미지 설명 입력


답변

일반적인 방법

원하는 것을 생성하는 일반적인 방법은 다음을 수행하는 것입니다.

    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();
    }


답변

Lollipop (21)에서는 Intent.EXTRA_REPLACEMENT_EXTRAS특별히 Facebook에 대한 인 텐트를 재정의하는 데 사용할 수 있습니다 (링크 만 지정).

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);
}


답변

나는 당신이 둘 다를 사용하는 것이 아니라 Text 또는 Image 중 하나만 공유 할 수 있다는 것을 알았다 Intents. 코드 공유에만 아래 이미지 가있는 경우, 또는 유일한 텍스트 경우 이미지가 종료되지 않습니다. 둘 다 공유하려면 여기에서 Facebook SDK 를 사용해야 합니다.

아래 코드 대신 다른 솔루션을 사용하는 경우 패키지 이름 com.facebook.lite 도 지정하는 것을 잊지 마십시오 . 이는 Facebook Lite의 패키지 이름입니다 . 나는 테스트하지 않았지만 com.facebook.orca 는 당신이 그것을 목표로 삼고 싶다면 Facebook Messenger 의 패키지 이름입니다 .

WhatsApp , Twitter 와 공유하기위한 더 많은 방법을 추가 할 수 있습니다 .

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


답변

여기 내가 한 일이 있습니다 (텍스트). 코드에서 필요한 모든 텍스트를 클립 보드에 복사합니다. 개인이 처음으로 공유 의도 버튼을 사용하려고하면 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);
}


답변

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);
    }