小米手机从相册获照片返回空指针异常
小米手机选择了图片之后,小米机会崩掉(别的机子,啥版本都没问题)。看异常信息,指示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. }