首页 > 解决方案 > Android:无法加载从相机保存的照片

问题描述

我在用相机拍照并在活动中显示时遇到问题。基本上照片没有被加载并且 BitmapFactory.decodeStream 返回 null。奇怪的是,如果我在调试中等待一段时间,它就会被加载。虽然这种行为并不一致。我还使用com.isseiaoki.simplecropview.CropImageView来裁剪处理位图解码的图像。这是相关代码:

活动:

private final String DATA_PATH = "/mnt/sdcard/ocr/";
private void init() {
            if (getIntent().getIntExtra(KEY_SHOULD_OPEN, 0) == CAMERA) {
                tryOpenCamera();
            } else {
                openGallery();
            }

            createImageFile();
        }

    public void createImageFile(){
            File photo;
            try
            {
                // place where to store camera taken picture
                photo = createTemporaryFile("picture", ".jpg");
            }
            catch(Exception e)
            {
                showGenericErrorDialog();
                photo = null;
            }
            if(photo != null){

                photoUri = FileProvider.getUriForFile(this, getApplicationContext().getPackageName() + ".provider", photo);
            }
        }


        private File createTemporaryFile(String part, String ext) throws Exception
        {
            File tempDir=new File(DATA_PATH);

            if(!tempDir.exists())
            {
                tempDir.mkdirs();
            }
            return File.createTempFile(part, ext, tempDir);
        }

    private void openCamera() {
            Intent takePictureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
            startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
        }

    @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            if (requestCode == REQUEST_TAKE_PHOTO && resultCode == Activity.RESULT_OK) {
                updateImageUI(photoUri);
            } 
        }

    private void updateImageUI(Uri uri) {
            getBinding().cropImageView.startLoad(
                    uri,
                    new LoadCallback() {
                        @Override
                        public void onSuccess() {

                        }

                        @Override
                        public void onError() {
                            showGenericErrorDialog();
                        }
                    });
        }

裁剪库相关代码:

public void startLoad(Uri sourceUri, LoadCallback callback) {
        mLoadCallback = callback;
        mSourceUri = sourceUri;
        if (sourceUri == null) {
            postErrorOnMainThread(mLoadCallback);
            throw new IllegalStateException("Source Uri must not be null.");
        }
        mExecutor.submit(new Runnable() {
            @Override
            public void run() {
                mIsLoading = true;
                mExifRotation = Utils.getExifOrientation(getContext(), mSourceUri);
                int maxSize = Utils.getMaxSize();
                int requestSize = Math.max(mViewWidth, mViewHeight);
                if (requestSize == 0) requestSize = maxSize;
                try {
                    final Bitmap sampledBitmap = Utils.decodeSampledBitmapFromUri(getContext(),
                            mSourceUri,
                            requestSize);
                    mInputImageWidth = Utils.sInputImageWidth;
                    mInputImageHeight = Utils.sInputImageHeight;
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            mAngle = mExifRotation;
                            setImageBitmap(sampledBitmap);
                            if (mLoadCallback != null) mLoadCallback.onSuccess();
                            mIsLoading = false;
                        }
                    });
                } catch (OutOfMemoryError e) {
                    Logger.e("OOM Error: " + e.getMessage(), e);
                    postErrorOnMainThread(mLoadCallback);
                    mIsLoading = false;
                } catch (Exception e) {
                    Logger.e("An unexpected error has occurred: " + e.getMessage(), e);
                    postErrorOnMainThread(mLoadCallback);
                    mIsLoading = false;
                }
            }
        });
    }

public static Bitmap decodeSampledBitmapFromUri(Context context, Uri sourceUri, int requestSize) {
        InputStream is = null;
        try {
            is = context.getContentResolver().openInputStream(sourceUri);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = Utils.calculateInSampleSize(context, sourceUri, requestSize);
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeStream(is, null, options);
    }

显现:

<provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

请注意,URI 看起来像这样:content://my.package.provider/%2Fmnt%2Fsdcard%2F/ocr/picture9052876345621346933.jpg我正在使用 Android 8 的三星 Galaxy S7 上进行测试

编辑:截至目前,问题仅存在于 S7,其他设备正常工作

知道为什么会发生这种情况以及如何避免它吗?

标签: androidandroid-intentcamerauri

解决方案


推荐阅读