Repository: square/leakcanary
File: leakcanary-android-core/src/main/java/leakcanary/internal/activity/LeakViews.kt (Kotlin)

Code before:
private fun View.startShareIntentChooser(uri: Uri) {
  val intent = Intent(Intent.ACTION_SEND)
  intent.type = "application/octet-stream"
  intent.putExtra(Intent.EXTRA_STREAM, uri)
  activity.startActivity(
      Intent.createChooser(intent, resources.getString(R.string.leak_canary_share_with))
  )
}

internal fun View.shareToStackOverflow(content: String) {
  val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
  // AsyncTask was needed here due to setPrimaryClip making a disk write which
  // violated StrictMode if on the main thread
  AsyncTask.execute {
    clipboard.setPrimaryClip(
        ClipData.newPlainText(
            context.getString(R.string.leak_canary_leak_clipdata_label),
            "```\n$content```"
        )
    )
  }
  Toast.makeText(context, R.string.leak_canary_leak_copied, Toast.LENGTH_LONG)
      .show()
  val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(STACKOVERFLOW_QUESTION_URL))
  try {
    activity.startActivity(browserIntent)
  } catch (e: ActivityNotFoundException) {
    Toast.makeText(context, e.toString(), Toast.LENGTH_LONG).show();
  }
}

internal fun View.shareToGitHubIssue(failure: HeapAnalysisFailure) {
  val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
  // AsyncTask was needed here due to setPrimaryClip making a disk write which
  // violated StrictMode if on the main thread
  AsyncTask.execute {
    clipboard.setPrimaryClip(
        ClipData.newPlainText(
            context.getString(R.string.leak_canary_failure_clipdata_label),
            """```
          |${failure.exception}
          |Build.VERSION.SDK_INT: ${Build.VERSION.SDK_INT}
          |Build.MANUFACTURER: ${Build.MANUFACTURER}
          |LeakCanary version: ${BuildConfig.LIBRARY_VERSION}
          |Analysis duration: ${failure.analysisDurationMillis} ms
          |Heap dump file path: ${failure.heapDumpFile.absolutePath}
          |Heap dump timestamp: ${failure.createdAtTimeMillis}
          |```
        """.trimMargin()
        )
    )

Review comment (suggestion):
AFAIK a correct way to handle this is by resolving activity:
https://developer.android.com/guide/components/intents-filters#ExampleSend

I'm curious, what kind of device you're testing on that doesn't have a browser? It's not an impossible scenario, but just strange not to have even built-in browser :) 

Code after:
private fun View.startShareIntentChooser(uri: Uri) {
  val intent = Intent(Intent.ACTION_SEND)
  intent.type = "application/octet-stream"
  intent.putExtra(Intent.EXTRA_STREAM, uri)
  activity.startActivity(
      Intent.createChooser(intent, resources.getString(R.string.leak_canary_share_with))
  )
}

internal fun View.shareToStackOverflow(content: String) {
  val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
  // AsyncTask was needed here due to setPrimaryClip making a disk write which
  // violated StrictMode if on the main thread
  AsyncTask.execute {
    clipboard.setPrimaryClip(
        ClipData.newPlainText(
            context.getString(R.string.leak_canary_leak_clipdata_label),
            "```\n$content```"
        )
    )
  }
  Toast.makeText(context, R.string.leak_canary_leak_copied, Toast.LENGTH_LONG)
      .show()
  val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(STACKOVERFLOW_QUESTION_URL))
  try {
    activity.startActivity(browserIntent)
  } catch (e: ActivityNotFoundException) {
    Toast.makeText(context, R.string.leak_canary_leak_missing_browser_error, Toast.LENGTH_LONG)
            .show();
  }
}

internal fun View.shareToGitHubIssue(failure: HeapAnalysisFailure) {
  val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
  // AsyncTask was needed here due to setPrimaryClip making a disk write which
  // violated StrictMode if on the main thread
  AsyncTask.execute {
    clipboard.setPrimaryClip(
        ClipData.newPlainText(
            context.getString(R.string.leak_canary_failure_clipdata_label),
            """```
          |${failure.exception}
          |Build.VERSION.SDK_INT: ${Build.VERSION.SDK_INT}
          |Build.MANUFACTURER: ${Build.MANUFACTURER}
          |LeakCanary version: ${BuildConfig.LIBRARY_VERSION}
          |Analysis duration: ${failure.analysisDurationMillis} ms
          |Heap dump file path: ${failure.heapDumpFile.absolutePath}
          |Heap dump timestamp: ${failure.createdAtTimeMillis}
          |```
        """.trimMargin()
        )