无法在ImageView中显示从图库中导出的图片

时间:2018-09-27 13:32:03

标签: java android imageview gallery bitmapfactory

我正在创建一个Android应用程序,该应用程序需要在内部存储器中存储一些多媒体文件。用户可以从选择器中选择该多媒体文件。即使用户删除了这些文件,这些文件也必须可用,因此它们会被复制到内部存储器中。

这是我的代码:

final Bitmap bitm = MediaStore.Images.Media.getBitmap( this.getContentResolver(), uri );
final int bitmapRawLength = bitm.getAllocationByteCount();
final ByteBuffer byteBuffer = ByteBuffer.allocate( bitmapRawLength );

bitm.copyPixelsToBuffer( byteBuffer );
data = byteBuffer.array();

final ByteArrayInputStream in = new ByteArrayInputStream( data );
db.store( in );

因此,组成图像的字节通过 InputStream 复制到内部存储中的平均文件中。显然可以,因为文件包含内容。

稍后将图像加载到 ImageView

private void loadImage(File imgFile)
{
    if ( imgFile.exists() ) {
        final Bitmap bitmap = BitmapFactory.decodeFile( mediaFile.getPath() );

        this.ivPictureBox.setImageBitmap( bitmap );
    } else {
        this.abortDueToMissingFile( imgFile );
    }

    return;
}

不幸的是,这不起作用。是时候加载该图像了, ImageView 变为空白,什么也没有显示。

实际上,日志中显示以下消息:

D/skia: --- Failed to create image decoder with message 'unimplemented'

如果我在Android Studio中使用文件浏览器并将图像导出到计算机,则GwenView失败,并显示消息“无法加载元数据”。

无论是更简单还是可行的方法,我如何正确存储包含完整信息的图像,或正确显示它?

2 个答案:

答案 0 :(得分:1)

在这种情况下,我已经开发并测试了一些代码。希望对您有帮助。

定义请求代码:

private static final int REQUEST_CODE_KITKAT_PICK_PHOTO = 11;
private static final int REQUEST_CODE_PICK_PHOTO = 12;

呼叫图像选择器:

if (Build.VERSION.SDK_INT < 19) {
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(Intent.createChooser(intent, "Choose a photo"), REQUEST_CODE_PICK_PHOTO);
} else {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("image/*");
    startActivityForResult(intent, REQUEST_CODE_KITKAT_PICK_PHOTO);
}

要接收选择的图像并将其复制,请在您的Activity中:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == Activity.RESULT_OK) {
        if (requestCode == REQUEST_CODE_PICK_PHOTO) {
            if (data == null || data.getData() == null) {
                Toast.makeText(getApplicationContext(), "Error in retrieving photo!", Toast.LENGTH_SHORT).show();
                return;
            }
            Uri uri = data.getData();
            String destPath = getFilesDir() + File.separator + "image.jpg"; // an example path

            File imageFile = null;
            try {
                imageFile = copy(uri, destPath);
            } catch (IOException e) {
                e.printStackTrace();
            }

            if (imageFile != null) {
                Bitmap bitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath());
                ivPictureBox.setImageBitmap(bitmap);
            }
        } else if (requestCode == REQUEST_CODE_KITKAT_PICK_PHOTO) {
            if (data == null || data.getData() == null) {
                Toast.makeText(getApplicationContext(), "Error in retrieving photo!", Toast.LENGTH_SHORT).show();
                return;
            }
            Uri originalUri = data.getData();
            final int takeFlags = data.getFlags()
                    & (Intent.FLAG_GRANT_READ_URI_PERMISSION
                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            // Check for the freshest data.
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                getContentResolver().takePersistableUriPermission(originalUri, takeFlags);
            }
            String destPath = getFilesDir() + File.separator + "image.jpg"; // an example path

            File imageFile = null;
            try {
                imageFile = copy(originalUri, destPath);
            } catch (IOException e) {
                e.printStackTrace();
            }

            if (imageFile != null) {
                Bitmap bitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath());
                ivPictureBox.setImageBitmap(bitmap);
            }
        }
    }
}

// To copy the file:
private File copy(Uri inputUri, String destPath) throws IOException {
    File inputFile = new File(ImageUtils.getPathFromUri(getApplicationContext(), inputUri));
    File outputFile = new File(destPath);
    if (!outputFile.exists()) {
        outputFile.createNewFile();
    }
    FileInputStream inStream = new FileInputStream(inputFile);
    FileOutputStream outStream = new FileOutputStream(outputFile);
    FileChannel inChannel = inStream.getChannel();
    FileChannel outChannel = outStream.getChannel();
    inChannel.transferTo(0, inChannel.size(), outChannel);
    inStream.close();
    outStream.close();
    return outputFile;
}

ImageUtils.java:

import android.annotation.SuppressLint;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;

public class ImageUtils {

    @SuppressLint("NewApi")
    public static String getPathFromUri(final Context context, final Uri uri) {

        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            // ExternalStorageProvider
            if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }

                // TODO handle non-primary volumes
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {

                final String id = DocumentsContract.getDocumentId(uri);
                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

                return getDataColumn(context, contentUri, null, null);
            }
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[]{
                        split[1]
                };

                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {

            // Return the remote address
            if (isGooglePhotosUri(uri))
                return uri.getLastPathSegment();

            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }

        return null;
    }

    public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {

        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = {
                column
        };

        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                    null);
            if (cursor != null && cursor.moveToFirst()) {
                final int index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }


    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    public static boolean isGooglePhotosUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    }
}

这是结果:

enter image description here

答案 1 :(得分:0)

我很傻!

这很简单:

final InputStream in = this.getContentResolver().openInputStream( uri );

...然后将其复制到任意位置。

这适用于具有SCHEME_CONTENT和SCHEME_FILE方案的URI。