Rozwijam aplikację na Androida i interesuje mnie, jak możesz zaktualizować stan użytkownika aplikacji z poziomu aplikacji, korzystając z funkcji udostępniania Androida.
Po przejrzeniu pakietu SDK Facebooka wydaje się, że jest to dość łatwe do zrobienia, jednak chciałbym, aby użytkownik mógł to zrobić za pośrednictwem zwykłego wyskakującego okienka zamiaru udostępniania? zobacz tutaj:
Wypróbowałem zwykły kod zamiaru udostępniania, jednak wydaje się, że nie działa to już na Facebooku.
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)));
}
AKTUALIZACJA: Po dalszych kopaniu wygląda na to, że jest to błąd w aplikacji Facebooka, który nie został jeszcze rozwiązany! ( błąd na Facebooku ) W międzyczasie wygląda na to, że będę musiał po prostu znosić negatywne stwierdzenie: „Udostępnianie nie działa !!!” recenzje. Pozdrawiam Facebook: * (
źródło
Odpowiedzi:
Oto link do błędu: https://developers.facebook.com/bugs/332619626816423
Dzięki @billynomates:
źródło
Najwyraźniej Facebook nie pozwala już (od 2014 roku) dostosowywać ekranu udostępniania, bez względu na to, czy po prostu otwierasz adres URL sharer.php, czy używasz intencji Androida w bardziej wyspecjalizowany sposób. Zobacz na przykład te odpowiedzi:
W każdym razie, za pomocą zwykłego konwersji kolorów ty możesz nadal udostępniać URL, ale nie każdy domyślny tekst z nim , jak billynomates skomentował . (Ponadto, jeśli nie masz adresu URL do udostępnienia, samo uruchomienie aplikacji Facebook z pustym oknem dialogowym „Napisz post” (tj. Aktualizacja statusu) jest równie łatwe; użyj poniższego kodu, ale pomiń
EXTRA_TEXT
).Oto najlepsze rozwiązanie, które znalazłem, które nie wymaga użycia żadnych zestawów SDK Facebooka.
Ten kod otwiera oficjalną aplikację Facebooka bezpośrednio, jeśli jest zainstalowana, a poza tym powraca do otwierania sharer.php w przeglądarce. (Większość innych rozwiązań w tym pytaniu powoduje wyświetlenie ogromnego okna dialogowego „Ukończ akcję, używając…”, które wcale nie jest optymalne!)
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);
(Jeśli chodzi o
com.facebook.katana
nazwę pakietu, zobacz komentarz MatheusJardimB ).Wynik wygląda następująco na moim Nexusie 7 (Android 4.4) z zainstalowaną aplikacją Facebook:
źródło
com.facebook
prefiksu.Zwykły sposób
Zwykłym sposobem tworzenia tego, o co prosisz, jest po prostu wykonanie następujących czynności:
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"));
To działa bez żadnych problemów dla mnie.
Alternatywny sposób (może)
Potencjalny problem polega na tym, że pozwalasz również na wysyłanie wiadomości e-mailem, SMS-em itp. Poniższy kod jest czymś, czego używam w aplikacji, co pozwala użytkownikowi wysłać mi e -mail za pomocą Gmaila. Domyślam się, że możesz spróbować to zmienić, aby działało tylko z Facebookiem.
Nie jestem pewien, jak reaguje na jakiekolwiek błędy lub wyjątki (zgaduję, że wystąpiłoby to, gdyby Facebook nie był zainstalowany), więc być może będziesz musiał go trochę przetestować.
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(); }
źródło
W Lollipop (21) możesz użyć,
Intent.EXTRA_REPLACEMENT_EXTRAS
aby zastąpić zamiar specjalnie dla Facebooka (i podać tylko link)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); }
źródło
Dowiedziałem się, że możesz udostępniać tylko tekst lub obraz , a nie oba za pomocą
Intents
. Poniższy kod udostępnia tylko obraz, jeśli istnieje, lub tylko tekst, jeśli obraz nie jest zamykany. Jeśli chcesz udostępnić oba, musisz tutaj użyć Facebook SDK.Jeśli używasz innego rozwiązania zamiast poniższego kodu, nie zapomnij również podać nazwy pakietu com.facebook.lite , która jest nazwą pakietu Facebook Lite . Nie testowałem, ale com.facebook.orca to nazwa pakietu programu Facebook Messenger, jeśli chcesz kierować również na to.
Możesz dodać więcej metod udostępniania w WhatsApp , Twitterze ...
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(); } }
Aby uzyskać Uri z pliku, użyj poniższej klasy:
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; } }
Aby napisać FileProvider , użyj tego linku: https://github.com/codepath/android_guides/wiki/Sharing-Content-with-Intents
źródło
Oto, co zrobiłem (w przypadku tekstu). W kodzie kopiuję dowolny tekst do schowka. Za pierwszym razem, gdy dana osoba próbuje użyć przycisku zamiaru udostępniania, wyskakuję powiadomienie, które wyjaśnia, czy chce udostępnić na Facebooku, musi kliknąć `` Facebook '', a następnie długo nacisnąć, aby wkleić (ma to na celu uświadomienie im, że Facebook ZNISZCZYŁA system intencji Androida). Następnie odpowiednie informacje są w terenie. Mogę również dołączyć link do tego posta, aby użytkownicy również mogli narzekać ...
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); } }
Poniżej znajduje się metoda radzenia sobie z poprzednimi wersjami
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); }
źródło
Wygląda na to, że w wersji 4.0.0 Facebooka zmieniło się tak wiele rzeczy. To jest mój kod, który działa dobrze. Mam nadzieję, że ci to pomoże.
/** * 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); }
źródło
To rozwiązanie działa również. Jeśli nie ma zainstalowanego Facebooka, po prostu uruchamia normalne okno dialogowe udostępniania. Jeśli jest i nie jesteś zalogowany, przechodzi do ekranu logowania. Jeśli jesteś zalogowany, otworzy się okno udostępniania i umieści „Udostępnij url” z Intent Extra.
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);
źródło
Oto coś, co zrobiłem, otwierając aplikację Facebook z łączem
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);
źródło
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))); }
źródło
Facebook nie zezwala na udostępnianie zwykłych danych tekstowych,
Intent.EXTRA_TEXT
ale możesz udostępniać tekst + link za pomocą komunikatora na Facebooku, to działa dobrze dla mnieIntent 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);
źródło
Najłatwiejszym sposobem przekazania wiadomości z mojej aplikacji do Facebooka było programowe skopiowanie do schowka i ostrzeżenie użytkownika, że ma możliwość wklejenia. Chroni użytkownika przed ręcznym wykonaniem tego; moja aplikacja nie wkleja się, ale użytkownik może.
... 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); ...
źródło