如何在小米Redmi 5设备上通过Intent.ACTION_ATTACH_DATA调出图库选项?
解决小米Redmi 5(Nougat)设置壁纸时不显示图库选项的问题
嘿,我明白你的困扰——同样的代码在Lenovo、Advan这些设备上能正常调出图库选壁纸,到了小米Redmi 5(Android 7.0)就没了这个选项,确实头疼。结合你的代码和设备情况,我来分析下原因并给出可行的解决方案:
问题根源
- Android 7.0的Uri安全限制:从Nougat开始,Android禁止直接使用
file://类型的Uri暴露给其他应用,虽然你的代码没抛出FileUriExposedException,但小米系统可能对这类不安全的Uri做了拦截,导致图库应用无法响应你的Intent。 - 小米系统定制逻辑:MIUI对系统Intent的处理有自己的规则,可能优先展示自带的壁纸设置工具,而屏蔽了图库的选项。
具体解决方案
方案1:用FileProvider生成安全Uri(官方推荐,适配7.0+)
这是最稳妥的适配方式,既能解决Uri暴露问题,也能让更多应用(包括图库)响应你的Intent:
- 在AndroidManifest.xml注册FileProvider:
<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>
- 创建file_paths.xml配置文件:
在res/xml目录下新建这个文件,指定你的图片所在的外部存储目录:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 对应你存放壁纸的"Wallpaper Folder"目录 --> <external-path name="wallpapers" path="Wallpaper Folder/" /> </paths>
- 修改代码生成安全Uri:
替换原来的Uri.fromFile()逻辑,同时添加权限授予:
// 原文件获取逻辑保持不变 File folderPict = new File(Environment.getExternalStorageDirectory() + File.separator + "Wallpaper Folder"); String pictName = "IMG_Wallpaper.jpg"; String destFileName = folderPict.getAbsolutePath() + "/" + pictName; File filePict = new File(destFileName); // 适配7.0+生成安全Uri Uri uriPict; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // 注意这里的authority要和Manifest里的一致 uriPict = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".fileprovider", filePict); } else { uriPict = Uri.fromFile(filePict); } // 构建Intent并添加临时权限 Intent intent = new Intent(Intent.ACTION_ATTACH_DATA); intent.setDataAndType(uriPict, "image/*"); intent.putExtra("mimeType", "image/*"); // 授予其他应用读取这个Uri的临时权限 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // 启动选择器 startActivity(Intent.createChooser(intent, "Set as"));
方案2:改用ACTION_SET_WALLPAPER Intent
如果方案1还是不显示图库,可以试试官方专门的设置壁纸Action,部分设备对这个Action的支持更友好:
Intent intent = new Intent(Intent.ACTION_SET_WALLPAPER); intent.setDataAndType(uriPict, "image/*"); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); startActivity(Intent.createChooser(intent, "Set as wallpaper"));
方案3:兜底方案——直接指定小米图库启动
如果前两种都不行,可以尝试直接调用小米图库的壁纸设置功能,但要注意这种方式兼容性有限,仅作为备选:
Intent intent = new Intent(Intent.ACTION_ATTACH_DATA); intent.setDataAndType(uriPict, "image/*"); intent.putExtra("mimeType", "image/*"); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // 指定小米图库的包名(不同MIUI版本可能有变化,先试试这个) intent.setPackage("com.miui.gallery"); try { startActivity(intent); } catch (ActivityNotFoundException e) { // 如果找不到小米图库,再 fallback到通用选择器 startActivity(Intent.createChooser(intent, "Set as")); }
额外注意点
- 别忘了在Android 6.0+设备上动态申请
READ_EXTERNAL_STORAGE权限,否则你的应用无法读取外部存储里的图片文件。 - MIUI的版本差异较大,建议多在目标机型上测试不同方案的效果,找到最适合的那一个。
内容的提问来源于stack exchange,提问作者danangmr
相关产品推荐
相关产品推荐

