it-swarm.com.de

Android und Facebook teilen ihre Absichten

Ich entwickle eine Android-App und bin daran interessiert zu erfahren, wie Sie den Status des App-Benutzers innerhalb der App mithilfe der Share-Intents von Android aktualisieren können.

Nachdem Sie das SDK von Facebook durchgesehen haben, scheint dies leicht genug zu sein. Ich möchte jedoch, dass der Benutzer dies über das reguläre Share Intent-Popup-Fenster tun kann. hier gesehen: 

pop up

Ich habe den üblichen Share-Intent-Code ausprobiert, scheint jedoch für Facebook nicht mehr zu funktionieren.

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

UPDATE: Nachdem mehr gegraben wurde, sieht es so aus, als wäre es ein Fehler in der App von Facebook, der noch nicht gelöst wurde! ( facebook bug ) Mittlerweile sieht es so aus, als müsste ich nur das Negative in Kauf nehmen "Sharing funktioniert nicht !!!" Bewertungen. Prost Facebook: * (

78
Joseph Woodward

Die Facebook-Anwendung verarbeitet weder die Felder EXTRA_SUBJECT noch EXTRA_TEXT.

Hier ist ein Bug-Link: https://developers.facebook.com/bugs/332619626816423

Vielen Dank @billynomates:

Die Sache ist, wenn Sie eine URL in das Feld EXTRA_TEXT eingeben, wird do Arbeit. Es ist, als würden sie absichtlich jeden Text entfernen.

88
Göksel Güren

Anscheinend erlaubt Facebook seit 2014 nicht mehr, den Freigabebildschirm anzupassen, egal ob Sie gerade sharer.php URL öffnen oder Android Absichten auf spezialisiertere Weise verwenden. Siehe zum Beispiel diese Antworten:

Wie auch immer, mit einfachen Absichten können Sie können immer noch eine URL freigeben, aber keinen Standardtext , wie billynomates kommentiert . (Auch wenn Sie keine URL zum Teilen haben, ist es genauso einfach, die Facebook-App mit dem leeren Dialogfeld "Beitrag schreiben" (d. H. Statusaktualisierung) zu starten. Verwenden Sie den folgenden Code, aber lassen Sie _EXTRA_TEXT_ aus.)

Hier ist die beste Lösung, die ich gefunden habe, die nicht ​​die Verwendung von Facebook-SDKs beinhaltet.

Dieser Code öffnet die offizielle Facebook-App direkt , wenn sie installiert ist, und greift andernfalls auf das Öffnen von sharer.php in einem Browser zurück. (Die meisten anderen Lösungen in dieser Frage bringen ein riesiges Dialogfeld "Vollständige Aktion mit ..." ), das nicht optimal ist überhaupt!)

_String urlToShare = "https://stackoverflow.com/questions/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);
_

(Bezüglich des com.facebook.katana Paketnamens siehe Kommentar von MatheusJardimB .)

Das Ergebnis sieht auf meinem Nexus 7 (Android 4.4) mit installierter Facebook-App so aus:

enter image description here

109
Jonik

Der übliche Weg

Der übliche Weg, um das zu erstellen, wonach Sie fragen, ist einfach Folgendes zu tun:

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

Dies funktioniert ohne Probleme für mich.

Der alternative Weg (vielleicht)

Das potenzielle Problem dabei ist, dass Sie die Nachricht auch per E-Mail, SMS usw. senden. Der folgende Code ist etwas, das ich in einer Anwendung verwende, mit dem der Benutzer mir eine E-Mail senden kann -Mail mit Google Mail. Ich vermute, Sie könnten versuchen, es zu ändern, damit es nur mit Facebook funktioniert.

Ich bin mir nicht sicher, wie es auf Fehler oder Ausnahmen reagiert (ich vermute, das würde passieren, wenn Facebook nicht installiert ist). Daher müssen Sie es vielleicht ein wenig testen.

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

Hier ist was ich getan habe (für Text). Im Code kopiere ich den erforderlichen Text in die Zwischenablage. Wenn eine Person zum ersten Mal versucht, den Share-Intent-Button zu verwenden, wird eine Benachrichtigung eingeblendet, in der erläutert wird, ob sie an Facebook weitergegeben werden soll. Sie müssen auf "Facebook" klicken und dann lange drücken, um sie einzufügen hat das Android-Intent-System BROKEN). Dann sind die relevanten Informationen im Feld. Ich könnte auch einen Link zu diesem Beitrag einfügen, damit sich die Nutzer auch beschweren können ...

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

Nachfolgend finden Sie eine Methode zum Umgang mit früheren Versionen

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

In Lollipop (21) können Sie Intent.EXTRA_REPLACEMENT_EXTRAS verwenden, um speziell die Absicht von Facebook zu überschreiben (und nur einen Link anzugeben).

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);
}
4
Simon Reggiani

Ich habe herausgefunden, dass Sie nur Textoder _ ​​Image gemeinsam nutzen können, nicht beide, indem Sie Intents verwenden. Unterhalb des Codes wird nur Image angezeigt, falls vorhanden, oder nur Text, wenn Image nicht beendet wird. Wenn Sie beide freigeben möchten, müssen Sie das Facebook SDK von hier aus verwenden.

Wenn Sie anstelle des folgenden Codes eine andere Lösung verwenden, vergessen Sie nicht, den Paketnamen com.facebook.lite anzugeben. Dies ist der Paketname von Facebook Lite. Ich habe nicht getestet, aber com.facebook.orca ist der Paketname von Facebook Messenger, wenn Sie auch auf dieses Ziel zugreifen möchten. 

Sie können weitere Methoden für das Teilen mit WhatsApp , Twitter ... hinzufügen.

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

Um Uri von File zu erhalten, verwenden Sie unterhalb der Klasse:

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

Verwenden Sie zum Schreiben von FileProvider diesen Link: https://github.com/codepath/Android_guides/wiki/Sharing-Content-with-Intents

3

Diese Lösung funktioniert auch. Wenn kein Facebook installiert ist, wird nur der normale Share-Dialog gestartet. Wenn dies der Fall ist und Sie nicht angemeldet sind, wird der Anmeldebildschirm angezeigt. Wenn Sie angemeldet sind, wird der Freigabedialog geöffnet und die "Freigabe-URL" aus dem Intent Extra eingefügt.

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);
1
Tommy

In Version 4.0.0 von Facebook scheint sich so vieles zu ändern. Dies ist mein Code, der gut funktioniert. Ich hoffe es hilft dir.

    /**
     * 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
Hesam

Hier ist etwas, was ich gemacht habe, die Facebook-App mit Link öffnen 

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);
0
Nayanesh Gupte

Facebook erlaubt nicht, Nur-Text-Daten mit Intent.EXTRA_TEXT zu teilen, aber Sie können Text + Link mit Facebook-Nachrichten teilen, dies funktioniert für mich

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

Die einfachste Möglichkeit, eine Nachricht von meiner App an Facebook zu übermitteln, war das programmgesteuerte Kopieren in die Zwischenablage und die Benachrichtigung des Benutzers, dass er die Option zum Einfügen hat. Es erspart dem Benutzer, es manuell auszuführen; Meine App fügt nicht ein, aber der Benutzer könnte es tun.

...
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);
...
0
Ned