小米手机相册空指针

转自:https://blog.csdn.net/iamwutianbao/article/details/52459509
小米手机选择了图片之后,小米机会崩掉(别的机子,啥版本都没问题)。看异常信息,指示cursor.moveToFirst(),空指针异常。也就是说,cursor为空。是uri的问题,4.4之前,返回的是包含图片绝对路劲的,4.4之后,返回的不再是绝对路劲了,而是一个图片的编码。小米不论版本高低,小米机会崩掉,得到的只是一个图片编码。这时需要去转换为绝对路径,才能方便使用。下面方法是可以得到绝对路径的方法,是大神封装好了,封装成了一个pictureHelper工具类。

吐槽一下,除了小米,用ACTION_PICK,都能得到一个图片的绝对路径。如果是小米,用ACTION_PICK,就需要去转化了。但是,小米用ACTION_GET_CONTENT或者ACTION_OPEN_DOCUMENT,低版本,也能得到绝对路径。。最后统一的处理方法就是,用ACTION_GET_CONTENT,然后分版本处理,低版本还是旧的方法,高版本,用pictureHelper工具类处理得到绝对路径。

package com.xxxe.utils;

import android.annotation.SuppressLint;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;

/**

  • 小米手机获取本地相册图片出现空指针异常处理类
  • @author dec

*/

public class MiPictureHelper {

@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)) {
        // ExternalStorageProvider
        if (isExternalStorageDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            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 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;

}

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;

}

public static boolean isExternalStorageDocument(Uri uri) {
    return "com.android.externalstorage.documents".equals(uri.getAuthority());
}

public static boolean isDownloadsDocument(Uri uri) {
    return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}

public static boolean isMediaDocument(Uri uri) {
    return "com.android.providers.media.documents".equals(uri.getAuthority());
}

private static boolean isGooglePhotosUri(Uri uri) {
    return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}

}

如果是想要获取相册中图片的路径,直接这样调用:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case PICK_PICTURE:
// 选取照片
if(data!=null){
try {
Uri uri = data.getData();
String pickPath = MiPictureHelper.getPath(mContext, uri); // 获取图片路径的方法调用
System.out.println("图片路径 -->> " + pickPath);
}
}
}
}
}
====================== 我是一条分割线 ==========================

下面是其他开发者的处理方法

 * 解决小米手机上获取图片路径为null的情况  
 * @param intent  
 * @return  
 */  
 public Uri getPictureUri(android.content.Intent intent) {    
        Uri uri = intent.getData();    
        String type = intent.getType();    
        if (uri.getScheme().equals("file") && (type.contains("image/"))) {    
            String path = uri.getEncodedPath();    
            if (path != null) {    
                path = Uri.decode(path);    
                ContentResolver cr = this.getContentResolver();    
                StringBuffer buff = new StringBuffer();    
                buff.append("(").append(Images.ImageColumns.DATA).append("=")    
                        .append("'" + path + "'").append(")");    
                Cursor cur = cr.query(Images.Media.EXTERNAL_CONTENT_URI,    
                        new String[] { Images.ImageColumns._ID },    
                        buff.toString(), null, null);    
                int index = 0;    
                for (cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) {    
                    index = cur.getColumnIndex(Images.ImageColumns._ID);    
                    // set _id value    
                    index = cur.getInt(index);    
                }    
                if (index == 0) {    
                    // do nothing    
                } else {    
                    Uri uri_temp = Uri    
                            .parse("content://media/external/images/media/"    
                                    + index);    
                    if (uri_temp != null) {    
                        uri = uri_temp;    
                    }    
                }    
            }    
        }    
        return uri;    
    } 

他们这样调用方法:
if (data == null) {
return;
}
uri = data.getData();
uri = getPictureUri(data); // 方法调用
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, proj, null, null, null);
if(cursor!=null) {
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String path = cursor.getString(column_index);// 图片在的路径
Intent intent3 = new Intent(this, SYClipActivity.class);
intent3.putExtra("path", path);
startActivityForResult(intent3, IMAGE_COMPLETE);
}

你可能感兴趣的:(小米手机相册空指针)