2014-10-11 99 views
0

UPDATE2:该问题与onResume和有关。它与BitmapFactory.decodeFile()无关。问题是,当我去拍照时,被调用,但没有任何内容保存到SharedPreferences,因为还没有任何要保存的东西。但是,一旦我从拍摄照片返回,将调用onResume,并尝试通过采用SharedPreferences中的适当值来设置自定义对象的图像路径。由于在那里没有对应的值,所以它将默认值应用到imagePath使用BitmapFactory和文件路径显示ImageView,返回NullPointerException

更新:我的程序的布局是ActivityA主机FragmentA其中承载此DialogFragment你看到下面。用户在FragmentA中按下一个按钮拍摄一张照片,一旦他们拍摄了照片,在onActivityResult中,我将图像路径设置为自定义对象中的字符串变量,并通过调用Log.d(mObject.getImagePath(), ...)来验证它是否存在。

然后,他们可以重新按下相同的图片按钮来查看图像。这是NullPointerException发生的地方。尽管我验证图像路径存在于onActivityResult中,但在我尝试访问它时稍后会返回null。这就是为什么BitmapFactory.decodeFile()返回空值 - 因为imagePathFragmentA中为空,当我尝试在DialogFragment中尝试访问它时,它当然为空。

任何人都可以看到为什么图像路径返回null,即使当我验证它存在于onActivityResult并将其分配给我的对象吗?我不知道为什么会发生这种情况。我有一个类似的按钮,用户可以在其中输入文本,然后再次按下按钮在对话框中查看/编辑该文本。我遵循在onActivityResult中将变量分配给我的对象的相同过程,并且我没有任何问题。

注意:如果您想查看图片是如何拍摄和保存的,请参考this回答,或者按照右侧的链接问题。

imagePath

/data/data/myPackageName/files/myInternalPicturesDir/IMG_20141011_152840.jpg

FragmentA

//onCreateView 
    mImageButton = (Button) v.findViewById(R.id.imageButton); 
    mImageButton.setOnClickListener(new View.OnClickListener() 
    { 
     public void onClick(View v) 
     { 
      if (isImageButtonFirstClick) 
      { 
       Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
       imageUri = CameraUtils.getOutputMediaFileUri(CameraUtils.MEDIA_TYPE_IMAGE); 
       intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); 
       startActivityForResult(intent, REQUEST_IMAGE); 
      } 
      else 
      { 
       try 
       { 
        Log.d("mImageButton onClick", mMyObject.getImagePath()); 
        //returns null... 
       } 
       catch (Exception e) 
       { 
        e.printStackTrace(); 
       } 

       FragmentManager fm = getActivity().getSupportFragmentManager(); 
       InputImageFragment dialog = InputImageFragment.newInstance(mMyObject.getImagePath()); 
       dialog.show(fm, DIALOG_IMAGE); 
      } 
     } 
    }); 

... 

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) 
{ 
    if (resultCode != Activity.RESULT_OK) 
    { 
     return; 
    } 
    ... 
    else if (requestCode == REQUEST_IMAGE) 
    { 
     String pathToInternallyStoredImage = CameraUtils.saveToInternalStorage(getActivity(), imageUri); 
     mMyObject.setImagePath(pathToInternallyStoredImage); 

     //verify imagePath exists, both return correct path 
     Log.d("onActivityResult pathToInternallyStoredImage", pathToInternallyStoredImage); 
     Log.d("onActivityResult mMyObject.getImagePath", mMyObject.getImagePath()); 

     isImageButtonFirstClick = false; 
     preferences.edit().putBoolean("isImageButtonFirstClick", isImageButtonFirstClick).commit(); 
    } 

DialogFragment

public static InputImageFragment newInstance(String imagePath) 
{ 
    Bundle args = new Bundle(); 
    args.putSerializable(EXTRA_IMAGEPATH, imagePath); 

    InputImageFragment fragment = new InputImageFragment(); 
    fragment.setArguments(args); 

    return fragment; 
} 

@Override 
public Dialog onCreateDialog(Bundle savedInstanceState) 
{ 
    String imagePath = (String) getArguments.getSerializable(EXTRA_IMAGEPATH); 

    try 
    { 
     Log.d("onCreateDialog imagePath", imagePath); 
     //returns null... 
    } 
    catch (Exception e) 
    { 
     e.printStackTrace(); 
    } 

    View v = getActivity().getLayoutInflater().inflate(R.layout.dialog_input_image, null); 

    final ImageView imageView = (ImageView) v.findViewById(R.id.dialogInputImageView); 
    Bitmap image = BitmapFactory.decodeFile(imagePath); 
    imageView.setImageBitmap(image); 

    return new AlertDialog.Builder(getActivity()) 
      .setView(v) 
      .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() 
      { 
       @Override 
       public void onClick(DialogInterface dialog, int whichButton) 
       { 
        dialog.cancel(); 
       } 
      }) 
      .create(); 
} 

}

