RecyclerView的ArrayList中图片分享显示Null问题求助
解决RecyclerView图片分享显示Null的问题
问题描述
点击RecyclerView中的分享按钮后,能弹出应用选择列表,但选择应用后,目标应用里显示的内容为Null。我的onBindViewHolder代码如下:
holder.send.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); StrictMode.setVmPolicy(builder.build()); final String image_path = fileslist.get(position).getUri().toString(); File share = new File(image_path); Uri uri = Uri.fromFile(share); Intent shareIntent = new Intent(); shareIntent.setAction(Intent.ACTION_SEND); shareIntent.setType("image/"); shareIntent.putExtra(Intent.EXTRA_STREAM, uri); context.startActivity(Intent.createChooser(shareIntent, "Share to.....")); } });
问题原因
- Uri处理错误:直接把
getUri().toString()转成File,如果原Uri是content://开头的内容Uri,这种转换会生成无效的file://Uri,目标应用无法访问到图片。 - MIME类型不合法:
setType("image/")格式错误,缺少通配符或具体类型,部分应用无法识别分享的内容类型。 - StrictMode的错误用法:用StrictMode绕过权限检查不是合规方案,Android 7.0+禁止直接分享
file://Uri,会触发FileUriExposedException,同时也会导致Uri无效。
解决方案
1. 配置FileProvider
在AndroidManifest.xml中添加FileProvider的配置,用于生成安全的content://Uri:
<application> ... <provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> </application>
2. 创建文件路径配置文件
在res/xml目录下新建file_paths.xml,指定允许分享的文件存储路径(根据你的图片实际存储位置调整):
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 示例:外部存储中应用专属的Pictures目录 --> <external-files-path name="shared_images" path="Pictures/" /> <!-- 如果图片在外部公共目录,用下面的配置 --> <!-- <external-path name="external_public" path="." /> --> </paths>
3. 修改分享逻辑代码
替换原来的点击事件代码,正确处理Uri并使用FileProvider生成安全Uri:
holder.send.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Uri originalUri = fileslist.get(position).getUri(); File imageFile = null; // 区分处理content://和file://类型的Uri if ("content".equals(originalUri.getScheme())) { // 从content Uri获取真实文件路径 String[] projection = {MediaStore.Images.Media.DATA}; try (Cursor cursor = context.getContentResolver().query(originalUri, projection, null, null, null)) { if (cursor != null && cursor.moveToFirst()) { int pathIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); String filePath = cursor.getString(pathIndex); imageFile = new File(filePath); } } catch (Exception e) { e.printStackTrace(); Toast.makeText(context, "获取图片路径失败", Toast.LENGTH_SHORT).show(); return; } } else if ("file".equals(originalUri.getScheme())) { imageFile = new File(originalUri.getPath()); } // 检查文件是否存在 if (imageFile == null || !imageFile.exists()) { Toast.makeText(context, "图片文件不存在", Toast.LENGTH_SHORT).show(); return; } // 生成安全的content Uri String authority = context.getPackageName() + ".fileprovider"; Uri shareUri = FileProvider.getUriForFile(context, authority, imageFile); // 构建分享Intent Intent shareIntent = new Intent(Intent.ACTION_SEND); shareIntent.setType("image/*"); // 正确的图片MIME类型 shareIntent.putExtra(Intent.EXTRA_STREAM, shareUri); // 授予目标应用临时读取权限 shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); context.startActivity(Intent.createChooser(shareIntent, "分享到.....")); } });
额外提示
- 如果你的图片存储在应用内部目录,需要调整
file_paths.xml中的路径标签,比如用files-path对应应用内部的files目录。 - 彻底移除StrictMode相关代码,它只是临时绕过限制,不符合Android安全规范,高版本系统会直接崩溃。
内容的提问来源于stack exchange,提问作者Aisha Kumari
相关产品推荐
相关产品推荐

