Невозможно отобразить в ImageView изображение, экспортированное из галереи - PullRequest
0 голосов
/ 27 сентября 2018

Я создаю приложение для 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 голосов
/ 28 сентября 2018

Глупый из меня!

Это так же просто, как:

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

... и скопируйте его в зависимости от того, что вы хотите.

Это работает для URI с обоимиСхемы SCHEME_CONTENT и SCHEME_FILE.

0 голосов
/ 27 сентября 2018

Я разработал и протестировал некоторый код в этом случае.Я надеюсь, что это поможет вам.

Определение кодов запроса:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...