这将返回一个NullPointerException,从我上BitmapFactory读书,有可能是因为该文件的名称为空或不能解码成位图。

10-13 17:10:39.498 5330-5330/myPackageName E/BitmapFactory﹕ Unable to decode stream: java.lang.NullPointerException

的对话框中显示,但是仅仅是与OK按钮一个空框。

我读过类似的问题,其中问题是ImageView本身为空。我不认为这是这里的问题,但下面是XML dialog_input_image。我试着用XML来修补,我已经把ImageView当作FrameLayout的孩子,类似于我见过的其他例子,但是我得到了同样的错误。

<?xml version="1.0" encoding="utf-8"?> 

<ImageView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/dialogInputImageView" 
    android:orientation="vertical" 
    android:scaleType="centerInside" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content"> 
</ImageView> 

我是新来的Android,所以我不知道我要去哪里错了。任何帮助表示感谢,谢谢!

+0

其中u'膨胀''onCreateView'中的布局 – kId 2014-10-15 04:49:22

+0

@kaushik由于这是一个'DialogFragment',我不会调用'onCreateView'。我在'onCreateDialog'中膨胀布局,然后当我返回一个新的'AlertDialog.Builder'时调用'setView(v)'。 – pez 2014-10-15 04:59:33

+0

BitmapFactory.decodeFile返回的位图是否为空?为这个异常附加logcat肯定会有所帮助。 – 2014-10-15 05:16:48

回答

1

该问题与BitmapFactory.decodeFile()无关。

问题是,当用户去拍照时,被调用。它检查是否存在现有的图像路径,如果存在,则将其保存到SharedPreferences。用户第一次打开该应用程序时,将不存在图像路径,因此不会保存任何内容。拍摄照片后,将调用onResume,并尝试从SharedPreferences中检索图像路径,但由于没有图像路径,因此最终分配了缺省值null。我一直在使用boolean来跟踪何时检索onResume中的信息,但更好的解决方案只是在尝试检索值之前检查值是否为null

if (preferences.getString("imagePath", null) != null) 
    { 
     myObject.setImagePath(preferences.getString("imagePath", null)); 
    } 

假设图像路径已经存在,原始代码就可以工作。但它不会第一次奏效。

我对这种困惑表示歉意,并且感谢所有想要帮助的人。虽然问题与你的答案无关(这是我的错),但你的答案仍然有帮助,我将在我继续学习时加以实施。

0

你最好使用Context方法getFilesDir()从内部存储读取,如:

String image path = getFilesDir() .getAbsolutePath(); + "/myInternalPicturesDir/IMG_20141011_152840.jpg"; 
final ImageView imageView = (ImageView) v.findViewById(R.id.dialogInputImageView); 
Bitmap image = BitmapFactory.decodeFile(imagePath); 
imageView.setImageBitmap(image); 
+0

感谢您的回复。从我的'DialogFragment'调用'getActivity()。getFilesDir()。getAbsolutePath();'只需返回'/ data/data/myPackageName/files'。不会产生'imagePath''字符串仍然是相同的? – pez 2014-10-11 23:38:34

+0

你可以通过你的文章完整的堆栈跟踪? – ToYonos 2014-10-11 23:49:26

+0

当然。这是它显示的全部内容:'10-11 16:35:56.098 31000-31000/myPackageName E/BitmapFactory:无法解码流:java.lang.NullPointerException' – pez 2014-10-11 23:51:27

0

改变你的Uri为位图首先从下面的代码获取其路径前,然后将其设置

.......... 
Bitmap image = BitmapFactory.decodeFile(getRealPathFromURI(URI)); 
} 

public String getRealPathFromURI(Uri contentURI) throws Exception { 
    String result; 
    Cursor cursor = context.getContentResolver().query(contentURI, null, 
      null, null, null); 
    if (cursor == null) { 
     result = contentURI.getPath(); 
    } else { 
     cursor.moveToFirst(); 
     int idx = cursor 
       .getColumnIndex(MediaStore.Images.ImageColumns.DATA); 
     result = cursor.getString(idx); 
     cursor.close(); 
    } 
    return result; 
}