小米手机Attempt to invoke interface method 'boolean android.database.Cursor.moveToFirst()'

原文:http://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工具类处理得到绝对路径。

[java]  view plain  copy
 
  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.                 Uri.parse("content://downloads/public_downloads"),  
  42.                 Long.valueOf(id));  
  43.                 return getDataColumn(context, contentUri, nullnull);  
  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.                 Uri contentUri = 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, nullnull);  
  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.         Cursor cursor = null;  
  81.         final String column = "_data";  
  82.         final String[] projection = { column };  
  83.         try {  
  84.             cursor = context.getContentResolver().query(uri, projection,  
  85.             selection, selectionArgs, 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. }  

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

[java]  view plain  copy
 
  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.                 String pickPath = MiPictureHelper.getPath(mContext, uri);  // 获取图片路径的方法调用  
  9.                 System.out.println("图片路径 -->> " + pickPath);  
  10.                 }  
  11.             }  
  12.         }  
  13.     }  
  14. }  

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


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

[java]  view plain  copy
 
  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.                ContentResolver cr = this.getContentResolver();      
  13.                StringBuffer buff = new StringBuffer();      
  14.                buff.append("(").append(Images.ImageColumns.DATA).append("=")      
  15.                        .append("'" + path + "'").append(")");      
  16.                Cursor cur = cr.query(Images.Media.EXTERNAL_CONTENT_URI,      
  17.                        new String[] { Images.ImageColumns._ID },      
  18.                        buff.toString(), nullnull);      
  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.                            .parse("content://media/external/images/media/"      
  30.                                    + index);      
  31.                    if (uri_temp != null) {      
  32.                        uri = uri_temp;      
  33.                    }      
  34.                }      
  35.            }      
  36.        }      
  37.        return uri;      
  38.    }   

他们这样调用方法:

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

你可能感兴趣的:(Android开发错误积累)