title: ACTION_SEND: Incorrect mime sent to WhatsApp resulting in missing Thumbnails
body: <p>My App manages a few videos and photos downloaded from a IoT device. It downloads videos &amp; photos from these devices and places them in the Apps external <code>Downloads</code> directory (retrieved with <code>context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)</code>). </p>
  
  <p>The App offers a <strong>sharing</strong> feature, which utilizes the <code>ACTION_SEND</code> intent to export a file to another application.</p>
  
  <p>I have observed different behavior with my App, based on the phones Android OS version. My test is simple: Share the same file (a single photo) to 3 different Apps: 1) WhatsApp, 2) Gmail 3) <a href="https://play.google.com/store/apps/details?id=com.camerasideas.instashot&amp;hl=en" rel="nofollow noreferrer">InShot</a>.</p>
  
  <h3>On Android 7.0, the App behavior is incomplete:</h3>
  
  <ol>
  <li>WhatsApp: Can not show image thumbnail, the file is sent as a "document".
  <a href="https://i.stack.imgur.com/7wciF.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/7wciF.png" alt="WhatsApp demonstration screenshot"></a></li>
  <li>Gmail: No problems, the file is sent passed over to Gmail correctly, including a thumbnail
  <a href="https://i.stack.imgur.com/NvKE8.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/NvKE8.png" alt="Gmail demonstration"></a></li>
  <li>InShot: Can not retrieve the file and shows a error message.
  <a href="https://i.stack.imgur.com/fHrQs.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/fHrQs.png" alt="InShot demontration"></a></li>
  </ol>
  
  <h3>On Android 8.0, everything works as expected.</h3>
  
  <ol>
  <li>WhatsApp: Shows the video or photo editor, then copies the file correctly.</li>
  <li>Gmail: No problem, as above.</li>
  <li>InShot: No problem, file can be imported.</li>
  </ol>
  
  <h2>Code</h2>
  
  <p>The App is using a <a href="https://developer.android.com/reference/android/support/v4/content/FileProvider.html" rel="nofollow noreferrer">FileProvider</a> to export the files as it's the standard on Android now.</p>
  
  <p>Support library version is <strong>27.1.0</strong>.</p>
  
  <p>The relevant code parts looks like this:</p>
  
  <h3>AndroidManifest.xml</h3>
  
  <p>Nothing special, just the default config and a link to the paths.xml. applicationId and filesAuthority placeholders are correctly replaced.</p>
  
  <pre><code>&lt;provider
      android:name="android.support.v4.content.FileProvider"
      android:authorities="${applicationId}${filesAuthority}"
      android:exported="false"
      android:grantUriPermissions="true"&gt;
      &lt;meta-data
          android:name="android.support.FILE_PROVIDER_PATHS"
          android:resource="@xml/paths"/&gt;
  &lt;/provider&gt;
  </code></pre>
  
  <h3>paths.xml</h3>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;paths&gt;
      &lt;external-files-path
          name="Download"
          path="Download"/&gt;
  &lt;/paths&gt;
  </code></pre>
  
  <h3><code>createSharingIntent(context: Context, videos: List&lt;Video&gt;): Intent</code></h3>
  
  <pre><code>var hasVideos = false
  var hasImages = false
  
  var items = emptyArray&lt;ClipData.Item&gt;()
  var contentTypes = emptyArray&lt;String&gt;()
  
  // Create ClipData items &amp; contentTypes which help to further specify the Intent contents.
  for (video in videos) {
      items += ClipData.Item(FileProvider.getUriForFile(context, BuildConfig.FILES_AUTHORITY, File(video.path)))
      contentTypes += (if (video.isJpg) IMAGE_JPG else MediaFormat.MIMETYPE_VIDEO_AVC)
  
      if (video.isJpg) {
          hasImages = true
      } else {
          hasVideos = true
      }
  }
  
  // Build the Intent
  val intent: Intent
  
  val intentType = when {
      hasImages &amp;&amp; hasVideos -&gt; "*/*"
      hasImages -&gt; IMAGE_JPG
      else -&gt; MediaFormat.MIMETYPE_VIDEO_AVC
  }
  
  intent = if (items.size &gt; 1) {
      Intent().setAction(Intent.ACTION_SEND_MULTIPLE)
              .setType(intentType)
              .putParcelableArrayListExtra(Intent.EXTRA_STREAM, ArrayList(items.map { it.uri }))
  } else {
      Intent().setAction(Intent.ACTION_SEND)
              .setDataAndTypeAndNormalize(items[0].uri, intentType)
              .putExtra(Intent.EXTRA_STREAM, items[0].uri)
  }
  
  intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION.or(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
  
  // Specify more detail in ClipData - which might be helpful for 
  val clipData = ClipData("Export", contentTypes, items[0])
  for (i in 1 until items.size) {
      clipData.addItem(items[i])
  }
  intent.clipData = clipData
  
  return intent
  </code></pre>
  
  <h3>take intent and send</h3>
  
  <pre><code>Intent intent = createSharingIntent(activity, videos)
  Intent chooser = Intent.createChooser(intent, activity.getString(R.string.share_files));
  activity.startActivity(chooser);
  </code></pre>
  
  <p>What is missing to create the same behavior - and most importantly - ensure WhatsApp and other apps can see the image properly, like Gmail?</p>