更新2:问题与onResume
和onPause
有关。它与BitmapFactory.decodeFile()
无关。问题是,当我去拍照时,onPause
被调用,但没有任何内容保存到SharedPreferences
,因为还没有任何东西可以保存。但是一旦我从拍照中返回,就会调用onResume
并尝试通过从SharedPreferences
获取适当的值来将图像路径设置为自定义对象。由于那里没有相应的值,因此它将默认值null应用于imagePath
。
更新:我的计划的布局是ActivityA
个主机FragmentA
,其中包含您在下面看到的DialogFragment
。用户按下FragmentA
中的按钮拍照,一旦他们拍照,在onActivityResult
中我将图像路径设置为自定义对象中的字符串变量,并通过以下方式验证它是否存在致电Log.d(mObject.getImagePath(), ...)
。
然后他们可以重新按相同的图片按钮来查看图像。这是NullPointerException
发生的地方。虽然我验证了onActivityResult
中的图像路径,但是当我尝试访问它时它会返回null。这就是BitmapFactory.decodeFile()
返回null的原因 - imagePath
中的FragmentA
为空,当我尝试在DialogFragment
中将其作为额外访问时,它将为null。
任何人都可以看到为什么图像路径返回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
上的读数中,它或者是因为文件名为null或者无法解码为位图。
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 :(得分:1)
问题与BitmapFactory.decodeFile()
无关。
问题在于,当用户去拍照时,会调用onPause
。它会检查是否存在现有图像路径,如果存在,则将其保存到SharedPreferences
。用户第一次打开应用程序时,不会存在任何图像路径,因此不会保存任何内容。拍摄照片后,系统会调用onResume
并尝试从SharedPreferences
检索图像路径,但最终会分配默认值null
,因为不存在图像路径。我一直使用boolean
来跟踪何时检索onResume
中的信息,但更好的解决方案是在尝试检索之前检查值是否为null
。
if (preferences.getString("imagePath", null) != null)
{
myObject.setImagePath(preferences.getString("imagePath", null));
}
假设已经存在图像路径,原始代码将起作用。但它不会第一次运作。
我为这种困惑道歉,并感谢所有试图提供帮助的人。虽然这个问题与你的答案无关(这是我的错),但你的答案仍然有用,我会继续学习它们。
答案 1 :(得分: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);
答案 2 :(得分: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;
}