版权声明
本文来自博客园,作者:观心静 ,转载请注明原文链接:https://www.cnblogs.com/guanxinjing/p/16741030.html
前言
在使用应用功能时会经常需要携带参数跳转到某个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() }
End
本文来自博客园,作者:观心静 ,转载请注明原文链接:https://www.cnblogs.com/guanxinjing/p/16741030.html
浙公网安备 33010602011771号