Skip to content
Nate Ebel edited this page Jul 22, 2022 · 6 revisions

πŸ–₯ Lab 17: Using Explicit and Implicit Intents

In this lab, we'll gain familiarity using Android's Intent system to perform various actions.

  • We'll review an "explicit intent" to show the TwitterActivity
  • We'll use an "implicit intent" to send a tweet
  • We'll use another implicit intent to select an image and save it as part of a Note

Β 

πŸ“ Objectives

Β 

πŸ“ Explicit & Implicit Intents

  1. Review navigation to TwitterActivity via explicit intent

    1. How are we creating the intent?
    2. What makes this intent "explicit" vs "implicit"?
    3. How do we use the Intent to actually show the TwitterActivity?
  2. When TwitterActivity opens, launch an Implicit Intent to send a Tweet (see hints)

Β 

πŸ“ Image Selection

We're going to add support for selecting an image to go along with our Note.

  1. Add an ImageView to fragment_create_note.xml

    1. This ImageView will show a selected image if/when one is selected
    2. This ImageView can be laid out anywhere you want within fragment_create_note.xml; just as long as it's visible
  2. Use an implicit Intent to select an image

    1. Within CreateNoteFragment, add a click handler for your newly added ImageView
    2. When the ImageView is clicked, create an Intent for selecting an image (see hints).
  3. Respond to image selection results

    1. Override CreateNoteFragment.onActivityResult() to respond to the selected image URI
    2. Check that the requestCode matches the request used in startActivityForResult(). This ensures we're only handling results for things we requested.
    3. Check that the resultCode == Activity.RESULT_OK. This ensures the selection didn't fail and that our desired data should be available.
    4. If both codes look correct, access the selected image URI by calling data.data
  4. Display the selected image

    1. Using the image data provided by data.data, call binding.imageView?.setImageURI(data.data) to display the image
  5. Save the selected Image URI as part of the Note

    1. When a Note is saved, it should include the selected URI if one exists
    2. Add val imageUri: String? = null to your Note model to store this data
    3. This is a database schema change, and will require either uninstalling/reinstalling your app, or providing a database migration (outside the scope of this lab).

Β 

✨ Challenges

Update UI to display selected image

  1. Update NoteDetailFragment UI to display the selected image
  2. Change the scaleType on your ImageView so that the aspect ratio is not changed when the image URI is set

Handling selection errors

Display feedback to the user if the "select photo" Intent returns a result other than Activity.RESULT_OK

Β 

πŸ–₯ Lab 17 Hints: Using Explicit and Implicit Intents

Β 

πŸ’‘ Helpful Resources

Β 

πŸ’‘ How do I send a Tweet with an Implicit Intent?

To do this, we need two things:

  1. We need an Intent with the action Intent.ACTION_VIEW
  2. We need a valid Twitter url to resolve

https://twitter.com/intent/tweet?text=%s

private fun createTweetIntent(): Intent {
    // Create intent using ACTION_VIEW and a normal Twitter url:
    val tweetUrl = String.format(
      "https://twitter.com/intent/tweet?text=%s",
      URLEncoder.encode("I'm learning a lot about #androiddev today!", "UTF-8")
    )
    return Intent(Intent.ACTION_VIEW, Uri.parse(tweetUrl))
}

Β 

πŸ’‘ How to send a Share Intent?

There are many ways to do this; depending on how general or specific your want to be.

You can customize your message for emails, text messages, note apps, etc.

For a general Share Intent that could send a text or an email, we can use something like the following:

private fun sendShareIntent() {
    val intent = Intent(Intent.ACTION_SEND).apply {
      type = "text/plain"
      putExtra(Intent.EXTRA_SUBJECT, "Android Bootcamp w/ Kotlin")
      putExtra(Intent.EXTRA_TEXT, "I'm learning a lot about Android development today!!")
    }
    startActivity(intent)
}

Β 

πŸ’‘ How to send an Intent to select an image?

There are a lot of different ways to accomplish this. Try the following

private fun selectImage() {
    val intent = Intent().apply {
      type = "image/*"
      action = Intent.ACTION_OPEN_DOCUMENT
    }
    startActivityForResult(Intent.createChooser(intent, "Select Picture"), REQUEST_CHOOSE_IMAGE)
  }

Β 

πŸ’‘ How do I get the selected image URI

If we launch an "image selection" Intent using startActivityForResult(), then we can respond to the returned result by overriding onActivityResult().

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if(requestCode != REQUEST_CHOOSE_IMAGE || resultCode == Activity.RESULT_CANCELED) return

    if (resultCode == Activity.RESULT_OK && data != null) {
      // these 3 lines ensure our app has permissions to access/use this file in the future; beyond just this selection
      // this is needed due to more restrictive permissions changes in recent versions of Android
      val contentResolver = requireContext().contentResolver
      val takeFlags: Int = Intent.FLAG_GRANT_READ_URI_PERMISSION 
      contentResolver.takePersistableUriPermission(data.data!!, takeFlags)

      // hold on to the reference to the URI so we can save it later
      uriToImage = data.data.toString()
      binding.imageView?.setImageURI(data.data)
    }
  }

Β 

πŸ’‘ How to show a local image URI in an ImageView?

ImageView has a method specifically for this.

Locate the URI to an image in the local filesystem, and call ImageView.setImageURI()

Clone this wiki locally