Android und Facebook teilen die Absicht

83

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

Nachdem ich das SDK von Facebook durchgesehen habe, scheint es einfach genug zu sein, aber ich möchte dem Benutzer erlauben, dies über das reguläre Popup-Fenster "Share Intent" zu tun. hier gesehen:

aufpoppen

Ich habe den üblichen Share Intent Code ausprobiert, dies 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 wir mehr gegraben haben, sieht es so aus, als wäre es ein Fehler in der Facebook-App, der noch behoben werden muss! ( Facebook-Bug ) In der Zwischenzeit sieht es so aus, als müsste ich mich nur mit dem negativen "Teilen funktioniert nicht !!!" abfinden. Bewertungen. Prost Facebook: * (

Joseph Woodward
quelle
Ich verstehe nicht, warum sie es nicht reparieren werden, seit ungefähr einem Jahr mit mehreren Revisionen.
Nathan Schwermann
4
Immer noch kaputt. Ich fange an zu denken, dass sie es nicht absichtlich reparieren, um dich dazu zu bringen, ihr dummes Facebook SDK zu benutzen.
OnkelIstvan
5
Ugh, es scheint, dass Facebook nun offiziell geantwortet hat, dass sie das Verhalten nicht als fehlerhaft betrachten und es nicht ändern werden: developer.facebook.com/bugs/332619626816423
Scott W
1
Also zumindest keine Lösung oder Problemumgehung? Wir müssen mit der leeren Nachricht leben? : /
Ixx
1
Leider besteht die einzige Lösung darin, das SDK in Ihre App zu integrieren.
Joseph Woodward

Antworten:

97

Die Facebook - Anwendung nicht verarbeitet entweder die EXTRA_SUBJECToder EXTRA_TEXTFelder.

Hier ist ein Fehlerlink: https://developers.facebook.com/bugs/332619626816423

Danke @billynomates:

Die Sache ist, wenn Sie eine URL in das EXTRA_TEXTFeld einfügen , es einfügen, funktioniert es. Es ist, als würden sie absichtlich jeden Text entfernen.

Göksel Güren
quelle
30
Die Sache ist, wenn Sie eine URL in dem EXTRA_TEXT Feld setzen, es tut Arbeit. Es ist, als würden sie absichtlich jeden Text entfernen.
MSpeed
1
Es ist wirklich dumm, dass dies unter iOS (zum Zeitpunkt des Schreibens) immer noch funktioniert, aber unter Android nicht.
Peter K.
Auf Facebook können nur Links mit der Absicht geteilt werden.
Mischa Akopov
2
Benutzer müssen den Inhalt
manuell eingeben
1
@ PeterK. Hast du einen Weg gefunden, den Text auf Facebook zu senden?
Karan Khurana
112

Anscheinend können Sie auf Facebook (ab 2014) den Freigabebildschirm nicht mehr anpassen, unabhängig davon, ob Sie nur die URL sharer.php öffnen oder Android-Absichten auf speziellere Weise verwenden. Siehe zum Beispiel diese Antworten:

Wie auch immer, mit Klar Intents, Sie können immer noch eine URL teilen, aber keine Standardtext mit ihm , als billynomates kommentiert . (Wenn Sie keine URL zum Teilen haben, ist es ebenso einfach, die Facebook-App mit dem leeren Dialog "Beitrag schreiben" (dh Statusaktualisierung) zu starten. Verwenden Sie den folgenden Code, lassen Sie ihn jedoch weg EXTRA_TEXT.)

Hier ist die beste Lösung , die ich gefunden habe , die sich nicht verwickeln Verwendung irgendwelcher Facebook SDKs.

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

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

(Bezüglich des com.facebook.katanaPaketnamens siehe den Kommentar von MatheusJardimB .)

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

Geben Sie hier die Bildbeschreibung ein

Jonik
quelle
3
"com.facebook.katana" ist der Paketname für die Facebook-App und "com.facebook.orca" für die FB Messenger-App. Sie können zu dem gewünschten Pckg wechseln. Wenn Sie keine angeben, wird die erste gefundene verwendet (nicht gut)
MatheusJardimB
1
Guter Fang, danke! Ich habe die Antwort aktualisiert. Es stellte sich heraus, dass Facebook auch andere Apps veröffentlicht hat ( Home and Pages Manager ), die ebenfalls dem com.facebookPräfix entsprechen würden.
Jonik
helow ... wenn ich post edittext füllen will dann wie man mit facebook arbeitet.
Das
Wie setze ich auch Text mit URL?
Anand Savjani
Sie können nicht (wie in Fettdruck am Anfang erwähnt). Bitte lesen Sie einfach die Antwort.
Jonik
16

Der übliche Weg

Der übliche Weg, um das zu erstellen, wonach Sie fragen, besteht darin, 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 für mich ohne Probleme.

Der alternative Weg (vielleicht)

Das potenzielle Problem dabei ist, dass Sie auch zulassen, dass die Nachricht per E-Mail, SMS usw. gesendet wird. Der folgende Code wird in einer Anwendung verwendet, sodass der Benutzer mir eine E senden kann -mail mit Google Mail. Ich vermute, Sie könnten versuchen, es so zu ändern, dass es nur mit Facebook funktioniert.

Ich bin mir nicht sicher, wie es auf Fehler oder Ausnahmen reagiert (ich vermute, dass dies auftreten würde, wenn Facebook nicht installiert ist), daher müssen Sie es möglicherweise 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();
    }
