Kivy开发Python安卓视频下载器下载视频无法在荣耀/真我图库立即显示
问题原因
- 厂商定制ROM权限拦截:荣耀、真我对应机型搭载的Magic UI、realme UI定制系统,默认会拦截第三方应用触发的全局媒体扫描请求,普通
MediaScannerConnection调用仅会扫描应用私有目录,不会同步公共存储文件到系统媒体库 - 存储路径不符合收录规则:如果视频保存到应用沙盒私有目录(/data/data/包名/ 或 Android/data/包名/路径下),系统媒体库无读取权限,自然不会收录
- 扫描调用参数错误:你现有代码调用
scanFile时第三个参数(MIME类型数组)传了None,系统无法识别文件媒体类型,会直接跳过该文件的媒体库收录流程 - 权限缺失:Android 10及以上版本如果未动态申请
READ_MEDIA_VIDEO(Android13+)/READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE权限,扫描请求会被系统直接驳回 - 文件元数据缺失:部分定制ROM要求视频文件必须包含完整的编码、时长等元信息才会被收录,刚下载完成未写完元数据的文件会被系统跳过
解决代码
from jnius import autoclass, cast PythonActivity = autoclass('org.kivy.android.PythonActivity') currentActivity = cast('android.app.Activity', PythonActivity.mActivity) context = cast('android.content.Context', currentActivity.getApplicationContext()) Intent = autoclass('android.content.Intent') Uri = autoclass('android.net.Uri') MediaScannerConnection = autoclass('android.media.MediaScannerConnection') Build_VERSION = autoclass('android.os.Build$VERSION') def refresh_system_media(file_path): # 优先传明确的视频MIME类型,避免系统识别失败 video_mime_types = ["video/mp4", "video/avi", "video/mkv", "video/flv", "video/mov", "video/wmv"] if Build_VERSION.SDK_INT >= 29: # Android 10及以上采用双方案兼容,适配厂商定制ROM MediaScannerConnection.scanFile( context, [file_path], video_mime_types, None ) # 额外发送媒体扫描广播,绕过厂商拦截规则 media_uri = Uri.parse("file://" + file_path) scan_intent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, media_uri) context.sendBroadcast(scan_intent) else: # 低版本直接发送广播即可生效 media_uri = Uri.parse("file://" + file_path) scan_intent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, media_uri) context.sendBroadcast(scan_intent)
适配注意事项
- 存储路径必须选择公共外部存储的媒体目录,比如系统Movies、Download、DCIM目录,不要存放在应用私有路径下
- 需提前动态申请对应版本的存储权限,可使用plyer库的permission接口快速实现动态权限申请
- 必须在视频文件完全写入、文件流关闭后再调用刷新接口,避免扫描到不完整的文件被系统忽略
内容的提问来源于stack exchange,提问作者Abdul
相关产品推荐
相关产品推荐

