【问题标题】:Cannot show in ImageView a picture exported from the gallery无法在 ImageView 中显示从图库导出的图片
【发布时间】:2019-03-03 10:38:49
【问题描述】:

我正在创建一个需要在内部存储中存储一些多媒体文件的 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 会失败并显示“加载元数据失败”消息。

我怎样才能正确地存储带有完整信息的图像,或者正确地显示它,无论是更容易或可行的吗?

【问题讨论】:

  • imgFile.getPath() 而不是 mediaFile.getPath()

标签: java android imageview gallery bitmapfactory


【解决方案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());
    }
}

结果如下:

【讨论】:

  • 我把答案做得更好了:)
  • 您正在使用外部库,例如 Glide。我想用普通的 Android 来做。
  • @Baltasarq:我已经对其进行了一些更改以满足您的要求。
【解决方案2】:

我真傻!

就这么简单:

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

...然后随意复制。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-24
    • 1970-01-01
    • 1970-01-01
    • 2018-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多