React Native 如何实现直接打开Android系统图片相册功能
实现方案
核心原理
现有第三方库默认跳转「最近文件」的核心原因是使用了ACTION_GET_CONTENT这个通用文件选择Action,要直接进入系统相册首页,需要使用ACTION_PICK并指定图片媒体库的专属URI,限定仅加载本地图片资源。
具体实现步骤
1. 安卓端权限配置
在AndroidManifest.xml中添加图片读取权限:
<!-- Android 13及以上 --> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <!-- Android 12及以下 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
2. 自定义原生模块
创建自定义RN原生模块,核心启动相册的代码示例如下:
class GalleryLauncherModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) { private val PICK_IMAGE_REQUEST = 1001 private var promise: Promise? = null override fun getName(): String = "GalleryLauncher" @ReactMethod fun openSystemGallery(promise: Promise) { this.promise = promise // 关键:使用ACTION_PICK指定图片媒体库URI,直接进入相册图片列表 val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI) intent.type = "image/*" // 可选:仅加载本地图片,排除云同步文件 intent.putExtra("android.intent.extra.LOCAL_IMAGES_ONLY", true) currentActivity?.let { activity -> try { activity.startActivityForResult(intent, PICK_IMAGE_REQUEST) } catch (e: Exception) { promise.reject("LAUNCH_ERROR", "启动相册失败", e) } } ?: run { promise.reject("ACTIVITY_NULL", "当前Activity不存在") } } // 注册ActivityResult回调接收选中的图片URI fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { if (requestCode == PICK_IMAGE_REQUEST && resultCode == Activity.RESULT_OK) { data?.data?.let { uri -> promise?.resolve(uri.toString()) } ?: promise?.reject("NO_IMAGE_SELECTED", "未选择图片") } else { promise?.reject("CANCELLED", "用户取消选择") } } }
3. 注册模块并绑定回调
在你的ReactPackage实现类中注册上述模块,同时在主Activity中绑定onActivityResult回调,将结果传递给自定义模块。
4. RN端调用
JS层直接调用原生模块方法即可:
import { NativeModules } from 'react-native'; const { GalleryLauncher } = NativeModules; // 调用示例 const pickImageFromGallery = async () => { try { const imageUri = await GalleryLauncher.openSystemGallery(); // 处理返回的图片URI console.log('选中的图片地址:', imageUri); } catch (e) { console.log('选择图片失败:', e); } };
扩展适配
- 多选需求:将Action替换为
ACTION_OPEN_DOCUMENT,添加intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true),回调中从data.clipData获取所有选中的URI即可 - 厂商适配:部分定制ROM如果无法匹配
ACTION_PICK的响应Activity,可添加兜底逻辑,检测到无响应应用时自动降级为带LOCAL_IMAGES_ONLY参数的ACTION_GET_CONTENT调用
内容的提问来源于stack exchange,提问作者fullStackChris
相关产品推荐
相关产品推荐

