Android 通过 Android Sharesheet 进行分享

1,253 阅读2分钟

最近的项目中需要用到分享功能,之前做分享一般都是直接用三方聚合类的SDK,比如国内的友盟、ShareSdk。

老大提到说可以试试看直接调用系统的分享,这个我之前还真没尝试过,所以通过本篇文章记录一下如何使用系统分享(Android Sharesheet)。

Android Sharesheet简介

Android Sharesheet 通过Intent与其内含的Extra让用户可以使用他们喜爱的应用快速轻松地分享信息。

常用的MIME类型

使用Android Sharesheet进行分享时,可以指定分享内容的类型,如果目标App有注册、处理指定的类型,则会在Android Sharesheet的面板中显示,下面是一些常用的类型:

object MimeType {

    const val TEXT_PLAIN = "text/plain"
    const val TEXT_RTF = "text/rtf"
    const val TEXT_HTML = "text/html"
    const val TEXT_JSON = "text/json"

    const val IMAGE_JPEG = "image/jpeg"
    const val IMAGE_PNG = "image/png"
    const val IMAGE_GIT = "image/gif"
    const val IMAGE_ALL = "image/*"

    const val VIDEO_MP4 = "video/mp4"
    const val VIDEO_3GP = "video/3gp"
}

更多的类型可以参考媒体类型的 IANA 官方注册表

分享文本

可以通过如下代码分享纯文本或者网页:


class SystemShareActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding = DataBindingUtil.setContentView<LayoutSystemShareActivityBinding>(this, R.layout.layout_system_share_activity)

        binding.btnShareText.setOnClickListener {
            val onlyTextShareIntent = Intent().apply {
                //actoin 必须使用Intent.ACTION_SEND
                action = Intent.ACTION_SEND
                //设置文本内容
                putExtra(Intent.EXTRA_TEXT, "this is test share text")
                //指定类型
                type = MimeType.TEXT_PLAIN
            }

            val shareIntent = Intent.createChooser(onlyTextShareIntent, "ShareTextTitle")
            startActivity(shareIntent)
        }
        binding.btnShareUrl.setOnClickListener {
            val urlShareIntent = Intent().apply {
                action = Intent.ACTION_SEND
                //设置网页链接
                putExtra(Intent.EXTRA_TEXT, "https://juejin.cn/")
                //设置标题
                putExtra(Intent.EXTRA_TITLE, "ShareUrlTitle")
                //指定类型
                type = MimeType.TEXT_HTML
            }

            val shareIntent = Intent.createChooser(urlShareIntent, null)
            startActivity(shareIntent)
        }
    }
}

分享文本效果如图:

分享文字.gif

分享网页效果如图:

分享网页.gif

分享文件

文件分享需要使用Uri,所以需要配置FileProvider

//在res文件夹下新建xml资源文件夹,并新建file_path.xml资源文件
<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path
        name="images"
        path="." />
    <cache-path
        name="cache-path"
        path="." />
    <external-path
        name="external_storage_root"
        path="." />
    <external-cache-path
        name="external_cache_path"
        path="." />
</paths>

//在Manifest中配置FileProvider
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <application>

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_path" />
        </provider>
    </application>
</manifest>

分享图片或者视频

可以通过如下代码分享图片或者视频:

class SystemShareActivity : AppCompatActivity() {

    private val pickPhoto = registerForActivityResult(PickSinglePhotoContract()) { uri ->
        if (uri != null) {
            val pictureShareIntent: Intent = Intent().apply {
                action = Intent.ACTION_SEND
                //设置图片Uri
                putExtra(Intent.EXTRA_STREAM, uri)
                //指定类型
                type = MimeType.IMAGE_JPEG
            }
            val shareIntent = Intent.createChooser(pictureShareIntent, "SharePictureTitle")
            startActivity(shareIntent)
        }
    }

    private val pickVideo = registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
        if (uri != null) {
            val pictureShareIntent: Intent = Intent().apply {
                action = Intent.ACTION_SEND
                //设置视频Uri
                putExtra(Intent.EXTRA_STREAM, uri)
                //指定类型
                type = MimeType.VIDEO_MP4
            }
            val shareIntent = Intent.createChooser(pictureShareIntent, "ShareVideoTitle")
            startActivity(shareIntent)
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding = DataBindingUtil.setContentView<LayoutSystemShareActivityBinding>(this, R.layout.layout_system_share_activity)

        binding.btnSharePicture.setOnClickListener {
            pickPhoto.launch(null)
        }
        binding.btnShareVideo.setOnClickListener {
            pickVideo.launch(MimeType.VIDEO_All)
        }
    }
}

分享图片效果如图:

分享图片.gif

分享视频效果如图:

分享视频.gif

多文件分享(混合类型)

可以分享多张图片,多个视频,或者图片+视频。

代码如下:

class SystemShareActivity : AppCompatActivity() {

    private val sharePhotoUri = ArrayList<Uri>()
    private val shareVideoUrl = ArrayList<Uri>()

    private val pickPhotos = registerForActivityResult(PickMultipleMediumContract()) { uriList ->
        if (uriList.isNotEmpty()) {
            sharePhotoUri.addAll(uriList)
            val photoShareIntent = Intent().apply {
                action = Intent.ACTION_SEND_MULTIPLE
                putParcelableArrayListExtra(Intent.EXTRA_STREAM, sharePhotoUri)
                type = MimeType.IMAGE_ALL
            }
            startActivity(Intent.createChooser(photoShareIntent, "SharePhotosTitle"))
        }
    }
    private val pickVideos = registerForActivityResult(ActivityResultContracts.GetMultipleContents()) { uri ->
        if (uri.isNotEmpty()) {
            shareVideoUrl.addAll(uri)
            val videoShareIntent: Intent = Intent().apply {
                action = Intent.ACTION_SEND_MULTIPLE
                putParcelableArrayListExtra(Intent.EXTRA_STREAM, shareVideoUrl)
                type = MimeType.VIDEO_All
            }
            val shareIntent = Intent.createChooser(videoShareIntent, "ShareVideosTitle")
            startActivity(shareIntent)
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding = DataBindingUtil.setContentView<LayoutSystemShareActivityBinding>(this, R.layout.layout_system_share_activity)

        binding.btnSharePictures.setOnClickListener {
            pickPhotos.launch(null)
        }
        binding.btnShareVideos.setOnClickListener {
            pickVideos.launch(MimeType.VIDEO_All)
        }
        binding.btnShareMultipleMedium.setOnClickListener {
            val mediumUris = ArrayList<Uri>()
            mediumUris.addAll(sharePhotoUri)
            mediumUris.addAll(shareVideoUrl)
            if (mediumUris.isNotEmpty()) {
                val mediumShareIntent = Intent().apply {
                    action = Intent.ACTION_SEND_MULTIPLE
                    putParcelableArrayListExtra(Intent.EXTRA_STREAM, mediumUris)
                    type = MimeType.ALL
                }
                startActivity(Intent.createChooser(mediumShareIntent, "ShareMultipleMediumTitle"))
            }
        }
    }
}

多图分享效果如图:

1660013449051780.gif

多视频分享效果如图:

1660013602056668.gif

图片视频混合分效果如图:

1660013819221990.gif