Android; BitmapFactory.decodeFile(文件) returns 空,已知文件存在
Android; BitmapFactory.decodeFile(file) returns null, file is known to exists
我正在尝试渲染我用以下 class 拍摄的照片,其中 returns 使用的文件:
public File takePhoto(){
Intent pictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File destination= null;
try {
destination = createFile();
} catch (IOException error) {
Log.v(TAG, "IO error, reading exception");
String errorMessage = error.getMessage();
Log.v(TAG, errorMessage);
String errorCauseMessage = error.getCause().getMessage();
Log.v(TAG, errorCauseMessage);
}
if (destination != null){
Log.v(TAG, "destination was written");
pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(destination));
parentActivity.startActivityForResult(pictureIntent, REQUEST_TAKE_PHOTO);
Log.v(TAG, "destination was: " + destination.getAbsolutePath());
}
else {
Log.v(TAG, "destination was not written");
}``
return destination;
然后在以下代码中使用结果:
Log.v(TAG, "adding picture");
PhotoHandler photoHandler = new PhotoHandler(getPackageManager(), PolishCreateActivity.this);
File imgFile = photoHandler.takePhoto();
if (imgFile == null) {
Toast.makeText(this, ERROR_TOAST_TEXT, Toast.LENGTH_SHORT).show();
} else {
Log.v(TAG, "Picture added");
Log.v(TAG, "storing directory");
img = imgFile.getAbsolutePath();
Log.v(TAG, "Directory stored");
Log.v(TAG, "Displaying picture");
LinearLayout layout = (LinearLayout) findViewById(R.id.rootLayout);
if (imageViewExists == Boolean.TRUE) {
ImageView oldView = (ImageView) findViewById(R.id.imageViewID);
layout.removeView(oldView);
}
UIHelper uiHelper = new UIHelper(this.getApplicationContext());
ImageView imageView = uiHelper.getImageViewFromPath(imgFile);
imageView.setId(R.id.imageViewID);
layout.addView(imageView);
imageViewExists = Boolean.TRUE;
Log.v(TAG, "picture displayed");
并传递给此方法,如 imgFile:
public ImageView getImageViewFromPath(File imgFile) {
ImageView imageView = new ImageView(context);
Bitmap imgBM = null;
if (imgFile.exists()) {
Log.v(TAG, "image file exists");
imgBM = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
if (imgBM == null){
Log.v(TAG, "Bitmap returned was null");
}
}
imageView.setImageBitmap(imgBM);
imageView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
Log.v(TAG, "ImageView was created");
return imageView;
}
问题是 BitmapFactory.decodeFile(imgFile.getAbsolutePath) returns 每次我 运行 它,即使文件存在(我可以告诉因为我得到"if (imgFile.exists())" 正文中的日志消息)。找了很久的解决方法,一直没有找到解决办法。我已经测试过它不会导致 outOfMemory 异常,事实并非如此。任何帮助将不胜感激。
检查 imgFile.getAbsolutePath() 的值。
这个值可能为空或非法。
使用调试模式或记录此值以记录 cat。
takePhoto
开始 activity 结果:
parentActivity.startActivityForResult(pictureIntent, REQUEST_TAKE_PHOTO);
但是您的代码会像这样立即完成,但事实并非如此。
该文件当然会在那里,但它总是 0 字节大。
您需要覆盖 onActivityResult()
并从那里处理文件内容。
好的,我通过切换到通过 onActivityResult 从 Intent 获取位图解决了这个问题。
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK){
Bundle extras = data.getExtras();
photo = (Bitmap) extras.get("data");
LinearLayout layout = (LinearLayout) findViewById(R.id.rootLayout);
layout.addView(UIHelper.getImageViewFromPath(photo, getApplicationContext()));
}
}
不过我还需要保存位图。
检查您使用的 sdk 版本 sdk 版本 23 或更高版本您必须获得在设备上读写的权限..检查下面的代码可能会解决您的问题
@Override
public void onClick(View v) {
if((ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE)!=PackageManager.PERMISSION_GRANTED)
|| (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED))
{
ActivityCompat.requestPermissions
(MainActivity.this, new String[]{
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
},MY_PERMISSIONS_REQUEST_READ_AND_WRITE_EXTERNAL_STORAGE);
}
}
我正在尝试渲染我用以下 class 拍摄的照片,其中 returns 使用的文件:
public File takePhoto(){
Intent pictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File destination= null;
try {
destination = createFile();
} catch (IOException error) {
Log.v(TAG, "IO error, reading exception");
String errorMessage = error.getMessage();
Log.v(TAG, errorMessage);
String errorCauseMessage = error.getCause().getMessage();
Log.v(TAG, errorCauseMessage);
}
if (destination != null){
Log.v(TAG, "destination was written");
pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(destination));
parentActivity.startActivityForResult(pictureIntent, REQUEST_TAKE_PHOTO);
Log.v(TAG, "destination was: " + destination.getAbsolutePath());
}
else {
Log.v(TAG, "destination was not written");
}``
return destination;
然后在以下代码中使用结果:
Log.v(TAG, "adding picture");
PhotoHandler photoHandler = new PhotoHandler(getPackageManager(), PolishCreateActivity.this);
File imgFile = photoHandler.takePhoto();
if (imgFile == null) {
Toast.makeText(this, ERROR_TOAST_TEXT, Toast.LENGTH_SHORT).show();
} else {
Log.v(TAG, "Picture added");
Log.v(TAG, "storing directory");
img = imgFile.getAbsolutePath();
Log.v(TAG, "Directory stored");
Log.v(TAG, "Displaying picture");
LinearLayout layout = (LinearLayout) findViewById(R.id.rootLayout);
if (imageViewExists == Boolean.TRUE) {
ImageView oldView = (ImageView) findViewById(R.id.imageViewID);
layout.removeView(oldView);
}
UIHelper uiHelper = new UIHelper(this.getApplicationContext());
ImageView imageView = uiHelper.getImageViewFromPath(imgFile);
imageView.setId(R.id.imageViewID);
layout.addView(imageView);
imageViewExists = Boolean.TRUE;
Log.v(TAG, "picture displayed");
并传递给此方法,如 imgFile:
public ImageView getImageViewFromPath(File imgFile) {
ImageView imageView = new ImageView(context);
Bitmap imgBM = null;
if (imgFile.exists()) {
Log.v(TAG, "image file exists");
imgBM = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
if (imgBM == null){
Log.v(TAG, "Bitmap returned was null");
}
}
imageView.setImageBitmap(imgBM);
imageView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
Log.v(TAG, "ImageView was created");
return imageView;
}
问题是 BitmapFactory.decodeFile(imgFile.getAbsolutePath) returns 每次我 运行 它,即使文件存在(我可以告诉因为我得到"if (imgFile.exists())" 正文中的日志消息)。找了很久的解决方法,一直没有找到解决办法。我已经测试过它不会导致 outOfMemory 异常,事实并非如此。任何帮助将不胜感激。
检查 imgFile.getAbsolutePath() 的值。
这个值可能为空或非法。
使用调试模式或记录此值以记录 cat。
takePhoto
开始 activity 结果:
parentActivity.startActivityForResult(pictureIntent, REQUEST_TAKE_PHOTO);
但是您的代码会像这样立即完成,但事实并非如此。 该文件当然会在那里,但它总是 0 字节大。
您需要覆盖 onActivityResult()
并从那里处理文件内容。
好的,我通过切换到通过 onActivityResult 从 Intent 获取位图解决了这个问题。
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK){
Bundle extras = data.getExtras();
photo = (Bitmap) extras.get("data");
LinearLayout layout = (LinearLayout) findViewById(R.id.rootLayout);
layout.addView(UIHelper.getImageViewFromPath(photo, getApplicationContext()));
}
}
不过我还需要保存位图。
检查您使用的 sdk 版本 sdk 版本 23 或更高版本您必须获得在设备上读写的权限..检查下面的代码可能会解决您的问题
@Override
public void onClick(View v) {
if((ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE)!=PackageManager.PERMISSION_GRANTED)
|| (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED))
{
ActivityCompat.requestPermissions
(MainActivity.this, new String[]{
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
},MY_PERMISSIONS_REQUEST_READ_AND_WRITE_EXTERNAL_STORAGE);
}
}