Michell Bak
quelle
3
Danke für Ihre Antwort. Dies ist jedoch das, was mich verwirrt. Der erste Code-Ausschnitt, den Sie veröffentlicht haben, funktioniert einwandfrei für das Posten in jeder anderen App mit verfügbaren Freigabeabsichten. Mit der Absicht von Facebook wird der Benutzer jedoch zu einer leeren Facebook-Seite "Etwas schreiben" geleitet, als würde er nicht senden ( oder möglicherweise) den Text im Feld EXTRA_TEXT empfangen.
Joseph Woodward
Hmm, es funktioniert gut mit dem ersten auf meinem Tablet. Versuchen Sie es wie angegeben ohne das Feld EXTRA_SUBJECT. Das scheint den Unterschied zu machen.
Michell Bak
1
Eigentlich habe ich es nur überprüft und ja - es ist kaputt. Funktionierte.
Michell Bak
Ja, wie in meinem bearbeiteten ersten Beitrag erwähnt, scheint es ein Fehler in der Facebook-App zu sein, die seit April 2011 da ist (!). Trotzdem danke, dass Sie sich die Zeit genommen haben, auf meine Frage zu antworten.
Joseph Woodward
4
@ TomSusel Ja, Facebook sollte ihre Scheiße zusammenbringen. Es funktioniert jedoch, wenn eine URL eingefügt wird. Danke für die Ablehnung ;-)
Michell Bak
5

In Lollipop (21) können Sie Intent.EXTRA_REPLACEMENT_EXTRASdie Absicht für Facebook spezifisch überschreiben (und nur einen Link angeben).

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

Ich habe herausgefunden, dass Sie nur Text oder Bild teilen können , nicht beide mit Intents. Der folgende Code teilt nur Bild, falls vorhanden, oder nur Text, wenn Bild nicht beendet wird. Wenn Sie beide teilen 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, auch den Paketnamen com.facebook.lite anzugeben , bei dem es sich um den Paketnamen von Facebook Lite handelt . Ich habe nicht getestet, aber com.facebook.orca ist der Paketname von Facebook Messenger wenn Sie auch darauf abzielen möchten.

Sie können weitere Methoden zum 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();
    }
}

Verwenden Sie die folgende Klasse , um Uri aus der Datei zu erhalten:

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

Jemshit Iskenderov
quelle
4

Hier ist was ich getan habe (für Text). Im Code kopiere ich den benötigten Text in die Zwischenablage. Wenn eine Person zum ersten Mal versucht, die Schaltfläche zum Teilen von Absichten zu verwenden, wird eine Benachrichtigung angezeigt, in der erklärt wird, ob sie auf Facebook teilen möchten. Sie müssen auf "Facebook" klicken und dann lange drücken, um sie einzufügen (um sie auf Facebook aufmerksam zu machen) hat das Android Intent System gebrochen). Dann sind die relevanten Informationen im Feld. Ich könnte auch einen Link zu diesem Beitrag einfügen, damit sich Benutzer 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 für den 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);
}
easycheese
quelle
2

Scheint in Version 4.0.0 von Facebook so viele Dinge geändert zu haben. Dies ist mein Code, der gut funktioniert. 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);
    }
Hesam
quelle
1
Was ist SupportUtils?
Silvia H
2

Diese Lösung funktioniert auch. Wenn kein Facebook installiert ist, wird nur der normale Freigabedialog ausgeführt. Wenn dies der Fall ist und Sie nicht angemeldet sind, wird der Anmeldebildschirm aufgerufen. Wenn Sie angemeldet sind, wird das Freigabedialogfeld geöffnet und die "Freigabe-URL" aus dem Intent Extra eingegeben.

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);
Tommy
quelle
0

Hier ist etwas, was ich getan habe, um die Facebook-App mit Link zu ö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);
Nayanesh Gupte
quelle
2
hat bei mir nicht funktioniert. wahrscheinlich hat Facebook den Namen von ImplicitShareIntentHandler geändert.
Hesam
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)));
}
Зоран Николовски
quelle
0

Facebook erlaubt es nicht, Klartextdaten mit zu teilen, Intent.EXTRA_TEXTaber Sie können Text + Link mit Facebook Messanger teilen, dies funktioniert gut 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);
kiran boghra
quelle
0

Der einfachste Weg, eine Nachricht von meiner App an Facebook zu übergeben, bestand darin, programmgesteuert in die Zwischenablage zu kopieren und den Benutzer darauf aufmerksam zu machen, dass er die Option zum Einfügen hat. Dies erspart dem Benutzer das manuelle Ausführen. Meine App wird nicht eingefügt, aber der Benutzer könnte.

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