Я разрабатываю приложение для Android, и мне интересно узнать, как можно обновить статус пользователя приложения из приложения, используя намерения общего доступа Android.
Посмотрев SDK Facebook, оказалось, что это достаточно легко сделать, однако я хочу, чтобы пользователь мог делать это через обычное всплывающее окно Share Intent? видно здесь:
Я пробовал обычный код намерения поделиться, но, похоже, он больше не работает для 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 ) А пока похоже, что мне просто придется смириться с негативом «Обмен не работает !!!» обзоры. Приветствую Facebook: * (
android
facebook
android-intent
Джозеф Вудворд
источник
источник
Ответы:
Вот ссылка на ошибку: https://developers.facebook.com/bugs/332619626816423
Спасибо @billynomates:
источник
По-видимому, Facebook больше (по состоянию на 2014 год) не позволяет настраивать экран совместного использования, независимо от того, открываете ли вы URL-адрес sharer.php или используете намерения Android более специализированными способами. См., Например, эти ответы:
В любом случае, используя простые намерения, вы все равно можете поделиться с ним URL-адресом, но не текстом по умолчанию , как прокомментировали billynomates . (Кроме того, если у вас нет URL-адреса, которым можно поделиться, просто запустить приложение Facebook с пустым диалоговым окном «Написать сообщение» (т.е. обновление статуса) также легко; используйте приведенный ниже код, но оставьте его
EXTRA_TEXT
.)Вот лучшее решение, которое я нашел, не требующее использования каких-либо SDK для Facebook.
Этот код открывает официальное приложение 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 .)Результат выглядит следующим образом на моем Nexus 7 (Android 4.4) с установленным приложением Facebook:
источник
com.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 и т. Д. Следующий код - это то, что я использую в приложении, которое позволяет пользователю отправлять мне электронные письма. -mail через 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(); }
источник
Я обнаружил, что вы можете делиться только текстом или изображением , но не обоими
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 сломал систему намерений Android). Тогда соответствующая информация находится в поле. Я мог бы также добавить ссылку на этот пост, чтобы пользователи тоже могли жаловаться ...
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); }
источник
Кажется, в версии 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 не установлен, он просто запускает обычный диалог обмена. Если есть, и вы не вошли в систему, он переходит на экран входа в систему. Если вы вошли в систему, он откроет диалоговое окно общего доступа и вставит «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))); }
источник
Facebook не позволяет обмениваться данными в виде обычного текста,
Intent.EXTRA_TEXT
но вы можете поделиться текстом + ссылкой с помощью этого мессенджера facebook, это отлично работает для меня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);
источник
Самый простой способ передать сообщение из моего приложения в Facebook - это программно скопировать его в буфер обмена и предупредить пользователя, что у него есть возможность вставить. Это избавляет пользователя от необходимости делать это вручную; мое приложение не вставляется, но пользователь может.
... 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); ...
источник