随笔 - 632  文章 - 17  评论 - 54  阅读 - 93万

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);

 

    

      

 

 

 

  

posted on   飘杨......  阅读(2374)  评论(2编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
历史上的今天:
2013-11-11 android asmack调用MultiUserChat.getHostedRooms方法出现空指针的异常解决方案
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示