Android 接收分享内容的完整实现指南

QuibblerAgentQuibblerAgent 2026-03-10 约 13 分钟 407 次阅读

Android 接收分享内容的完整实现指南

关于如何实现分享单个或多个文件,参考之前的Android 分享功能实现指南。本篇讲的则是从接收方,要接收来自其他应用的分享内容(文本、链接、图片或文件),需要正确配置 Intent Filter 和处理传入的数据。

1、基本配置

下面是完整的实现流程:

1.1. 修改 Manifest 文件

首先需要在 AndroidManifest.xml 中添加适当的 Intent Filter:android.intent.action.SEND

<intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="*/*" />  <!-- 接收任意类型 -->
    </intent-filter>

支持多文件接收,添加android.intent.action.SEND_MULTIPLE:

<!-- 如果要同时支持多选 -->
    <intent-filter>
        <action android:name="android.intent.action.SEND_MULTIPLE" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="*/*" />
    </intent-filter>

1.2、处理不同类型的分享内容

在接收的Activity 中处理传入的 Intent:

public class ShareReceiverActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_receiver);
    
            handleReceivedContent(getIntent());
        }
    
        private void handleReceivedContent(Intent intent) {
            String action = intent.getAction();
            String type = intent.getType();
    
            if (Intent.ACTION_SEND.equals(action) && type != null) {
                // 处理单个分享项
                if ("text/plain".equals(type)) {
                    handleText(intent); // 处理文本
                } else if (type.startsWith("image/")) {
                    handleImage(intent); // 处理图片
                } else if (type.startsWith("*/*")){
                    handleFile(intent); // 处理通用文件
                }
            } else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) {
                // 处理多个分享项
                handleMultipleItems(intent);
            } else {
                // 不是有效的分享内容
                finish();
            }
        }
    }

2、具体数据处理方法

2.1. 接收纯文本或链接

private fun handleText(intent: Intent) {
        val sharedText = intent.getStringExtra(Intent.EXTRA_TEXT)
        Log.d(TAG, "handleText: $sharedText")
        if (sharedText != null) {
            // 更新UI显示文本

            // 如果是URL链接
            if (isValidUrl(sharedText)) {
                //processLink(sharedText)
            }
        }
    }

或者从clipData读取文本:

it.clipData?.getItemAt(0)?.text

判断是否是链接:

private boolean isValidUrl(String url) {
        Pattern p = Patterns.WEB_URL;
        Matcher m = p.matcher(url.toLowerCase(Locale.getDefault()));
        return m.matches();
    }

2.2. 接收单一图片/文件

private fun handleImage(intent: Intent) {
        val imageUri: Uri? = intent.getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java)
        Log.i(TAG, "handleImage: $imageUri")
        if (imageUri != null) {
            try {
                val bitmap = MediaStore.Images.Media.getBitmap(contentResolver, imageUri)
                // 显示图片
                binding.image.setImageBitmap(bitmap)

                // 如果需要保存文件
                //saveToLocal(imageUri)
            } catch (e: IOException) {
            }
        }
    }

    //保存接收到的图片
    private void saveToLocal(Uri uri) throws IOException {
        InputStream inputStream = getContentResolver().openInputStream(uri);
        File outputFile = new File(getExternalFilesDir(null), "received_" + System.currentTimeMillis() + ".jpg");
        FileUtils.copy(inputStream, new FileOutputStream(outputFile));
    }

或者从clipData读取

it.clipData?.getItemAt(0)?.uri

2.3. 接收多个文件

接收多文件:

private void handleMultipleItems(Intent intent) {
        ArrayList<Uri> uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
        if (uris != null) {
            for (Uri uri : uris) {
                String mimeType = getContentResolver().getType(uri);
                if (mimeType != null) {
                    if (mimeType.startsWith("image/")) {
                        // 处理图片
                    } else if (mimeType.contains("video")) {
                        // 处理视频
                    } else {
                        // 处理普通文件
                    }
                }
            }
        }
    }

或者从clipData读取

for (i in 0 until clipData.itemCount) {
            clipData.getItemAt(i).let { clipDataItem ->
            clipDataItem.text
            clipDataItem.uri
        }
    }

3、权限处理

确保在 manifest 中有必要的权限声明:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

对于 Android 10+,还需要使用 Scoped Storage API:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        // 使用 ContentResolver 直接操作,不需要额外权限
    } else {
        // 检查并申请传统存储权限
    }

4、优化用户体验

添加预览功能:对大图进行压缩后再显示

进度指示器:处理大文件时显示进度条

错误处理:捕获所有可能的IO异常并提供友好的提示

深色模式支持:适配不同的主题

5、注意要点

从不同应用发送不同类型的内容,以及兼容性考虑:

超大文件的处理能力

网络链接的正确识别

验证在多任务情况下的行为

以上实现了完整的分享接收功能,根据需要调整各部分细节来满足特定的业务需求。

相关推荐

精选
ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager
Android

ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager

ViewPager1、ViewPagerandroidx.viewpager.widget.ViewPager,Android中使用非常广泛的控件,可以说是APP必备:首次打开引导页、页面Banner广告等。常用方法:setAdapter() 设置适配器setOffscreenPageLimit() 设置缓存的页面个数,默认是 1setCurrentItem() 跳转到特定的页面setOnPage

1.1k
获取Android内置WebView内核版本
Android

获取Android内置WebView内核版本

获取Android内置WebView内核版本竟然能遇到这样奇葩的事情,网页用的技术过于新颖,以至于只支持高版本Chromium内核的,低版本安卓系统中内置的内核版本较低,无法加载前端页面。1、设置查看在系统设置里 > 应用 > 应用管理 > 显示系统应用,查看WebView组件:2、页面查看通过WebView发起的网络请求,都会带上浏览器的UA,通常页面都可以通过UA判断浏览器的内核版本。这里有两

1.1w
Android 14适配总结
Android

Android 14适配总结

Android 14适配总结毕业工作至今已经适配了三个Android大版本,从Android 11到Android 12、再到Android 13。2023年,Google即将推出的Android 14,上半年已经开始第一批适配。现在,第四个Android版本已经适配完,总结记录一下。1、Android 14计划Google一般会在2月份对外发布预告,同时放出开发者预览版。“拉通”各大平台、厂商以

1.1w