通过 Intent 为 WhatsApp、Telegram 等分享图像和 link

Sharing image and link through Intent for WhatsApp, Telegram, etc

通过在网络上搜索,我发现有不止一种方法可以通过邀请他人下载来分享我的应用程序。

我尝试了这段有效的代码,向用户显示了应用程序选择器窗格。

Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_SUBJECT, "My subject");
intent.putExtra(Intent.EXTRA_TITLE, "My subject");
intent.putExtra(Intent.EXTRA_TEXT, "https://play.google.com/store/apps/details?id=" + BuildConfig.APPLICATION_ID);
startActivity(Intent.createChooser(intent, "Share App"));

当用户选择与 WhatsApp、Telegram、SMS、电子邮件等分享消息时,为了正确显示消息,我必须在 Intent 中包含哪些信息?

例如,此代码将在 Telegram 中显示预览(带有突出显示的 link 和预览图像),但不会在 WhatsApp 中显示(它仅显示要作为消息发送的纯文本):为什么?

我也试过这段代码,但它适用于电报,但不适用于 Whatsapp(它发送的消息只有一个附件,无法用文本打开 "without title"):

Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_TITLE, "title test");
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "subject test");
String shareMessage= "message test\n\n";
shareMessage = shareMessage + "https://play.google.com/store/apps/details?id=" + BuildConfig.APPLICATION_ID +"\n\n";
shareIntent.putExtra(Intent.EXTRA_TEXT, shareMessage);
shareIntent.putExtra(Intent.EXTRA_HTML_TEXT, "HTML " + shareMessage);
Uri imageUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://"
        + res.getResourcePackageName(R.drawable.testjpg) + '/'
        + res.getResourceTypeName(R.drawable.testjpg) + '/'
        + res.getResourceEntryName(R.drawable.testjpg));
Toast.makeText(this, imageUri.toString(), Toast.LENGTH_LONG).show();
shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri);
shareIntent.setType("image/jpg");
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(shareIntent, getString(R.string.share)));

如何使其适用于 WhatsApp、Telegram、FB、电子邮件和其他纯文本(如 SMS)?

这是一个可能的答案 -

Intent waIntent = new Intent(Intent.ACTION_SEND);
waIntent.setType("text/plain");
String text = "Sorry For Interruption,I'm Just Trying Something";
waIntent.setPackage("com.whatsapp");

if (waIntent != null) {
    waIntent.putExtra(Intent.EXTRA_TEXT, text);
    waIntent.putExtra(Intent.EXTRA_SUBJECT, "My subject");
    waIntent.putExtra(Intent.EXTRA_TITLE, "My subject");
    waIntent.putExtra(Intent.EXTRA_TEXT, "https://play.google.com/store/apps/details?id=" + BuildConfig.APPLICATION_ID);
    waIntent.putExtra(Intent.EXTRA_STREAM, attachment);
    startActivity(Intent.createChooser(waIntent,"Share with"));

希望对您有所帮助!!

来源 - Sending message through WhatsApp By intent

https://developer.android.com/guide/components/intents-common#java

What information must I include in the Intent in order to correctly display the message when the user chooses to share it with WhatsApp, Telegram, SMS, email, etc.?

"correctly" 的定义取决于其他应用程序的开发者,而不是您。他们如何处理您 Intent 上的额外内容取决于他们,而不是您。他们对这些额外功能的处理方式会因应用程序、应用程序版本以及可能的 device/OS 特性而异。你无法控制这些。您只需提供数据,然后让其他应用程序的开发人员使用这些数据做他们想做的事。

this code will show a preview in Telegram (with the highlighted link and a preview image) but not in WhatsApp (it show only the plain text to send as a message): why?

因为 Telegram 和 WhatsApp 开发人员选择这样做。

I tried also this code but it works for telegram but not for whatsapp

该代码中存在各种错误:

  • 您提供的内容不属于 EXTRA_HTML_TEXT

  • 中的 HTML
  • image/jpg 不是有效的 MIME 类型(它是 image/jpeg

  • 你的Uriandroid.resource方案,不是content方案

修复这些错误是否会改变 WhatsApp 的行为取决于 WhatsApp 的开发人员,而据您所知,该行为可能会在接下来的一个小时内改变七次。因此,虽然我建议修复这些错误,但不要假设任何给定的应用程序必然会以不同的方式或以您想要的方式运行。

对我来说,以下是使用 FileProvider 的工作代码(在 Android 6.1 的真实设备上测试)。

通过使用 FileProvider 我可以允许其他应用程序读取我的图像。

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="app.example.com">
    <application
        ...>
        <activity
            ...></activity>
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="app.example.com"
            android:exported="false"
            android:grantUriPermissions="true"
            android:readPermission="app.example.com.fileprovider.READ">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
        </provider>
    </application>
</manifest>

provider_paths.xml:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-files-path name="files" path="/" />
</paths>

Activity.java:

String nomeApp = getString(R.string.app_name);
String titoloApp = getString(R.string.titolo_app);
String shareMessage = "Text message\n\n";
shareMessage = shareMessage + "https://play.google.com/store/apps/details?id=" + BuildConfig.APPLICATION_ID +"\n\n";

// use the dedicated external directory so the App doesn't need to ask for permission in manifest
File dirSaveFile = getApplicationContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES);

// create needed dirs for file path
File imagePath = new File(dirSaveFile, "external_files");
imagePath.mkdir();

// create empty file
File imageFile = new File(imagePath.getPath(), "test.jpg");

// get the Bitmap of the drawable to show
final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.testjpg);

// write in the file the drawable image
try {
    FileOutputStream fos = new FileOutputStream(imageFile);
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
    fos.flush();
    fos.close();
} catch (Exception e) {
    e.printStackTrace();
}

// create the uri
Uri uri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID, imageFile);

// create the Intent
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_TITLE, "Title test");
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "Subject test");
shareIntent.putExtra(Intent.EXTRA_TEXT, shareMessage);
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
shareIntent.setType("text/plain");

startActivity(Intent.createChooser(shareIntent, getString(R.string.share)));

注意:正如@CommonsWare 在他的回答中所说:

What they do with the extras on your Intent is up to them, not you.

因此此代码以后可能不再有效。