【问题标题】:Android Studio mailto Intent doesn't show subject and mail bodyAndroid Studio mailto Intent 不显示主题和邮件正文
【发布时间】:2020-04-06 10:28:29
【问题描述】:

我正在尝试从我的 Android 应用程序发送电子邮件。单击一个按钮,gmail 应该会打开并显示一封新电子邮件,其中包含我之前定义的收件人、主题和电子邮件正文。到目前为止,我已经尝试发送 Intent.ACTION_VIEW 以及 Intent.ACTION_SENDTO。两者都只向收件人显示我的草稿。主题和消息都被压缩了。奇怪的是在使用模拟器时,它工作得很好。还试图锁定android错误日志。好像我没有权限。这真的是权限问题还是其他问题? 我真的很感激任何帮助 干杯

这是我的代码:

  • 通过 ACTION_VIEW 发送电子邮件
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("mailto:" + to));
intent.putExtra(intent.EXTRA_SUBJECT, subject);
intent.putExtra(intent.EXTRA_TEXT, message);
mainActivity.startActivity(intent);
  • 通过 ACTION_SENDTO 发送电子邮件
Intent email = new Intent(Intent.ACTION_SENDTO);
email.setType("message/rfc822");
email.putExtra(Intent.EXTRA_EMAIL, new String[]{to});
email.putExtra(Intent.EXTRA_SUBJECT, subject);
email.putExtra(Intent.EXTRA_TEXT, message);
mainActivity.startActivity(Intent.createChooser(email, "Choose an Email client :"));
  • 来自 logcat 的错误消息
2019-12-13 01:30:35.172 29268-29268/? E//system/bin/webview_zygote32: failed to make and chown /acct/uid_99044: Permission denied
2019-12-13 01:30:35.172 29268-29268/? E/Zygote: createProcessGroup(99044, 0) failed: Permission denied
2019-12-13 01:30:35.206 29289-29289/? E/asset: setgid: Operation not permitted
2019-12-13 01:30:35.226 29296-29296/? E/asset: setgid: Operation not permitted
2019-12-13 01:30:35.355 29268-29268/? E/Typeface: Error mapping font file /system/fonts/NotoSansKhmer-Regular.ttf
2019-12-13 01:30:35.356 29268-29268/? E/Typeface: Error mapping font file /system/fonts/NotoSansKhmer-Bold.ttf
2019-12-13 01:30:35.356 29268-29268/? E/Minikin: Could not get cmap table size!
2019-12-13 01:30:35.356 29268-29268/? E/Typeface: Unable to load Family: null:und-Khmr
2019-12-13 01:30:35.484 29268-29268/? E/Typeface: Error mapping font file /system/fonts/LGAka_Light.ttf
2019-12-13 01:30:35.484 29268-29268/? E/Minikin: Could not get cmap table size!
2019-12-13 01:30:35.484 29268-29268/? E/Typeface: Unable to load Family: lg-lgaka:null
2019-12-13 01:30:35.816 29342-29342/? E//system/bin/webview_zygote32: failed to make and chown /acct/uid_99045: Permission denied
2019-12-13 01:30:35.816 29342-29342/? E/Zygote: createProcessGroup(99045, 0) failed: Permission denied
2019-12-13 01:30:35.842 29354-29354/? E/asset: setgid: Operation not permitted
2019-12-13 01:30:35.864 29367-29367/? E/asset: setgid: Operation not permitted
2019-12-13 01:30:36.139 29342-29342/? E/Typeface: Error mapping font file /system/fonts/NotoSansKhmer-Regular.ttf
2019-12-13 01:30:36.139 29342-29342/? E/Typeface: Error mapping font file /system/fonts/NotoSansKhmer-Bold.ttf
2019-12-13 01:30:36.139 29342-29342/? E/Minikin: Could not get cmap table size!
2019-12-13 01:30:36.139 29342-29342/? E/Typeface: Unable to load Family: null:und-Khmr
2019-12-13 01:30:36.362 29342-29342/? E/Typeface: Error mapping font file /system/fonts/LGAka_Light.ttf
2019-12-13 01:30:36.362 29342-29342/? E/Minikin: Could not get cmap table size!
2019-12-13 01:30:36.362 29342-29342/? E/Typeface: Unable to load Family: lg-lgaka:null
2019-12-13 01:30:36.523 4349-4359/? E/GBMv2: FPS Scaler: EXP
2019-12-13 01:30:36.602 29342-29342/? E/WebViewFactory: can't load with relro file; address space not reserved
2019-12-13 01:30:37.058 29220-29220/? E/Gmail: Gmail:EditWebView JS Console: b/119949571:draft.editor.onLoad; source: file:///android_asset/draft_editor_gmail_compiled.js at 89
2019-12-13 01:30:37.146 29220-29220/? E/Gmail: Gmail:EditWebView JS Console: b/119949571:draft.editor.onLoad is finished; source: file:///android_asset/draft_editor_gmail_compiled.js at 90

