2015-10-28 57 views
0

我正在开发一个遵循教程的Android上的学生注册应用程序。我需要创建一个新的学生在手机上保存照片。从Android的内部存储器获取图像时出现NullPointerException

问题是我无法从检索到的URI加载图像。

我的 “脚本” 日志打印:

Img uri: content://com.android.providers.media.documents/document/image%3A30 

但我imgString为空。

我正在使用genymotion模拟器。

这里是调用库的代码...

public void loadImage(View view){ 
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT); 
    intent.setType("image/*"); 
    startActivityForResult(intent, IMG_SDCARD_ACTIVITY); 
} 

这是处理来自画廊的答案onActivityResult ...

@Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     File file; 
     String pass = null; 
     Log.i("Script", "RequestCode: "+requestCode+" ResultCode: "+resultCode); 
     if(requestCode == IMG_SDCARD_ACTIVITY && resultCode == Activity.RESULT_OK){ 
      try{ 
       Uri img = data.getData(); 
       Log.i("Script", "Img uri: "+img.toString()); 
       String[] cols = {MediaStore.Images.Media.DATA}; 
       Cursor cursor = getContentResolver().query(img, cols, null, null, null); 
       cursor.moveToFirst(); 

       int indexCol = cursor.getColumnIndex(cols[0]); 
       String imgString = cursor.getString(indexCol); 
       cursor.close(); 

       file = new File(imgString); //this is the line 108 where the problem is... 
       ivImg.setImageBitmap(ImageUtil.setPic(Uri.fromFile(file), 100, 100)); 
       ivImg.setContentDescription(file.getPath()); 
       pass = "passou"; 
      } 
      catch (NullPointerException e){e.printStackTrace();} 
      catch (Exception e){e.printStackTrace();} 
      finally { 
       if(pass==null){ 
        ivImg.setImageResource(R.drawable.person); 
        Toast.makeText(SalvarAlunoActivity.this, "Fail! Try again.", Toast.LENGTH_SHORT).show(); 
      } 
     } 
    } 
} 

这是ImageUtil类。 ..

public class ImageUtil { 
    public static Bitmap setPic(Uri uriFile, int width, int height){ 
     //Get the dimensions of the view 
     int targetW = width; 
     int targetH = height; 

     //Get the dimensions of the Bitmap 
     BitmapFactory.Options bmOptions = new BitmapFactory.Options(); 
     bmOptions.inJustDecodeBounds = true; 
     BitmapFactory.decodeFile(uriFile.getPath(), bmOptions); 
     int photoW = bmOptions.outWidth; 
     int photoH = bmOptions.outHeight; 

     //Determine how much to scale down the image 
     int scaleFactor = Math.min(photoW/targetW, photoH/targetH); 

     //Decode the image file into a Bitmap sized to fill the View 
     bmOptions.inJustDecodeBounds = false; 
     bmOptions.inSampleSize = scaleFactor; 
     bmOptions.inPurgeable = true; 

     Bitmap bitmap = BitmapFactory.decodeFile(uriFile.getPath(), bmOptions); 
     return(bitmap); 
} 

}

日志打印也是这个错误...

10-28 08:19:45.602 10874-10874/? W/System.err﹕ java.lang.NullPointerException 
10-28 08:19:45.606 10874-10874/? W/System.err﹕ at java.io.File.fixSlashes(File.java:185) 
10-28 08:19:45.606 10874-10874/? W/System.err﹕ at java.io.File.<init>(File.java:134) 
10-28 08:19:45.606 10874-10874/? W/System.err﹕ at com.XXXX.contentProvider.SalvarAlunoActivity.onActivityResult(SalvarAlunoActivity.java:108) 
10-28 08:19:45.606 10874-10874/? W/System.err﹕ at android.app.Activity.dispatchActivityResult(Activity.java:5423) 
10-28 08:19:45.606 10874-10874/? W/System.err﹕ at android.app.ActivityThread.deliverResults(ActivityThread.java:3347) 
10-28 08:19:45.606 10874-10874/? W/System.err﹕ at android.app.ActivityThread.handleSendResult(ActivityThread.java:3394) 
10-28 08:19:45.606 10874-10874/? W/System.err﹕ at android.app.ActivityThread.access$1300(ActivityThread.java:135) 
10-28 08:19:45.606 10874-10874/? W/System.err﹕ at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1244) 
10-28 08:19:45.606 10874-10874/? W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:102) 
10-28 08:19:45.606 10874-10874/? W/System.err﹕ at android.os.Looper.loop(Looper.java:136) 
10-28 08:19:45.606 10874-10874/? W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:5001) 
10-28 08:19:45.606 10874-10874/? W/System.err﹕ at java.lang.reflect.Method.invokeNative(Native Method) 
10-28 08:19:45.606 10874-10874/? W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:515) 
10-28 08:19:45.606 10874-10874/? W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) 
10-28 08:19:45.606 10874-10874/? W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 
10-28 08:19:45.606 10874-10874/? W/System.err﹕ at dalvik.system.NativeStart.main(Native Method) 

