小米手机从相册获照片返回空指针异常

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


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


1. package com.xxxe.utils;  
2.   
3. import android.annotation.SuppressLint;  
4. import android.content.ContentUris;  
5. import android.content.Context;  
6. import android.database.Cursor;  
7. import android.net.Uri;  
8. import android.os.Build;  
9. import android.os.Environment;  
10. import android.provider.DocumentsContract;  
11. import android.provider.MediaStore;  
12.       
13. /**
14.  *  小米手机获取本地相册图片出现空指针异常处理类
15.  * @author dec
16.  *
17.  */  
18.   
19. public class MiPictureHelper {  
20.       
21.       
22.   
23. @SuppressLint("NewApi")  
24. public static String getPath(final Context context, final Uri uri) {  
25. final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;  
26. // DocumentProvider  
27. if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {  
28. // ExternalStorageProvider  
29. if (isExternalStorageDocument(uri)) {  
30. final String docId = DocumentsContract.getDocumentId(uri);  
31. final String[] split = docId.split(":");  
32. final String type = split[0];  
33. if ("primary".equalsIgnoreCase(type)) {  
34. return Environment.getExternalStorageDirectory() + "/" + split[1];  
35.                 }  
36.             }  
37. // DownloadsProvider  
38. else if (isDownloadsDocument(uri)) {  
39. final String id = DocumentsContract.getDocumentId(uri);  
40. final Uri contentUri = ContentUris.withAppendedId(  
41. "content://downloads/public_downloads"),  
42.                 Long.valueOf(id));  
43. return getDataColumn(context, contentUri, null, null);  
44.             }  
45. // MediaProvider  
46. else if (isMediaDocument(uri)) {  
47. final String docId = DocumentsContract.getDocumentId(uri);  
48. final String[] split = docId.split(":");  
49. final String type = split[0];  
50. null;  
51. if ("image".equals(type)) {  
52.                     contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;  
53. else if ("video".equals(type)) {  
54.                     contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;  
55. else if ("audio".equals(type)) {  
56.                     contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;  
57.                 }  
58. final String selection = "_id=?";  
59. final String[] selectionArgs = new String[] { split[1] };  
60. return getDataColumn(context, contentUri, selection,  
61.                 selectionArgs);  
62.             }  
63.         }  
64. // MediaStore (and general)  
65. else if ("content".equalsIgnoreCase(uri.getScheme())) {  
66. // Return the remote address  
67. if (isGooglePhotosUri(uri))  
68. return uri.getLastPathSegment();  
69. return getDataColumn(context, uri, null, null);  
70.         }  
71. // File  
72. else if ("file".equalsIgnoreCase(uri.getScheme())) {  
73. return uri.getPath();  
74.         }  
75. return null;  
76.   
77.     }  
78.   
79. public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {  
80. null;  
81. final String column = "_data";  
82. final String[] projection = { column };  
83. try {  
84.             cursor = context.getContentResolver().query(uri, projection,  
85. null);  
86. if (cursor != null && cursor.moveToFirst()) {  
87. final int index = cursor.getColumnIndexOrThrow(column);  
88. return cursor.getString(index);  
89.             }  
90. finally {  
91. if (cursor != null)  
92.                 cursor.close();  
93.         }  
94. return null;  
95.   
96.     }  
97.   
98. public static boolean isExternalStorageDocument(Uri uri) {  
99. return "com.android.externalstorage.documents".equals(uri.getAuthority());  
100.     }  
101.   
102. public static boolean isDownloadsDocument(Uri uri) {  
103. return "com.android.providers.downloads.documents".equals(uri.getAuthority());  
104.     }  
105.   
106. public static boolean isMediaDocument(Uri uri) {  
107. return "com.android.providers.media.documents".equals(uri.getAuthority());  
108.     }  
109.   
110. private static boolean isGooglePhotosUri(Uri uri) {  
111. return "com.google.android.apps.photos.content".equals(uri.getAuthority());  
112.     }  
113.   
114. }



如果是想要获取相册中图片的路径,直接这样调用:


 


1. protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
2. switch (requestCode) {  
3. case PICK_PICTURE:  
4. // 选取照片  
5. if(data!=null){  
6. try {  
7.                 Uri uri = data.getData();  
8. // 获取图片路径的方法调用  
9. "图片路径 -->> " + pickPath);  
10.                 }  
11.             }  
12.         }  
13.     }  
14. }


====================== 我是一条分割线 ==========================

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




 
1. * 解决小米手机上获取图片路径为null的情况    
2. * @param intent    
3. * @return    
4. */    
5. public Uri getPictureUri(android.content.Intent intent) {      
6.        Uri uri = intent.getData();      
7.        String type = intent.getType();      
8. if (uri.getScheme().equals("file") && (type.contains("image/"))) {      
9.            String path = uri.getEncodedPath();      
10. if (path != null) {      
11.                path = Uri.decode(path);      
12. this.getContentResolver();      
13. new StringBuffer();      
14. "(").append(Images.ImageColumns.DATA).append("=")      
15. "'" + path + "'").append(")");      
16.                Cursor cur = cr.query(Images.Media.EXTERNAL_CONTENT_URI,      
17. new String[] { Images.ImageColumns._ID },      
18. null, null);      
19. int index = 0;      
20. for (cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) {      
21.                    index = cur.getColumnIndex(Images.ImageColumns._ID);      
22. // set _id value      
23.                    index = cur.getInt(index);      
24.                }      
25. if (index == 0) {      
26. // do nothing      
27. else {      
28.                    Uri uri_temp = Uri      
29. "content://media/external/images/media/"      
30.                                    + index);      
31. if (uri_temp != null) {      
32.                        uri = uri_temp;      
33.                    }      
34.                }      
35.            }      
36.        }      
37. return uri;      
38.    }


他们这样调用方法:

1. <span style="white-space:pre">    </span>if (data == null) {    
2. return;    
3.     }    
4.     uri = data.getData();    
5. // 方法调用  
6.         String[] proj = { MediaStore.Images.Media.DATA };    
7. null, null, null);    
8. if(cursor!=null) {    
9. int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);    
10.                 cursor.moveToFirst();    
11. // 图片在的路径    
12. new Intent(this, SYClipActivity.class);    
13. "path", path);    
14.                 startActivityForResult(intent3, IMAGE_COMPLETE);    
15.     }