添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

在使用应用功能时会经常需要携带参数跳转到某个app、分享一些图片等等其他资源到微信上、接收一些其他应用分享来的图片等等其他资源。此篇博客讲解Scheme协议与分享功能

常见的 MIME 类型

超文本标记语言文本 .html、.html text/html

普通文本 .txt text/plain

RTF 文本 .rtf application/rtf

GIF 图形 .gif image/gif

JPEG 图形 .jpeg、.jpg image/jpeg

au 声音文件 .au audio/basic

MIDI 音乐文件 mid、.midi audio/midi、audio/x-midi

RealAudio 音乐文件 .ra、.ram audio/x-pn-realaudio

MPEG 文件 .mpg、.mpeg video/mpeg

AVI 文件 .avi video/x-msvideo

GZIP 文件 .gz application/x-gzip

TAR 文件 .tar application/x-tar

Scheme协议跳转

创建跳转的Activity

class SchemeActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_scheme)
        getUriData()
    fun getUriData(){
        val uri: Uri? = intent.data
        uri?.let {
            // uri
            Log.e("zh", "uri: ${it.toString()}")
            //scheme部分
            Log.e("zh", "scheme: ${it.scheme}")
            //host部分
            Log.e("zh", "host: ${it.host}")
            //port部分
            Log.e("zh", "host: ${it.port}")
            //访问路劲
            Log.e("zh", "path: ${it.path}")
            //路径片段
            Log.e("zh", "pathSegments: ${it.pathSegments}")
            //参数名称
            Log.e("zh", "getQueryParameterNames: ${it.queryParameterNames}")
            // Query部分
            Log.e("zh", "query: ${uri.query}")

打印结果:

  uri: zh://com.example.settings:9000/scheme
  scheme: zh
  host: com.example.settings
  host: 9000
  path: /scheme
  pathSegments: [scheme]
  getQueryParameterNames: []
  query: null

AndroidManifest.xml 上注册

  • scheme 协议名称
  • host 作用域
  • port 端口号
  • path 目标路径
  •         <activity
                android:name=".ui.SchemeActivity"
                android:exported="true">
                <intent-filter>
                    <action android:name="android.intent.action.VIEW"/>
                    <category android:name="android.intent.category.DEFAULT"/>
                    <category android:name="android.intent.category.BROWSABLE"/>
                    <data android:scheme="zh"
                        android:host="com.example.settings"
                        android:port="9000"
                        android:path="/scheme"/>
                </intent-filter>
            </activity>

    其他app里的跳转代码:

                val uri = Uri.parse("zh://com.example.settings:9000/scheme")
                val intent = Intent(Intent.ACTION_VIEW, uri)
                startActivity(intent)

     其他部分与上面一致

    跳转的Activity解析参数:

    class SchemeActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_scheme)
            getUriData()
        fun getUriData(){
            val uri: Uri? = intent.data
            uri?.let {
                val list = it.queryParameterNames
                for (item in list){
                    val parameter = it.getQueryParameter(item)
                    Log.e("zh", "parameter ${item} = ${parameter}")
    

    其他app里的跳转代码:

                val uri = Uri.parse("zh://com.example.settings:9000/scheme?id=123456&time=${System.currentTimeMillis()}")
                val intent = Intent(Intent.ACTION_VIEW, uri)
                startActivity(intent)
               E  parameter id = 123456
               E  parameter time = 1678952157640

    判断Scheme协议的有效性

                val uri = Uri.parse("zh://com.example.settings:9000/scheme?id=123456&time=${System.currentTimeMillis()}")
                val packageManager = packageManager
                val intent = Intent(ACTION_VIEW, uri)
                val activities: List<ResolveInfo> = packageManager.queryIntentActivities(intent, 0)
                val isValid = !activities.isEmpty()
                if (isValid) {
                    startActivity(intent)
    

    接收分享来的资源

    下面这个例子使用一个activity来接收分享来的图片,在AndroidManifest.xml 中添加, 请注意以下几个关键:

  • android:exported="true"  一定是true。否则此activity不会出现在分享弹窗的选项里
  • android.intent.action.SEND  为分享单个文件
  • android.intent.action.SEND_MULTIPLE  为分享多个文件
  •         <activity
                android:name=".ui.gallery.ReceiveShareImageActivity"
                android:exported="true" >
                <intent-filter android:label="将图片添加到收藏">
                    <action android:name="android.intent.action.SEND" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <data android:mimeType="image/*" />
                </intent-filter>
                <intent-filter android:label="将图片添加到收藏">
                    <action android:name="android.intent.action.SEND_MULTIPLE" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <data android:mimeType="image/*" />
                </intent-filter>
            </activity>

    mimeType的其他类型

            <data android:mimeType="image/*" />
            <data android:mimeType="video/*" />
            <data android:mimeType="audio/*" />
            <data android:mimeType="text/x-vcard" />
            <data android:mimeType="text/x-vcalendar" />
            <data android:mimeType="text/calendar" />
            <data android:mimeType="text/plain" />
            <data android:mimeType="text/html" />
            <data android:mimeType="text/xml" />
            <data android:mimeType="application/zip" />
            <data android:mimeType="application/vnd.ms-excel" />
            <data android:mimeType="application/msword" />
            <data android:mimeType="application/vnd.ms-powerpoint" />
            <data android:mimeType="application/pdf" />
            <data android:mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" />
            <data android:mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.document" />
            <data android:mimeType="application/vnd.openxmlformats-officedocument.presentationml.presentation" />
            <data android:mimeType="application/x-hwp" />

    在activity的onCreate调用如下代码,获取分享来的图片:

        private fun getShareImage() {
            intent.type?.let { type ->
                    单个图片分享接收
                if (intent.action == Intent.ACTION_SEND && type.startsWith("image/")) {
                    val uri: Uri? = intent.getParcelableExtra(Intent.EXTRA_STREAM)
                    uri?.let { uri ->
                        val inputStream = contentResolver.openInputStream(uri)
                        val bitmap = BitmapFactory.decodeStream(inputStream)
                        inputStream?.close()
                    多个图片分享接收
                if (intent.action == Intent.ACTION_SEND_MULTIPLE && type.startsWith("image/")) {
                    val arrayList: ArrayList<Uri>? =
                        intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM)
                    arrayList?.let { arrayList ->
                        arrayList.forEach {
                            val inputStream = contentResolver.openInputStream(it)
                            val bitmap = BitmapFactory.decodeStream(inputStream)
                            inputStream?.close()
    

    发送资源分享到其他应用

    在设备中获取支持分享的应用

    fun getShareImageApps(): List<ResolveInfo> {
        val intent = Intent(Intent.ACTION_SEND, null)
        intent.addCategory(Intent.CATEGORY_DEFAULT)
        intent.type = "image/*"
        var appList = packageManager.queryIntentActivities(intent, PackageManager.MATCH_ALL)
        for (item in appList){
            val packageName = item.activityInfo.packageName
            val activityName = item.activityInfo.name
            val appName = item.loadLabel(packageManager)
            val appIcon = item.loadIcon(packageManager)
            Log.e("zh", "获取可分享的应用 应用名称 = ${appName} 包名 = ${packageName}  分享的目标Activity路径 = ${activityName}  图标 = ${appIcon} ")
        return appList
    
    2023-07-06 10:00:41.583  8917-8917  zh      获取可分享的应用 应用名称 = 蓝牙 包名 = com.android.bluetooth  分享的目标Activity路径 = com.android.bluetooth.opp.BluetoothOppLauncherActivity  图标 = android.graphics.drawable.AdaptiveIconDrawable@8b826dc 
    2023-07-06 10:00:41.645  8917-8917  zh      获取可分享的应用 应用名称 = 图片转文档(PDF/Excel/Word/PPT) 包名 = cn.wps.moffice_eng  分享的目标Activity路径 = cn.wps.moffice.entrance.pictodoc.PicToDocEntranceActivity  图标 = android.graphics.drawable.BitmapDrawable@72d316b 
    2023-07-06 10:00:41.648  8917-8917  zh      获取可分享的应用 应用名称 = 图片工具集(压缩、抠图、消除…) 包名 = cn.wps.moffice_eng  分享的目标Activity路径 = cn.wps.moffice.entrance.pictool.PicToolEntranceActivity  图标 = android.graphics.drawable.BitmapDrawable@d5b961 
    2023-07-06 10:00:41.651  8917-8917  zh      获取可分享的应用 应用名称 = 保存到WPS云文档 包名 = cn.wps.moffice_eng  分享的目标Activity路径 = cn.wps.moffice.main.cloud.drive.upload.UploadFileActivity  图标 = android.graphics.drawable.BitmapDrawable@e6b7947 
    2023-07-06 10:00:41.742  8917-8917  zh      获取可分享的应用 应用名称 = 钉钉 包名 = com.alibaba.android.rimet  分享的目标Activity路径 = com.alibaba.android.rimet.biz.BokuiActivity  图标 = android.graphics.drawable.AdaptiveIconDrawable@a0974e0 
    2023-07-06 10:00:41.768  8917-8917  zh      获取可分享的应用 应用名称 = 今日头条 包名 = com.ss.android.article.news  分享的目标Activity路径 = com.ss.android.publish.send.TTSendPostActivity  图标 = android.graphics.drawable.BitmapDrawable@2e84a3f 
    2023-07-06 10:00:41.782  8917-8917  zh      获取可分享的应用 应用名称 = 将图片添加到收藏 包名 = com.zh.calligraphy  分享的目标Activity路径 = com.zh.calligraphy.ui.share.ReceiveShareImageActivity  图标 = android.graphics.drawable.VectorDrawable@c89ea6a 

    向目标应用分享图片

        //向目标apk分享图片
        fun shareSingleImage() {
            //分享给微信朋友圈
            val componentName = ComponentName("com.tencent.mm","com.tencent.mm.ui.tools.ShareToTimeLineUI")
            val file = File(FileConstant.SAVE_IMAGE_PATH, "1664357696014.jpg")
            val imageUri = Uri.fromFile(file)
            val shareIntent = Intent()
            shareIntent.setComponent(componentName)
            shareIntent.action = Intent.ACTION_SEND
            shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri)
            shareIntent.type = "image/*"
            startActivity(Intent.createChooser(shareIntent, "分享到"))
    

    单个图片分享

        //分享单张图片
        fun shareSingleImage() {
            //可以通过bitmap分享图片
    //        val imageUri: Uri = Uri.parse(MediaStore.Images.Media.insertImage(activity?.contentResolver, bitmap, null, null))
            //通过文件分享图片
            val file = File(FileConstant.SAVE_IMAGE_PATH, "1664357696014.jpg")
            val imageUri = Uri.fromFile(file)
            val shareIntent = Intent()
            shareIntent.action = Intent.ACTION_SEND
            shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri)
            shareIntent.type = "image/*"
            startActivity(Intent.createChooser(shareIntent, "分享到"))
    

    多个图片分享

        //分享多张图片
        fun shareMoreImage() {
            val file = File(FileConstant.SAVE_IMAGE_PATH, "1664357696014.jpg")
            val imageUri = Uri.fromFile(file)
            val shareIntent = Intent()
            shareIntent.action = Intent.ACTION_SEND_MULTIPLE
            val list = ArrayList<Uri>()
            list.add(imageUri)
            shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, list)
            shareIntent.type = "image/*"
            startActivity(Intent.createChooser(shareIntent, "分享到"))
    
        //分享文字
        fun shareText() {
            val shareIntent = Intent()
            shareIntent.action = Intent.ACTION_SEND
            shareIntent.putExtra(Intent.EXTRA_TEXT, "This is my Share text.")
            shareIntent.type = "text/plain"
            //设置分享列表的标题,并且每次都显示分享列表
            startActivity(Intent.createChooser(shareIntent, "分享到"))
    

    使用Uri分享请注意

    首先需要在分享之前onCreate里调用,解决资源分享报错问题

        private fun detectFileUriExposure() {
            val builder: StrictMode.VmPolicy.Builder = Builder()
            StrictMode.setVmPolicy(builder.build())
            builder.detectFileUriExposure()
        

    本文来自博客园,作者:观心静 ,转载请注明原文链接:https://www.cnblogs.com/guanxinjing/p/16741030.html

    本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。