1

I want to share an image located in assets folder using 'Kotlin'.How can I achieve that Similar block of code in android :

Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("image/jpeg");
intent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(intent, "Share Image"));
PRATEEK BHARDWAJ
  • 2,364
  • 2
  • 21
  • 35
PKumar
  • 516
  • 9
  • 20
  • 1
    When you use the Java-to-Kotlin converter in Android Studio, what do you get? Note that Android itself has no ability to share an asset directly -- you either need your own `ContentProvider`, a third-party provider like [my `StreamProvider`](https://github.com/commonsguy/cwac-provider), or copy the asset to a file and then use `FileProvider`. – CommonsWare Jan 07 '18 at 13:31
  • @CommonsWare any example could be helpful – PKumar Jan 07 '18 at 13:34
  • 1
    Example code for *what*? – CommonsWare Jan 07 '18 at 13:36
  • What you consider "Android" code up there, is actually just Java code written using Android framework components (Intent, Activity, etc.). Are you asking us to help you convert the exact code above to Kotlin, or to help you with any approach in Kotlin achieving something similar? If it is the first case, you need to expand what `Intent.createChooser` does for you. – anthonymonori Jan 07 '18 at 17:19

1 Answers1

6

First you need to have the data stored somewhere. If you are compiling against API 24 or above, the FileProvider is a popular choice:

Declare the provider in your AndroidManifest.xml:

<application>
  <!-- make sure within the application tag, otherwise app will crash with XmlResourceParser errors -->
  <provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.codepath.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
      <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/fileprovider" />
  </provider>
</application>

Next, create a resource directory called xml and create a fileprovider.xml. Assuming you wish to grant access to the application's specific external storage directory, which requires requesting no additional permissions, you can declare this line as follows:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-files-path
        name="images"
        path="Pictures" />

    <!--Uncomment below to share the entire application specific directory -->
    <!--<external-path name="all_dirs" path="."/>-->
</paths>

Finally, you will convert the File object into a content provider using the FileProvider class:

// getExternalFilesDir() + "/Pictures" should match the declaration in fileprovider.xml paths
val file = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "share_image_" + System.currentTimeMillis() + ".png")

// wrap File object into a content provider. NOTE: authority here should match authority in manifest declaration
val bmpUri = FileProvider.getUriForFile(MyActivity.this, "com.codepath.fileprovider", file)

Source

Now you have a way to store and retrieve Uri for an individual File. The next step is to simply create an intent and start it by writing the following:

val intent = Intent().apply {
        this.action = Intent.ACTION_SEND
        this.putExtra(Intent.EXTRA_STREAM, bmpUri)
        this.type = "image/jpeg"
    }
startActivity(Intent.createChooser(intent, resources.getText(R.string.send_to)))

Notice the bmpUri is the value you retrieved just before.

Source

You should remember to consider Runtime permissions if you are running API 23 or above. Here's a good tutorial on that.

anthonymonori
  • 1,754
  • 14
  • 36