Android 华为mate30系统相册加载不出来或者加载视频第一帧很慢
一、概述
案例:公司测试自己的手机华为mate30,鸿蒙2.0操作系统。用App选择相册的时候视频第一帧加载非常慢(有些视频第一帧加载不出来),如果第一帧没加载出来的情况下点击做预览就会出现黑屏和ANR。但是其他像小米、vivo、华为其他型号的手机就没有这个问题。
二、解决方法
找问题过程:
1.由于加载视频缩略图的框架用的是Glide,所以最开始的时候怀疑是Glide解码速度比较慢导致相册中的图片加载不出来。最后测试下来并非这个问题,因为其他手机并没有这个问题。ps:即使是最老旧的手机相册视频的第一帧加载速度依然很快。
2.开始定位是否是系统问题,因为公司所有的测试机中都没有类似或者同样的问题,只有华为mate30有这个每个问题。百度和google了一圈最终找到这么一篇文章。
https://github.com/zhihu/Matisse/issues/726
解决办法:
上述问题并没有实际有效的解决,因为我这边的手机无法复现了,我让测试把手机重启一下试试,结果重启后此异常消失了。后面再遇到此问题时做再问题补充。
问题补充:
上述方案重启后确实当时相册的加载速度还是可以的。但是隔天确有不行了,我不得不调整一下方案,单独适配mate30机型。调整后相册加载变得正常了。
解决步骤:
1.判断手机是否是Android10系统
2.判断手机系统是华为Harmony OS系统
3.判断得到的路径是content://开头的路径
4.如果三个条件都满足则把content://开头的路径转为绝对路径,即:/storage/emulated/0/DCIM/Camera/share_7b2a295b74f8b18d3bd3c40ada8bb304.mp4 形式的路径,转换后相册加载速度正常。
ps:相关转换代码如下:
/** * 返回条件: * 1.如果是Android10.0的系统 * 2.且手机系统是华为的 * 3.路径是content://开头的 * @return */ public static String getNewPath(Context context,String path){ if(SdkVersionUtils.checkedAndroid_Q_31()&&SdkVersionUtils.isHarmonyOSa()&&PictureMimeType.isContent(path)){ return getPath(context, Uri.parse(path)); } return path; } /** * Get a file path from a Uri. This will get the the path for Storage Access * Framework Documents, as well as the _data field for the MediaStore and * other file-based ContentProviders.<br> * <br> * Callers should check whether the path is local before assuming it * represents a local file. * * @param context The context. * @param uri The Uri to query. * @author paulburke */ @SuppressLint("NewApi") public static String getPath(final Context context, final Uri uri) { final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; // DocumentProvider if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { if (isExternalStorageDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; if ("primary".equalsIgnoreCase(type)) { if (SdkVersionUtils.checkedAndroid_Q()) { return context.getExternalFilesDir(Environment.DIRECTORY_PICTURES) + "/" + split[1]; } else { return Environment.getExternalStorageDirectory() + "/" + split[1]; } } // TODO handle non-primary volumes } // DownloadsProvider else if (isDownloadsDocument(uri)) { final String id = DocumentsContract.getDocumentId(uri); final Uri contentUri = ContentUris.withAppendedId( Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); return getDataColumn(context, contentUri, null, null); } // MediaProvider else if (isMediaDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; Uri contentUri = null; if ("image".equals(type)) { contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; } else if ("video".equals(type)) { contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; } else if ("audio".equals(type)) { contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } final String selection = "_id=?"; final String[] selectionArgs = new String[]{ split[1] }; return getDataColumn(context, contentUri, selection, selectionArgs); } } // MediaStore (and general) else if ("content".equalsIgnoreCase(uri.getScheme())) { // Return the remote address if (isGooglePhotosUri(uri)) { return uri.getLastPathSegment(); } return getDataColumn(context, uri, null, null); } // File else if ("file".equalsIgnoreCase(uri.getScheme())) { return uri.getPath(); } return null; }
使用的时候只需要调用,getNewPath方法获取路径即可。加载相册的库依然使用的是Glide
String newPath = PictureFileUtils.getNewPath(context,path);
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
2013-11-11 android asmack调用MultiUserChat.getHostedRooms方法出现空指针的异常解决方案