Creating Explicit Intents at Runtime

You used an implicit intent to gather the desired activities and present them in a list. The next step is to start the selected activity when the user presses its list item. You will start the activity using an explicit intent.

To create the explicit intent, you need to get the activity’s package name and class name from the ResolveInfo. You can get this data from a part of the ResolveInfo called ActivityInfo. (You can learn what data is available in different parts of ResolveInfo from its reference page: developer.android.com/​reference/​kotlin/​android/​content/​pm/​ResolveInfo.html)

Update ActivityHolder to implement a click listener. When an activity in the list is pressed, use the ActivityInfo for that activity to create an explicit intent. Then use that explicit intent to launch the selected activity.

Listing 23.8  Launching a pressed activity (NerdLauncherActivity.kt)

class NerdLauncherActivity : AppCompatActivity() {
    ...
    private class ActivityHolder(itemView: View) :
            RecyclerView.ViewHolder(itemView),
            View.OnClickListener {

        private val nameTextView = itemView as TextView
        private lateinit var resolveInfo: ResolveInfo

        init {
            nameTextView.setOnClickListener(this)
        }

        fun bindActivity(resolveInfo: ResolveInfo) {
            ...
        }

        override fun onClick(view: View) {
            val activityInfo = resolveInfo.activityInfo

            val intent = Intent(Intent.ACTION_MAIN).apply {
                setClassName(activityInfo.applicationInfo.packageName,
                    activityInfo.name)
            }

            val context = view.context
            context.startActivity(intent)
        }
    }
    ...
}

Notice that in this intent you are sending an action as part of an explicit intent. Most apps will behave the same whether you include the action or not. However, some may change their behavior. The same activity can display different interfaces depending on how it is started. As a programmer, it is best to declare your intentions clearly and let the activities you start do what they will.

In Listing 23.8, you get the package name and class name from the metadata and use them to create an explicit intent using the Intent function:

    fun setClassName(packageName: String, className: String): Intent

This is different from how you have created explicit intents in the past. Before, you used an Intent constructor that accepts a Context and a Class object:

    Intent(packageContext: Context, cls: Class<?>)

This constructor uses its parameters to get what the Intent really needs – a ComponentName. A ComponentName is a package name and a class name stuck together. When you pass in an Activity and a Class to create an Intent, the constructor determines the fully qualified package name from the Activity.

    fun setComponent(component: ComponentName): Intent

However, it is less code to use setClassName(…), which creates the component name behind the scenes.

Run NerdLauncher and launch some apps.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
54.152.216.170