Blog Infos
Author
Published
Topics
,
Published
Problem Statement

We have data that we want to share with other applications using the Intent. The data can be text or a web URL.

  • SMS
  • Web URL
Solutions

I’ll discuss three different approaches to solve the above problem and discuss the pros and cons of each one of them.

  • Start the activity with the intent
fun shareSimpleText(context: Context, text: String) {
val intent = ShareCompat.IntentBuilder(context)
.setType("text/plain")
.setText(text)
.intent
val intentWithChooser = Intent.createChooser(intent, "Sharing with")
context.startActivity(intentWithChooser)
}
fun shareViaSms(context: Context, sms: Sms) {
val intent = Intent().apply {
action = Intent.ACTION_VIEW
data = Uri.parse("sms: ${sms.phoneNumber}")
putExtra("sms_body", sms.body)
}
val intentWithChooser = Intent.createChooser(intent, "Sharing with")
context.startActivity(intentWithChooser)
}
fun openWebPage(context: Context, url: String) {
val intent = Intent().apply {
action = Intent.ACTION_VIEW
data = url.toUri()
}
val intentWithChooser = Intent.createChooser(intent, "Open url using")
context.startActivity(intentWithChooser)
}
  • Create the intent
  • Start the activity with the intent
sealed class SharingType {
data class Default(val text: String) : SharingType()
data class SmsType(val sms: Sms) : SharingType()
data class WebBrowserType(val url: String) : SharingType()
}
view raw SharingType.kt hosted with ❤ by GitHub

Now create a factory method to get the intent object using the sharing type.

class SharingIntentFactory {
fun prepareIntent(context: Context, sharingType: SharingType): Intent {
return when (sharingType) {
is SharingType.Default -> {
ShareCompat.IntentBuilder(context)
.setType("text/plain")
.setText(sharingType.text)
.intent
}
is SharingType.SmsType -> {
Intent().apply {
action = Intent.ACTION_VIEW
data = Uri.parse("sms: ${sharingType.sms.phoneNumber}")
putExtra("sms_body", sharingType.sms.body)
}
}
is SharingType.WebBrowserType -> {
Intent().apply {
action = Intent.ACTION_VIEW
data = sharingType.url.toUri()
}
}
}
}
}
fun startActivity(context: Context, intent: Intent, chooserTitle: String) {
val intentWithChooser = Intent.createChooser(intent, chooserTitle)
context.startActivity(intentWithChooser)
}

phew, all the preparations for this approach are done, now we have to implement it.

val sharingIntentFactory = SharingIntentFactory()
fun shareViaSms(context: Context, sms: Sms) {
val sharingType = SharingType.SmsType(sms)
val intent = sharingIntentFactory.prepareIntent(context, sharingType)
startActivity(context, intent, "Sharing with")
}
fun shareSimpleText(context: Context, text: String) {
val sharingType = SharingType.Default(text)
val intent = sharingIntentFactory.prepareIntent(context, sharingType)
startActivity(context, intent, "Sharing with")
}
fun openWebPage(context: Context, url: String) {
val sharingType = SharingType.WebBrowserType(url)
val intent = sharingIntentFactory.prepareIntent(context, sharingType)
startActivity(context, intent, "Open url using")
}

Job Offers

Job Offers


    Android Build Engineer

    Pinterest
    San Francisco, CA | Seattle, WA
    • Full Time
    apply now

    Android Developer

    Small and Modern GmbH
    Hamburg, Remote (Germany)
    • Full Time
    apply now

    Senior Android Developer (Remote)

    Komoot
    Europe
    • Full Time
    apply now
Load more listings

OUR VIDEO RECOMMENDATION

,

Leveling Up Your Tests

We all know about TDD and Unit Testing, and even screenshot testing, but sometimes we do not need to embrace a new paradigm to make our tests better. These are several techniques I have adopted…
Watch Video

Leveling Up Your Tests

Jobs

  • We have intent types in a sealed class
  • Define the concrete intent type class.
  • Create the intent
  • Start the activity with the intent
interface SharingIntent {
val intentChooserTitle: String
fun prepareIntent(): Intent
}
class DefaultSharingIntent(
private val context: Context,
private val body: String,
chooserTitle: String = "Share using",
) : SharingIntent {
override val intentChooserTitle: String = chooserTitle
override fun prepareIntent(): Intent {
return ShareCompat.IntentBuilder(context)
.setType("text/plain")
.setText(body)
.intent
}
}
class SmsSharingIntent(
private val sms: Sms,
chooserTitle: String = "Please select app to send SMS with",
) : SharingIntent {
override val intentChooserTitle: String = chooserTitle
override fun prepareIntent(): Intent = Intent().apply {
action = Intent.ACTION_VIEW
data = Uri.parse("sms: ${sms.phoneNumber}")
putExtra("sms_body", sms.body)
}
}

Web URL

class WebBrowserSharingIntent(
private val url: String,
chooserTitle: String = "Please select the web browser",
) : SharingIntent {
override val intentChooserTitle: String = chooserTitle
override fun prepareIntent(): Intent {
return Intent().apply {
action = Intent.ACTION_VIEW
data = url.toUri()
}
}
}
fun shareIntent(context: Context, sharingIntent: SharingIntent) {
val intent = sharingIntent.prepareIntent()
val shareIntent = Intent.createChooser(intent, sharingIntent.intentChooserTitle)
context.startActivity(shareIntent)
}

Lastly, we have to create the instances of the concrete implementation and start the activity.

fun shareViaSms(context: Context, sms: Sms) {
val chooserTitle = "Sharing with"
val smsSharingIntent = SmsSharingIntent(sms, chooserTitle)
shareIntent(context, smsSharingIntent)
}
fun shareSimpleText(context: Context, text: String) {
val chooserTitle = "Sharing with"
val textSharingIntent = DefaultSharingIntent(context, text, chooserTitle)
shareIntent(context, textSharingIntent)
}
fun openWebPage(context: Context, url: String) {
val chooserTitle = "Open url using"
val webBrowserSharingIntent = WebBrowserSharingIntent(url, chooserTitle)
shareIntent(context, webBrowserSharingIntent)
}
  • Adding or removing intent types won’t cause ripple effects

A rule of thumb that you follow while choosing one over the other is that when you have to frequently add/remove the type then use the object-oriented approach and when you want to frequently add/remove the behavior then use the procedural approach.

Conclusion

The different approaches that we discussed above are good in their own way but each subsequent to them overcome the drawbacks of the previous one. In the article, we started with a procedural approach and ended up with an object-oriented approach.

YOU MAY BE INTERESTED IN

YOU MAY BE INTERESTED IN

blog
As the rate of data communication increases, the complexity of the application architecture also…
READ MORE

Leave a Reply

Your email address will not be published.

Fill out this field
Fill out this field
Please enter a valid email address.

Menu