这里它了我的第一次。让我知道是否需要提供更多信息。

在此先感谢。

+0

这是什么问题? resultCode = -1或requestCode = -1 – activesince93

+0

-1的结果代码是'RESULT_OK'。请详细解释为什么这是一个问题。 – CommonsWare

+0

其实它确实不是问题。我现在已经检查过了......事情是我无法加载图像。我会编辑帖子。 – DMS

回答

1

您的文件路径为空。从Gallery中选择图片时,您可以直接从uri获得Bitmap。因此,在您onActivityResult方法做这样的事情:

Uri fileUri = data.getData(); 
Bitmap b = decodeUri(fileUri); 
your_image_view.setImageBitmap(b); 


// here decodeUri method will directly return you Bitmap which can be set to imageview 

private Bitmap decodeUri(Uri selectedImage) throws FileNotFoundException 
    { 
     BitmapFactory.Options o = new BitmapFactory.Options(); 

     o.inJustDecodeBounds = true; 

     BitmapFactory.decodeStream(getContentResolver() 
       .openInputStream(selectedImage), null, o); 

     final int REQUIRED_SIZE = 72; 

     int width_tmp = o.outWidth, height_tmp = o.outHeight; 

     int scale = 1; 

     while (true) 
     { 
      if (width_tmp/2 < REQUIRED_SIZE || height_tmp/2 < REQUIRED_SIZE) 
      { 
       break; 
      } 
      width_tmp /= 2; 

      height_tmp /= 2; 

      scale *= 2; 
     } 

     BitmapFactory.Options o2 = new BitmapFactory.Options(); 

     o2.inSampleSize = scale; 

     Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver() 
       .openInputStream(selectedImage), null, o2); 

     return bitmap; 
    } 

编辑:

对于开放的解释见@CommonsWare答案。他还提到关于毕加索这是非常有用的图书馆的android在Android中有效地加载图像。

+0

谢谢Zubair! @CommonsWare完美地解释了这个理论,但是你的代码和他的解释为我省下了很多,因为你展示了解决问题所需的代码示例,并引用了CommonsWare的解释。 – DMS

1

A Uri is not a file。您从ACTION_GET_CONTENT请求中获得的Uri不必指向文件,更不用说您可以在文件系统上访问自己的文件了。另外,您从ACTION_GET_CONTENT请求中获得的Uri不必是MediaStore中的一个,并且在任何情况下MediaStore都不必返回DATA值。

我不知道做什么ImageUtil.setPic(),但如果它需要一个Uri作为输入,通过在实际Uri你取回onActivityResult()setPic()希望使用ContentResolveropenInputStream()下盖。

更好的是使用图像加载库,如PicassoUniversal Image Loader,因此所有磁盘I/O和位图解码都可以在后台线程上完成。

+0

非常适合关于Uri的解释+1 –

+0

Hi CommonsWare!谢谢回复。我将添加ImageUtil类以更好地理解。 – DMS

0

我认为上面的答案涵盖了您经历的错误,但作为一条经验法则,您绝对不应该假设cursor.moveToFirst()会起作用,而是将其包装在if中,因为它返回布尔值。

if(cursor.moveToFirst()) 
{ 
    //Do something here 
} 
相关问题