【问题标题】:Android Intent Chooser to only show E-mail optionAndroid Intent 选择器仅显示电子邮件选项
【发布时间】:2011-09-09 11:59:34
【问题描述】:

我的应用程序集成了电子邮件,用户可以直接从应用程序提交错误报告、反馈等。我使用 application/octet-stream 作为 Intent 的 SetType。当您提交电子邮件时,您会看到内容选择器,它会显示来自 Evernote、Facebook、电子邮件等的各种项目。

我怎样才能让这个选择器只显示电子邮件,以免将用户与适合内容选择器类型的所有其他项目混淆?

谢谢。

【问题讨论】:

  • 您是否添加了所有额外内容,如下所示:stackoverflow.com/questions/2197741/…
  • 是的,我确实做到了。它工作,它发送电子邮件。我只是想消除内容选择器显示的所有内容的混乱。我只想显示“电子邮件”或电子邮件相关程序。我不确定为什么会出现所有其他这些,我认为这是因为它们可以处理 application/octet-stream 类型。
  • 想必你也遇到了同样的message/rfc822问题?

标签: android android-intent xamarin.android


【解决方案1】:

要解决此问题,只需遵循官方文档即可。最重要的考虑因素是:

  1. 标志是 ACTION_SENDTO,而不是 ACTION_SEND

  2. intent的方法的setData,

    intent.setData(Uri.parse("mailto:")); // 只有电子邮件应用才能处理此问题

如果您发送一个空的Extra,最后的if() 将不起作用,应用程序将不会启动电子邮件客户端。

这对我有用。根据Android文档。如果您想确保您的意图仅由电子邮件应用程序(而不是其他短信或社交应用程序)处理,请使用 ACTION_SENDTO 操作并包含“mailto:”数据方案。例如:

public void composeEmail(String[] addresses, String subject) {
    Intent intent = new Intent(Intent.ACTION_SENDTO);
    intent.setData(Uri.parse("mailto:")); // only email apps should handle this
    intent.putExtra(Intent.EXTRA_EMAIL, addresses);
    intent.putExtra(Intent.EXTRA_SUBJECT, subject);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

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

【讨论】:

  • 对于附件问题,我很抱歉。我不确定如何实施。我想这个功能只是通过意图共享文本。
【解决方案2】:

我假设您正在使用 ACTION_SEND Intent 操作,因为您没有费心实际说明您正在使用什么,但您同意 @Aleadam 的评论。

我使用 application/octet-stream 作为 Intent 的 SetType。

这句话中没有任何内容限制电子邮件。

ACTION_SEND 是一个通用的Intent 操作,任何需要的应用程序都可以支持它。您所要做的就是指明您要共享的数据以及该数据的 MIME 类型——从那里,用户可以从可用活动中进行选择。

正如@Jasoon 所指出的,您可以尝试将message/rfc822 作为 MIME 类型。但是,这并不表示“只提供电子邮件客户端”——它表示“提供任何支持message/rfc822 数据的东西”。这可能很容易包括一些不是电子邮件客户端的应用程序。

如果您特别想通过电子邮件发送内容,请将 JavaMail 集成到您的应用程序中,或者在您的 Web 服务器上编写一个电子邮件转发脚本并调用它,等等。如果您使用ACTION_SEND,您就在暗示用户想要什么才是最重要的,并且您希望用户能够通过用户选择的任何方式发送某某数据。

【讨论】:

    【解决方案3】:

    在实现 Magic Link 功能时遇到了这个问题,这是所有已安装电子邮件应用程序的选择器意图:

    Chooser Intent Screenshot

    private void openEmailApp() {
      List<Intent> emailAppLauncherIntents = new ArrayList<>();
    
      //Intent that only email apps can handle:
      Intent emailAppIntent = new Intent(Intent.ACTION_SENDTO);
      emailAppIntent.setData(Uri.parse("mailto:"));
      emailAppIntent.putExtra(Intent.EXTRA_EMAIL, "");
      emailAppIntent.putExtra(Intent.EXTRA_SUBJECT, "");
    
      PackageManager packageManager = getPackageManager();
    
      //All installed apps that can handle email intent:
      List<ResolveInfo> emailApps = packageManager.queryIntentActivities(emailAppIntent, PackageManager.MATCH_ALL);
    
      for (ResolveInfo resolveInfo : emailApps) {
        String packageName = resolveInfo.activityInfo.packageName;
        Intent launchIntent = packageManager.getLaunchIntentForPackage(packageName);
        emailAppLauncherIntents.add(launchIntent);
      }
    
      //Create chooser
      Intent chooserIntent = Intent.createChooser(new Intent(), "Select email app:");
      chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, emailAppLauncherIntents.toArray(new Parcelable[emailAppLauncherIntents.size()]));
      startActivity(chooserIntent);
    }
    

    【讨论】:

    • 我也在实现魔术链接功能,我只想显示选择器以显示所有电子邮件客户端,然后查看收件箱。提到的大多数解决方案都是发送电子邮件。您的解决方案非常适合我的用例谢谢!
    • 我遇到了一个问题,即触发意图未获得任何电子邮件启动器应用程序。我也有 gmail 应用程序和 Outlook
    • PackageManager.MATCH_ALL 在这里可能是骗人的。我相信这将禁用操作系统自动发生的任何过滤结果(可能通过用户设置)。这可能不是你想要的。标准PackageManager.MATCH_DEFAULT_ONLY 在某些情况下可能是合适的。
    • 我一直在寻找解决此问题的方法,因为我在该主题上看到的所有其他答案都只打开了 Gmail。该解决方案也适用于让 Outlook 显示。谢谢你,互联网朋友!
    【解决方案4】:

    有一种更通用的方法可以做到这一点,适用于任何 MIME 类型。

    看到这个帖子:How to customize share intent in Android?

    【讨论】:

      【解决方案5】:

      可以将意图选择器的选择限制为几个选项。 the answer to this question 中的代码就是一个很好的例子。本质上,您必须创建一个 LabeledIntents 列表以提供给意图选择器,然后将其包含在其列表中。请注意,此解决方案不适用于排除(某些应用程序被排除,而其余应用程序保留),而是您必须选择要显示的应用程序。希望对您有所帮助!

      【讨论】:

        【解决方案6】:

        它适用于所有设备。它只会显示电子邮件应用程序

        public static void shareViaMail(Activity activity, String title, String body, String filePath) {
        
            Uri URI = Uri.parse("file://" + filePath);
            final Intent emailIntent = new Intent(Intent.ACTION_VIEW);
        
            emailIntent.setData(Uri.parse("mailto:"));
        
            emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"contact@brightsociety.com"});
        
            if (URI != null) {
                emailIntent.putExtra(Intent.EXTRA_STREAM, URI);
            }
            try {
                activity.startActivity(emailIntent);
            } catch (Exception e) {
                ((BaseActivity) activity).showToast("Gmail App is not installed");
                e.printStackTrace();
            }
        }
        

        【讨论】:

          【解决方案7】:

          Kotlin 答案

          如果您需要仅显示电子邮件应用程序,然后您想仅打开收件箱不打开新的电子邮件写作),您需要做A和B:

          A) 在您的 AndroidManifest.xml 文件中添加以下代码以用于 Android 11,因为 package visibility update of Android 11

          <queries>
              <intent>
                  <action android:name="android.intent.action.SENDTO" />
                  <data android:scheme="mailto" />
              </intent>
              <intent>
                  <action android:name="android.intent.action.CHOOSER" />
              </intent>
          </queries>
          

          B) 使用以下功能显示电子邮件选择器:

          // Show email app list.
          fun showEmailAppList() {
          
              // Email app list.
              val emailAppLauncherIntents: MutableList<Intent?> = ArrayList()
          
              // Create intent which can handle only by email apps.
              val emailAppIntent = Intent(Intent.ACTION_SENDTO)
              emailAppIntent.data = Uri.parse("mailto:")
          
              // Find from all installed apps that can handle email intent and check version. 
              val emailApps = packageManager.queryIntentActivities(
                  emailAppIntent,
                  if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) 0 else PackageManager.MATCH_ALL
              )
          
              // Collect email apps and put in intent list.
              for (resolveInfo in emailApps) {
                  val packageName = resolveInfo.activityInfo.packageName
                  val launchIntent = packageManager.getLaunchIntentForPackage(packageName)
                  emailAppLauncherIntents.add(launchIntent)
              }
          
              // Create chooser with created intent list to show email apps of device.
              val chooserIntent = Intent.createChooser(Intent(), "OPEN EMAIL APP")
              chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, emailAppLauncherIntents.toTypedArray())
              startActivity(chooserIntent)
          }
          

          结果:

          【讨论】:

          【解决方案8】:

          它适用于所有设备。它只会显示电子邮件应用程序

          public static void shareViaMail(Activity activity, String title, String body, String filePath) {
                  Uri URI = Uri.parse("file://" + filePath);
                  final Intent emailIntent = new Intent(Intent.ACTION_VIEW);
                  emailIntent.setData(Uri.parse("mailto:"));
                  emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"xyz@gmail.com"});
                  /*if you want to attach something*/
                  if (URI != null) {
                      emailIntent.putExtra(Intent.EXTRA_STREAM, URI);
                  }
                  try {
                      activity.startActivity(emailIntent);
                  } catch (Exception e) {
                      ((BaseActivity) activity).showToast("Gmail App is not installed");
                      e.printStackTrace();
                  }
          }
          

          【讨论】:

          • 这工作并在选择器中显示电子邮件应用程序,但它不会向邮件添加附件
          【解决方案9】:

          解决方法很简单:

          Intent testIntent = new Intent(Intent.ACTION_VIEW);  
          Uri data = Uri.parse("mailto:?subject=" + "blah blah subject" + "&body=" + "blah blah body" + "&to=" + "sendme@me.com");  
          testIntent.setData(data);  
          startActivity(testIntent);  
          

          见:http://www.gaanza.com/blog/email-client-intent-android/

          【讨论】:

            【解决方案10】:

            经过大量的搜索和测试,我终于找到了一个完美的解决方案。感谢开源开发者cketti 分享他/她简洁明了的解决方案。

            String mailto = "mailto:bob@example.org" +
                "?cc=" + "alice@example.com" +
                "&subject=" + Uri.encode(subject) +
                "&body=" + Uri.encode(bodyText);
            
            Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
            emailIntent.setData(Uri.parse(mailto));
            
            try {
              startActivity(emailIntent);
            } catch (ActivityNotFoundException e) {
              //TODO: Handle case where no email app is available
            }
            

            this 是指向他/她的要点的链接。

            【讨论】:

              猜你喜欢
              • 2011-04-28
              • 2010-12-20
              • 1970-01-01
              • 2016-10-23
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多