Android的; BitmapFactory.decodeFile(file)返回null,已知文件存在

时间:2015-03-06 10:21:20

标签: java android bitmapfactory

我正在尝试使用以下类渲染我拍摄的照片,该照片将返回使用过的文件:

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)每次运行都会返回,即使该文件存在(我可以告诉因为我在“if(imgFile.exists())中获取日志消息“ 身体)。我已经搜索了很长时间的解决方案,但我还没有找到解决方案。我测试过它没有导致outOfMemory异常,但事实并非如此。任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:1)

检查您用于sdk 23或更高版本的sdk版本,您必须获得读取和写入设备的权限。检查以下代码可能会解决您的问题

@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);
        }
}

答案 1 :(得分:0)

检查imgFile.getAbsolutePath()的值。

该值可能为空或非法。

使用调试模式或记录此值以记录cat。

答案 2 :(得分:0)

takePhoto为结果启动活动:

parentActivity.startActivityForResult(pictureIntent, REQUEST_TAKE_PHOTO);

但是你的代码会像现在这样进行,但实际上并非如此。 该文件当然会存在,但它总是大0字节。

您需要覆盖onActivityResult()并从那里处理文件内容。

答案 3 :(得分:0)

好的,我通过切换到通过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()));
    }
}

但我仍然需要保存位图。