【问题讨论】:

  • ACTION_VIEWACTION_SENDTO 均未记录为支持 EXTRA_SUBJECTEXTRA_TEXT
  • 编辑到这个 setType("text/plain")

标签: java android email android-intent error-handling


【解决方案1】:

我认为我们遇到了同样的问题。 Android API 29 引入了一些关于向其他应用发送数据的改进。在此处查看更多详细信息:Sending simple data to other apps

这是适合我的解决方案。

Intent selectorIntent = new Intent(Intent.ACTION_SENDTO);
selectorIntent.setData(Uri.parse("mailto:"));

final Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{"address@mail.com"});
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "The subject");
emailIntent.putExtra(Intent.EXTRA_TEXT, "The email body");
emailIntent.setSelector( selectorIntent );

activity.startActivity(Intent.createChooser(emailIntent, "Send email..."));

简而言之,您需要使用 Android 标准应用选择器,此外,您还指定要发送电子邮件。因此,结果,电子邮件客户端只会出现。 如果用户只安装了一个电子邮件客户端,intent 将立即重定向到它。

希望这对你也有帮助。

【讨论】:

  • 最后。在它突然停止工作之前,我的代码在过去 10 到 11 年一直与 Gmail 一起使用。这样做是要走的路。 :)
  • 也为我工作。 Intent.createChooser 是可选的,emailIntent 可以直接传递。
  • 工作就像一个魅力,节省了我几分钟的时间。非常感谢
  • 它有点工作,但它要求用户选择“Gmail”,还提供“复制”和“Paypal”选项,这只会导致奇怪或没有行为
  • @pete 这是由于“ACTION_SEND”意图的广泛范围,我同意这对用户来说有点混乱。我没有尝试过,但我相信您可以在 extras 中指定 MIME 数据类型,这应该会进一步过滤显示的应用列表。
【解决方案2】:

试试这个代码,它对我有用。

Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:")); // only email apps should handle this
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{email});
intent.putExtra(Intent.EXTRA_SUBJECT, "Subject here");
intent.putExtra(Intent.EXTRA_TEXT,"Body Here");
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(intent);
}

还在 android manifest 中添加意图过滤器。

<activity ...>
<intent-filter>
    <action android:name="android.intent.action.SENDTO" />
    <data android:scheme="mailto" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

【讨论】:

  • 您能否对答案添加一些解释?
  • 非常感谢,我什至可以选择使用一个电子邮件客户端作为标准。必须将意图过滤器标签放在服务标签内,并将 MainActivity 作为名称。所以看起来像这样:&lt;service android:name="MainActivity"&gt;
  • 它仍然没有显示主题和正文!
【解决方案3】:

为了让它在三星和 Pixel 设备上运行,我们必须在 url 附加参数上添加参数

val email = "xxxx@xxxx.com"
val subject = "xxxx"
val body = "xxxx"

val selectorIntent = Intent(Intent.ACTION_SENDTO)
val urlString = "mailto:" + Uri.encode(email) + "?subject=" + Uri.encode(subject) + "&body=" + Uri.encode(body)
selectorIntent.data = Uri.parse(urlString)

val emailIntent = Intent(Intent.ACTION_SEND)
emailIntent.putExtra(Intent.EXTRA_EMAIL, arrayOf(email))
emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject)
emailIntent.putExtra(Intent.EXTRA_TEXT, body)
emailIntent.selector = selectorIntent

startActivity(Intent.createChooser(emailIntent, "Send email"))

