在使用应用功能时会经常需要携带参数跳转到某个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
本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。