我正在使用ACTION_IMAGE_CAPTURE
与预定的目标Uri,就像文档中建议的那样。但是,当我尝试在活动获取后立即解码图像时,decodeStream()
失败。如果我几秒后再试一次,它运行正常。我想这个文件是在后台异步写的。我怎样才能知道什么时候可以使用?
以下是我的代码的关键部分:
确定目标文件名:
String filename = String.format("pic%d.jpg", new Date().getTime());
File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), filename);
try {
file.createNewFile();
} catch (IOException e) {
file = new File(context.getFilesDir(), filename);
}
targetUri = Uri.fromFile(photoFile);
拍照:
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, targetUri);
fragment.startActivityForResult(takePictureIntent, RESULT_TAKE_PICTURE);
在onActivityResult()
:
if (resultCode == Activity.RESULT_OK) {
if (data != null) {
// Note that data.getData() is null here.
InputStream is = getContentResolver().openInputStream(targetUri);
if (is != null) {
Bitmap bm = BitmapFactory.decodeStream(is);
decodeStream
返回null。如果我在几秒钟之后再次拨打同一个电话,它就会成功。有什么能告诉我这个文件何时可用?
更新:根据greenapps的建议,我首先与decodeStream
进行inJustDecodeBounds
通话,以获取维度以查看是否存在内存问题。原来这个第一个边界只有解码传递失败,但现在紧接着的实际decodeStream调用成功了!如果我再做两次,他们都会成功!
所以似乎对decodeStream
的第一次调用总是失败,之后的所有其他调用都很好,即使它们之后立即发生(=在同一方法中)。因此,异步写入可能不是问题。但还有别的。但是什么?
答案 0 :(得分:2)
if (requestCode == Utility.GALLERY_PICTURE) {
Uri selectedImageUri = null;
try {
selectedImageUri = data.getData();
if (mImgProfilePic != null) {
// mImgProfilePic.setImageURI(selectedImageUri);
mImgProfilePic.setImageBitmap(decodeUri(getActivity(),
selectedImageUri, 60));
// decodeUri
}
} catch (Exception e) {
}
// //////////////
try {
// Bundle extras = data.getExtras();
// // get the cropped bitmap
// Bitmap thePic = extras.getParcelable("data");
// mImgProfilePic.setImageBitmap(thePic);
final Uri tempUri = selectedImageUri;
Log.d("check", "uri " + tempUri);
// http://dev1.brainpulse.org/quickmanhelp/webservice/api.php?act=companylogo
upLoadServerUri = "http://dev1.brainpulse.org/quickmanhelp/webservice/api.php?act=employee_profile_pic&image=";
upLoadServerUri = Utility.EMPLOYEE_PROFILE_PIC_URL
+ "&employee_id=" + empId;
dialog = ProgressDialog.show(getActivity(), "",
"Uploading file...", true);
new Thread(new Runnable() {
public void run() {
getActivity().runOnUiThread(new Runnable() {
public void run() {
// messageText.setText("uploading started.....");
}
});
uploadFilePath = getRealPathFromURI(tempUri);
uploadFile(uploadFilePath + "");
// uploadFile(tempUri+"");
}
}).start();
} catch (Exception e) {
}
// ///////
}
答案 1 :(得分:0)
public static void updateFile(File file ,Context context) {
MediaScannerConnection.scanFile(context,
new String[]{file.getAbsolutePath()}, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
}
}
);
}
我认为您可以在openInputStream之前使用它来更新。
答案 2 :(得分:0)
从您分享的片段我知道您将图像文件设置为文件变量文件
File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), filename);
但是您要从文件 photoFile 设置图片Uri,这可能是空的
targetUri = Uri.fromFile(photoFile);
所以基本上你需要用targetUri = Uri.fromFile(photoFile);
targetUri = Uri.fromFile(file);
或者甚至更好 data.getData()
会像这样直接返回Image URi
InputStream is = null;
try {
is = getContentResolver().openInputStream(data.getData());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (is != null) {
Bitmap bm = BitmapFactory.decodeStream(is);
((ImageView) findViewById(R.id.imageView1)).setImageBitmap(bm);
}
您仍然需要解码位图以避免OOM异常,您可以使用Glide
使用图像URI加载图像。
在Xpria C上测试的完整类
package com.example.test;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
public class TestActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
findViewById(R.id.take_picture).setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View v) {
dispatchTakePictureIntent();
}
});
}
static final int REQUEST_TAKE_PHOTO = 1;
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
protected static final int RESULT_TAKE_PICTURE = 100;
private File createImageFile() throws IOException {
// Create an image file name
String filename = String.format("pic%d.jpg", new Date().getTime());
File file = new File(
getExternalFilesDir(Environment.DIRECTORY_PICTURES), filename);
try {
file.createNewFile();
} catch (IOException e) {
file = new File(getFilesDir(), filename);
}
return file;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) {
InputStream is = null;
try {
is = getContentResolver().openInputStream(data.getData());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (is != null) {
Bitmap bm = BitmapFactory.decodeStream(is);
((ImageView) findViewById(R.id.imageView1)).setImageBitmap(bm);
}
}
}
}