BitmapFactory.decodeFile 为空,除非我等待接受照片
BitmapFactory.decodeFile is null unless I WAIT to accept photo
我有一个奇怪的问题,似乎只发生在我的一台运行 android 6 的平板电脑上。
我有这段代码可以将相机拍摄的照片添加到 recycler view
1) 我在设备上创建了一个文件对象(这是照片)
2) 我从那个文件
得到 uri
3) 我创建了一个意图传递 uri
就这样
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getActivity().getPackageManager()) != null)
// this is done in a fragment, everything else below is in the if statement
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(take_photo_intent, option_int);
我知道 MediaStore.EXTRA_OUTPUT
不会 return 任何东西到 onActivityResult
,而是写入你传入的 uri
。
现在 onActivityResult
我有
Log.i("PHOTO", "path--->" + uri.getPath());
所以我想提一下,当程序工作或 不 工作时,uri
ALWAYS 有一个路径,路径之一的一个例子是
/storage/emulated/0/data/20161212_175150797715155.jpg
所以要在 onActivityResult
中继续
5) 根据 uri
路径创建位图以供稍后使用
BitmapFactory.Options bitmap_options = new BitmapFactory.Options();
bitmap_options.inPreferredConfig = Bitmap.Config.ARGB_8888;
*************** problem here ****************
Bitmap temp = BitmapFactory.decodeFile(uri.getPath());
临时位图returns null SOME的时间,让我解释一下
当我拍照时,asus android 6 平板电脑在拍照时显示两个按钮,一个按钮用于丢弃照片,另一个按钮用于保留照片..这是奇怪的部分,ON那个屏幕,如果我在按下按钮之前等待 5-15 秒以保留照片,bitmap
将不会为空,但如果我拍照并立即接受它,位图为空。
现在如前所述,不管我怎么做,如果 bitmap
输出为 null,或者它没有输出 null,它在将它传递到 [=31 之前总是有一个路径=] 函数(这很奇怪)
我不知道是不是相机软件,物理相机硬件,android 6 bug....
我还想说,我不确定这是否是最好的代码,但它已在其他 4 种 android 设备(手机、平板电脑)上运行,只是这一款平板电脑是华硕和只有一个 android 6,它适用于其他一切
编辑:
我按照建议试过了
Bitmap TEMP = null;
try {
TEMP = BitmapFactory.decodeStream(getContext().getContentResolver().openInputStream(uri));
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
运气不好
编辑 2:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1 && resultCode == Activity.RESULT_OK) {
BitmapFactory.Options bitmap_options = new BitmapFactory.Options();
bitmap_options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap TEMP = BitmapFactory.decodeFile(uri.getPath());
Bitmap bitmap_image = ThumbnailUtils.extractThumbnail(TEMP, THUMBNAIL_SIZE, THUMBNAIL_SIZE);
if (bitmap_image == null)
Log.i("PHOTO", "BITMAP THUMBNAIL NULL");
setAdapterBitmap(bitmap_image, uri.getPath(), 1);
}
}
解决方案:
我用这个方法创建了一个 File
对象并将它变成了一个 URI
对象
private File createFileForImage() throws IOException {
String file_creation_time = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
String image_file_name = DIR_NAME + "_" + file_creation_time;
File storage_dir = new File(String.valueOf(Environment.getExternalStorageDirectory()), DIR_NAME);
if (!storage_dir.exists())
{
if(!storage_dir.mkdir())
{
return null;
}
}
return File.createTempFile(image_file_name, ".jpg", storage_dir);
}
然后我用了这个 return
uri = Uri.fromFile(image_file);
但由于某种原因,这是有效的,但它有轻微的延迟,导致原始 post
中所述的奇怪行为
Jan Kaufmann 的建议似乎有效,我做了一些小修改
private Uri getOutputMediaUriFromFile()
{
File photo_storage_dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), DIR_NAME);
if (!photo_storage_dir.exists())
{
if (!photo_storage_dir.mkdirs())
{
return null;
}
}
String file_creation_time = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
String image_file_name = "ipr" + "_" + file_creation_time;
File photo = new File(photo_storage_dir.getPath() + File.separator + image_file_name + ".jpg");
return Uri.fromFile(photo);
}
它的作用基本相同,但出于某种原因,这不会导致我遇到的问题,至少在我的测试中不会。
我很高兴这现在可以工作了,但是谁能解释为什么会这样吗?
试试这个家伙:
温度 = MediaStore.Images.Media.getBitmap(context.getContentResolver(), YOUR_URL);
如果这不起作用,我猜您没有创建临时文件来保存图像。
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
try{
GEY_FILE;
}catch (Exception ex){
Log.i(TAG, "run: " + ex);
}
}
}, 15000);
确保图片尺寸不要太大。如果需要,对原始图像进行子采样以节省内存
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inSampleSize = 8;
确保您拥有
的权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
或者尝试将您的 URI 构造成这样的内容:
Uri uri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE, "myimage");
其中 getOutputMediaFileUri 是:
private File getOutputMediaFile(int type, String imgname) {
// External sdcard location
//public static String DIRECTORY_PICTURES = "Pictures";
File mediaStorageDir = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), IMAGE_DIRECTORY_NAME);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d(IMAGE_DIRECTORY_NAME, "Oops! Failed create "
+ IMAGE_DIRECTORY_NAME + " directory");
return null;
}
}
File mediaFile;
if (type == MEDIA_TYPE_IMAGE) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + imgname + ".jpg");
} else {
return null;
}
return mediaFile;
}
我有一个奇怪的问题,似乎只发生在我的一台运行 android 6 的平板电脑上。
我有这段代码可以将相机拍摄的照片添加到 recycler view
1) 我在设备上创建了一个文件对象(这是照片)
2) 我从那个文件
得到uri
3) 我创建了一个意图传递 uri
就这样
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getActivity().getPackageManager()) != null)
// this is done in a fragment, everything else below is in the if statement
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(take_photo_intent, option_int);
我知道 MediaStore.EXTRA_OUTPUT
不会 return 任何东西到 onActivityResult
,而是写入你传入的 uri
。
现在 onActivityResult
我有
Log.i("PHOTO", "path--->" + uri.getPath());
所以我想提一下,当程序工作或 不 工作时,uri
ALWAYS 有一个路径,路径之一的一个例子是
/storage/emulated/0/data/20161212_175150797715155.jpg
所以要在 onActivityResult
5) 根据 uri
路径创建位图以供稍后使用
BitmapFactory.Options bitmap_options = new BitmapFactory.Options();
bitmap_options.inPreferredConfig = Bitmap.Config.ARGB_8888;
*************** problem here ****************
Bitmap temp = BitmapFactory.decodeFile(uri.getPath());
临时位图returns null SOME的时间,让我解释一下
当我拍照时,asus android 6 平板电脑在拍照时显示两个按钮,一个按钮用于丢弃照片,另一个按钮用于保留照片..这是奇怪的部分,ON那个屏幕,如果我在按下按钮之前等待 5-15 秒以保留照片,bitmap
将不会为空,但如果我拍照并立即接受它,位图为空。
现在如前所述,不管我怎么做,如果 bitmap
输出为 null,或者它没有输出 null,它在将它传递到 [=31 之前总是有一个路径=] 函数(这很奇怪)
我不知道是不是相机软件,物理相机硬件,android 6 bug....
我还想说,我不确定这是否是最好的代码,但它已在其他 4 种 android 设备(手机、平板电脑)上运行,只是这一款平板电脑是华硕和只有一个 android 6,它适用于其他一切
编辑:
我按照建议试过了
Bitmap TEMP = null;
try {
TEMP = BitmapFactory.decodeStream(getContext().getContentResolver().openInputStream(uri));
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
运气不好
编辑 2:
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 1 && resultCode == Activity.RESULT_OK) { BitmapFactory.Options bitmap_options = new BitmapFactory.Options(); bitmap_options.inPreferredConfig = Bitmap.Config.ARGB_8888; Bitmap TEMP = BitmapFactory.decodeFile(uri.getPath()); Bitmap bitmap_image = ThumbnailUtils.extractThumbnail(TEMP, THUMBNAIL_SIZE, THUMBNAIL_SIZE); if (bitmap_image == null) Log.i("PHOTO", "BITMAP THUMBNAIL NULL"); setAdapterBitmap(bitmap_image, uri.getPath(), 1); } }
解决方案:
我用这个方法创建了一个 File
对象并将它变成了一个 URI
对象
private File createFileForImage() throws IOException {
String file_creation_time = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
String image_file_name = DIR_NAME + "_" + file_creation_time;
File storage_dir = new File(String.valueOf(Environment.getExternalStorageDirectory()), DIR_NAME);
if (!storage_dir.exists())
{
if(!storage_dir.mkdir())
{
return null;
}
}
return File.createTempFile(image_file_name, ".jpg", storage_dir);
}
然后我用了这个 return
uri = Uri.fromFile(image_file);
但由于某种原因,这是有效的,但它有轻微的延迟,导致原始 post
中所述的奇怪行为Jan Kaufmann 的建议似乎有效,我做了一些小修改
private Uri getOutputMediaUriFromFile()
{
File photo_storage_dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), DIR_NAME);
if (!photo_storage_dir.exists())
{
if (!photo_storage_dir.mkdirs())
{
return null;
}
}
String file_creation_time = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
String image_file_name = "ipr" + "_" + file_creation_time;
File photo = new File(photo_storage_dir.getPath() + File.separator + image_file_name + ".jpg");
return Uri.fromFile(photo);
}
它的作用基本相同,但出于某种原因,这不会导致我遇到的问题,至少在我的测试中不会。
我很高兴这现在可以工作了,但是谁能解释为什么会这样吗?
试试这个家伙:
温度 = MediaStore.Images.Media.getBitmap(context.getContentResolver(), YOUR_URL);
如果这不起作用,我猜您没有创建临时文件来保存图像。
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
try{
GEY_FILE;
}catch (Exception ex){
Log.i(TAG, "run: " + ex);
}
}
}, 15000);
确保图片尺寸不要太大。如果需要,对原始图像进行子采样以节省内存
BitmapFactory.Options opt = new BitmapFactory.Options(); opt.inSampleSize = 8;
确保您拥有
的权限<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
或者尝试将您的 URI 构造成这样的内容:
Uri uri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE, "myimage");
其中 getOutputMediaFileUri 是:
private File getOutputMediaFile(int type, String imgname) {
// External sdcard location
//public static String DIRECTORY_PICTURES = "Pictures";
File mediaStorageDir = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), IMAGE_DIRECTORY_NAME);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d(IMAGE_DIRECTORY_NAME, "Oops! Failed create "
+ IMAGE_DIRECTORY_NAME + " directory");
return null;
}
}
File mediaFile;
if (type == MEDIA_TYPE_IMAGE) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + imgname + ".jpg");
} else {
return null;
}
return mediaFile;
}