Android и Facebook делятся намерениями
Я разрабатываю приложение для Android и мне интересно узнать, как вы можете обновить статус пользователя приложения из приложения, используя общие намерения Android.
просмотрев SDK Facebook, кажется, что это достаточно легко сделать, однако я очень хочу, чтобы пользователь мог сделать это через обычное окно Share Intent pop up? посмотреть здесь:
Я пробовал обычный код намерения share, однако это больше не работает Фейсбук.
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 :*(
11 ответов:
приложение Facebook не обрабатывает тег
EXTRA_SUBJECT
илиEXTRA_TEXT
поля.вот ссылка на ошибку:https://developers.facebook.com/bugs/332619626816423
спасибо @billynomates:
дело в том, что если вы поместите URL в
по-видимому, Facebook больше не позволяет вам настраивать экран совместного доступа, независимо от того, открываете ли вы его sharer.PHP в URL-адресом или использование Android намерений более специализированными способами. См., например, следующие ответы:
- " Sharer.php больше не позволяет вам настраивать."
- "вы должны использовать Facebook для Android SDK или просто SDK для Facebook для Android делитесь."
в любом случае, используя простые Намерения,вы можете по-прежнему поделиться URL, но не любой текст по умолчанию с ним, а billynomates комментарием. (Кроме того, если у вас нет URL-адреса для обмена, просто запустите приложение Facebook с пустым диалогом "Написать сообщение" (т. е. обновление статуса) одинаково легко; используйте код ниже, но оставьте
EXTRA_TEXT
.)вот лучшее решение, которое я нашел, что делает не задействуйте любые SDK Facebook.
код открывает официальное приложение Facebook непосредственно если он установлен, а в противном случае возвращается к открытию sharer.PHP в браузере. (Большинство других решений в этом вопросе поднимают огромный "полное действие с помощью..." диалог что совсем не оптимально!)
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);
(относительно
com.facebook.katana
имя пакета, см. MatheusJardimB комментарий.)результат выглядит так на моем Nexus 7 (Android 4.4) с приложением Facebook установлено:
обычным способом
обычный способ создать то, что вы просите, это просто сделать следующее:
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(); }
вот что я сделал (для текста). В коде я копирую любой текст, необходимый для буфера обмена. В первый раз, когда человек пытается использовать кнопку share intent, я всплываю уведомление, которое объясняет, если они хотят поделиться с facebook, им нужно нажать "Facebook", а затем долго нажимать, чтобы вставить (это чтобы они знали, что Facebook сломал систему Android intent). Тогда соответствующая информация находится в поле. Я также могу включить ссылку на этот пост, чтобы пользователи могли жаловаться тоже...
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); }
в 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); }
я узнал, что вы можете только поделиться либо текстилиизображения, а не как с помощью
Intents
. Ниже кода акции только изображения если он существует, или только текст если изображения не выходит. Если вы хотите поделиться обоими, вам нужно использовать Facebook SDK отсюда.Если вы используете другое решение вместо кода ниже, не забудьте указать имя пакета com.фейсбук.облегченная также, который является именем пакета Facebook Lite. Я не проверял, но com.фейсбук.орка - имя пакета 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 не установлен, он просто запускает обычный share-диалог. Если есть и вы не вошли в систему, он переходит на экран входа. Если вы вошли в систему, он откроет диалоговое окно share и вставит "share url" из 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);
вот что я сделал, что открыть приложение 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);
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))); }
Кажется, в версии 4.0.0 Facebook так много вещей изменилось. Это мой код, который работает нормально. Надеюсь, это поможет вам.
/** * 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); }
Facebook не позволяет обмениваться текстовыми данными с
Intent.EXTRA_TEXT
но вы можете поделиться Текст + ссылка с facebook messanger с помощью этого, это прекрасно работает для меня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);