使用ACTION_IMAGE_CAPTURE拍摄的图像 - 第一个decodeStream调用失败,其他正常

时间:2016-05-13 05:44:09

标签: android

我正在使用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的第一次调用总是失败,之后的所有其他调用都很好,即使它们之后立即发生(=在同一方法中)。因此,异步写入可能不是问题。但还有别的。但是什么?

3 个答案:

答案 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);
                }
            }


}
}