解决4.4版本以上剪裁图片时提示无法加载图片的问题

 /**
     * 将uri转换成字符串
     * 解决4.4版本以上获取到的uri是图片名称而非图片路径,导致剪裁图片时提示无法加载图片的问题
     * 详细的解决方案,请参考这篇文章
     * 当安卓的版本比较高时(如4.4),选择本地相册可能会返回“无法加载此图片”
     * 原因:正常uri是file://...而高版本是content://...
     * 所以需要一个转换操作
     *
     * @param context
     * @param uri
     * @return
     */
    @SuppressLint("NewApi")
    public static String getPath(final Context context, final Uri uri) {
//        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
        final boolean isKitKat = Build.VERSION.SDK_INT >= 19;
        try {
            ReflectionUtil reflectionUtil = new ReflectionUtil();
            Object documentUri = reflectionUtil.invokeStaticMethod("android.provider.DocumentsContract", "isDocumentUri", new Object[]{context, uri});
            Object documentId = reflectionUtil.invokeStaticMethod("android.provider.DocumentsContract", "getDocumentId", new Object[]{uri});
            // DocumentProvider
//            if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            if (isKitKat && Boolean.valueOf(documentUri.toString()) == true) {
                // ExternalStorageProvider
                if (isExternalStorageDocument(uri)) {
//                    final String docId = DocumentsContract.getDocumentId(uri);
                    final String docId = documentId.toString();
                    final String[] split = docId.split(":");
                    final String type = split[0];
                    if ("primary".equalsIgnoreCase(type)) {
                        return Environment.getExternalStorageDirectory() + "/" + split[1];
                    }
                }
                // DownloadsProvider
                else if (isDownloadsDocument(uri)) {
//                    final String id = DocumentsContract.getDocumentId(uri);
                    final String id = documentId.toString();
                    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 docId = documentId.toString();
                    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();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * Get the value of the data column for this Uri. This is useful for
     * MediaStore Uris, and other file-based ContentProviders.
     *
     * @param context       The context.
     * @param uri           The Uri to query.
     * @param selection     (Optional) Filter used in the query.
     * @param selectionArgs (Optional) Selection arguments used in the query.
     * @return The value of the _data column, which is typically a file path.
     */
    public static String getDataColumn(Context context, Uri uri, String selection,
                                       String[] selectionArgs) {
        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = {
                column
        };
        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                    null);
            if (cursor != null && cursor.moveToFirst()) {
                final int index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }
    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }
    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }
    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }
    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    public static boolean isGooglePhotosUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    }
时间: 2024-08-07 00:16:53

解决4.4版本以上剪裁图片时提示无法加载图片的问题的相关文章

Android App 启动时显示正在加载图片(源码)

微信.QQ.天天动听等程序,在打开时显示了一张图片,然后跳转到相关界面.本文实现这个功能,其实很简单.... 新建两个Activity,LoadingActivity,MainActivity,将LoadingActivity设置为android.intent.action.MAIN.使用TimerTesk,或者Thread将LoadingActivity显示几秒后跳转到MainActivity界面. LoadingActivity: new Timer().schedule(new Timer

Java导入package编译后运行时提示无法加载主类的解决办法

Java代码中通过package导入包后,用命令行编译可以成功,但是运行时提示无法加载主类,这时候可以把编译后的class文件放在导入包的上一层文件夹,然后用 java 包名.类名 的命令形式运行 参考链接:点击这里 原文地址:https://www.cnblogs.com/excellent-ship/p/9134994.html

Android:ViewPager扩展详解——带有导航的ViewPagerIndicator(附带图片缓存,异步加载图片)

大家都用过viewpager了, github上有对viewpager进行扩展,导航风格更加丰富,这个开源项目是ViewPagerIndicator,很好用,但是例子比较简单,实际用起来要进行很多扩展,比如在fragment里进行图片缓存和图片异步加载. 下面是ViewPagerIndicator源码运行后的效果,大家也都看过了,我多此一举截几张图: 下载源码请点击这里 ===========================================华丽的分割线==============

EF连接Sqlserver2014,使用DBGeography时提示无法加载sqlserverspatial.dll

(1)确认你要使用的SqlServer版本,如果是2014,就要在nuget中添加microsoft.sqlserver.types.dll,使用12.0.4100.1这个版本,它会自动添加sqlservertypes文件夹到项目中,并自动添加一个Loader类,在Loader类中修改以下代码,指定让sqlserver使用sqlserver2014的版本使用sqlserver spatial: public static void LoadNativeAssemblies(string root

Android:ViewPager扩展的具体解释——导航ViewPagerIndicator(有图片缓存,异步加载图片)

我们已经用viewpager该. github那里viewpager扩展,导航风格更丰富.这个开源项目ViewPagerIndicator.非常好用,但样品是比较简单,实际用起来是非常不延长.例如,在fragment里进行图片缓存和图片异步载入. 以下是ViewPagerIndicator源代码执行后的效果.大家也都看过了,我多此一举截几张图. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHljNjY2NjY2NjY2NjY=/font/5a6L5

Android开发解决加载图片OOM问题(非常全面 兼顾4.0以下系统)(by 星空武哥)

转载请标明:http://blog.csdn.net/lsyz0021/article/details/51295402 我们项目中经常会加载图片,有时候如果加载图片过多的话,小则导致程序很卡,重则OOM导致App挂了,今天翻译https://developer.Android.com/training/displaying-bitmaps/index.html,学习Google高效加载大图片的方法. 图片有各种形状和大小,但在大多数情况下,这些图片都会大于我们程序所需要的大小.比如说系统图片库

android listview 滑动过程中不加载图片,停止时加载图片

今天闲来无事, 就测试了一下listview加载图片优化的功能, 在我们使用新浪微博的时候,细心的同学一定发现了,在滑动的过程中,图片是没有被加载的, 而是在滑动停止时,才加载图片了. 我们今天就做一个这样的效果吧. 我们先考虑两个问题: 1.在滑动停止的时候,如何获得需要加载的图片控件? 2.因为listiew在初始化完成的时候,OnScrollListener的onScrollStateChanged与onScroll并未被触发,如何初始化第一页的图片? package com.test.l

win32加载图片获得像素值

在写光栅渲染器时,需要加载图片获得像素以便进行纹理插值,试了几种方法发现下面这种比价简单,效率也可以接受 Texture2D是我自己定义的类,其中m_pixelBuffer是一个动态二维数组,每个元素为ZCFLOAT3(自定义类型用来保存颜色rgb值). 1 #include "LoadBitmap.h" 2 #include <windows.h> 3 #include <gdiplus.h> 4 5 #include <iostream> 6 #

UI小项目之拳皇动画的实现(抽取加载图片和播放音乐的方法)

实现思路 1.加载图片 2.播放音乐 实现思想 1.封装思想 抽取相同代码生成一个新的方法,通过传递参数调用该方法: 2.内存管理思想 不需要每次调用方法时都重新加载图片,for循环加载图片写在ViewdidLoad中 下列代码没有对运行过程中内存管理进行优化 其中加载图片有两种方法: 通过imageNmae加载有缓存 通过imageWithContentsOfFile加载无缓存 有无缓存的区别: 有缓存,使用时不需要重新加载 无缓存,使用时才加载 #import "ViewController