【讨论】:

    【解决方案4】:

    我们用于电子邮件的旧代码几天前就停止工作了。

    是这样的:

    public static void shareTextToEmail(Context context, String[] email, String subject, String text)
        Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:" + TextUtils.join(",", email)));
        emailIntent.putExtra(Intent.EXTRA_EMAIL, email);
        emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
        emailIntent.putExtra(Intent.EXTRA_TEXT, text);
        try {
            context.startActivity(Intent.createChooser(emailIntent, context.getString(R.string.share_email_title)));
        } catch (android.content.ActivityNotFoundException e) {
            Toast.makeText(context, context.getString(R.string.share_no_intent_handler_found), Toast.LENGTH_SHORT).show();
        }
    }
    

    我根据 Zak.Antonio 的回答采用了它:

    public static void shareTextToEmail(Context context, String[] email, String subject, String text)
        Intent selectorIntent = new Intent(Intent.ACTION_SENDTO);
        selectorIntent.setData(Uri.parse("mailto:"));
    
        final Intent emailIntent = new Intent(Intent.ACTION_SEND);
        emailIntent.putExtra(Intent.EXTRA_EMAIL, email);
        emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
        emailIntent.putExtra(Intent.EXTRA_TEXT, text);
        emailIntent.setSelector(selectorIntent);
    
        try {
            context.startActivity(Intent.createChooser(emailIntent, context.getString(R.string.share_email_title)));
        } catch (android.content.ActivityNotFoundException e) {
            Toast.makeText(context, context.getString(R.string.share_no_intent_handler_found), Toast.LENGTH_SHORT).show();
        }
    }
    

    重点是:

    • emailIntent 中将Intent.ACTION_SENDTO 替换为Intent.ACTION_SEND
    • Intent.ACTION_SENDTO 移动到selectorIntent
    • 不要将电子邮件放在意图数据中,仅将它们放在附加信息中 Intent.EXTRA_EMAIL

    【讨论】:

    • 我也像您的回答一样解决了这个问题。其他答案不好。
    • 这个例子仍然对我不起作用,直到我将电子邮件“收件人”地址放入数组中,就像其他答案一样。 (我在 Pixel、Android 10 上进行测试)。否则,这个例子也很棒。
    • @gjgjgj 变量email在示例中为String[]
    【解决方案5】:

    这个答案对我使用 Uri 进行解析对我有用

    Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:?subject=" + subject + "&to=" + to));
     context.startActivity(emailIntent);
    

    【讨论】:

      【解决方案6】:

      试试这个代码

          val emailIntent = Intent(Intent.ACTION_SEND)
          emailIntent.setType("text/plain")
          emailIntent.putExtra(Intent.EXTRA_EMAIL, arrayOf("jon@example.com")) 
          emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject")
          emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text")
          val packageManager = packageManager
          val activities = packageManager.queryIntentActivities(emailIntent, 0)
          val isIntentSafe = activities.size > 0
          if (isIntentSafe) {
              startActivity(emailIntent);
          }else{
              Log.d("MainActivty","Email App not installed");
          }
      

      【讨论】:

      • 这是什么语言?我试过把它翻译成Java,但我不知道packageManager和activity是什么类型的变量
      • 这是 Kotlin。 packageManager 的类型为 android.content.pm.PackageManager
      【解决方案7】:

      在运行 Android 10 的三星上似乎既不能向 SENDTO 意图添加 Extras,也不能使用 selectorIntent。对电子邮件地址、主题和正文进行编码的 Uri 似乎在运行 Android 10 及更低版本的多台设备上效果最佳。 EmailIntentLibrary 对解决使 URI 编码适用于复杂正文内容的细节有很大帮助。

      val email = Uri.encode("xxxx@xxxx.com")
      val subject = Uri.encode("xxxx")
      val body = Uri.encode("some body. one two & more. \n new line \n &%>?")
      val uri = "mailto:$email?subject=$subject&body=$body"
      val intent = Intent(Intent.ACTION_SENDTO)
      intent.type = "text/plain"
      intent.data = Uri.parse(uri)
      startActivity(intent)
      

      如果您对在选择器中有很多选项感到满意,下面来自 Android Development Guide 的示例确实有效(用于过滤这些选项的 ACTION_SENDTO 示例对我不起作用)

      fun composeEmail(addresses: Array<String>, subject: String, attachment: Uri) {
          val intent = Intent(Intent.ACTION_SEND).apply {
              type = "*/*"
              putExtra(Intent.EXTRA_EMAIL, addresses)
              putExtra(Intent.EXTRA_SUBJECT, subject)
              putExtra(Intent.EXTRA_STREAM, attachment)
          }
          if (intent.resolveActivity(packageManager) != null) {
              startActivity(intent)
          }
      }
      

      【讨论】:

        【解决方案8】:

        如果您的应用面向 Android 11(API 级别 30)或更高版本,那么我们需要添加:

        像这样在 Manifest 中设置queries

        <manifest package="com.example.app">
            ...
            <!-- Package visibility -->
            <queries>
                <!-- Mail -->
                <intent>
                    <action android:name="android.intent.action.SENDTO" />
                    <data android:scheme="mailto" />
                    <category android:name="android.intent.category.DEFAULT" />
                </intent>
            </queries>
            ...
        </manifest>
        

        Kotlin 方法打开电子邮件应用程序:

        fun composeEmail(recipient: String, subject: String, body: String) {
            val selectorIntent = Intent(Intent.ACTION_SENDTO).apply{
                data = Uri.parse("mailto:") // only email apps should handle this
            }
            val emailIntent = Intent(Intent.ACTION_SEND).apply {
                putExtra(Intent.EXTRA_EMAIL, arrayOf(recipient))
                putExtra(Intent.EXTRA_SUBJECT, subject)
                putExtra(Intent.EXTRA_TEXT, body)
                selector = selectorIntent
            }
            if (emailIntent.resolveActivity(packageManager) != null) {
                startActivity(emailIntent)
            }
        }
        

        【讨论】:

        • 事实上,AndroidManifest.xml 中的查询标签,就像你的例子一样,是 API 30+ 唯一缺少的东西。用于打开电子邮件应用程序的意图甚至不需要更改。我使用与 API 29 相同的代码。所以查询标签是正确的解决方法。
        【解决方案9】:

        非常感谢,在我没有使用选择器意图之前,唯一对我有用的针对 Android 31 的解决方案;)谢谢

        【讨论】:

          猜你喜欢
          • 2021-04-03
          • 2021-10-08
          • 1970-01-01
          • 1970-01-01
          • 2019-01-08
          • 2021-12-23
          • 2015-01-30
          • 1970-01-01
          相关资源
          最近更新 更多