Как получить изображение из Firebase Storage и показать его?Ошибка «Нет контент-провайдера» - PullRequest
7 голосов
/ 10 мая 2019

Мое приложение сохраняет изображения в Firebase Storage, но у меня возникают проблемы с их получением и просмотром. Изображения загружаются нормально, в папку с именем "images".

Каждое изображение связано с Box. Коллекция boxes в базе данных выглядит следующим образом:

boxes > key1 > name: Box 1 name
             > uid: xxxxxxxxx          (user id of Box creator)
             > image: "images/box1image.jpg"
      > key2 > name: Box 2 name
             > uid: yyyyyyyyy          
             > image: "images/box2image.jpg"

Я хочу получить изображение и показать его в DialogFragment. В настоящее время макет фрагмента (dialog_fragment_show_box) выглядит следующим образом (для краткости я убрал layout_width и т. Д.):

<android.support.constraint.ConstraintLayout >

    <ImageView
        android:id="@+id/iv_box_image" />

    <TextView
        android:id="@+id/tv_box_name"
        app:layout_constraintTop_toBottomOf="@id/iv_box_image" />

</android.support.constraint.ConstraintLayout>

Теперь, когда загружается DialogFragment, я хочу передать Box и отобразить его имя и соответствующее изображение. Box.java содержит:

public class HybridBox {

    private String  name, uid, key, url;


    // CONSTRUCTOR
    public HybridBox() {}

    // GETTERS
    public String   getName()         { return name; }
    public String   getUrl()          { return url; }
    public String   getUid()          { return this.uid; }
    public String   getKey()          { return key; }

    // SETTERS
    public void setName(String thisName) { this.name = thisName; }
    public void setUrl(String thisUrl)   { this.url = thisUrl; }
    public void setUid(String thisUid)   { this.uid = thisUid; }
    public void setKey(String thisKey)   { this.key = thisKey; }

}

Box извлекается из базы данных без проблем и передается в DialogFragment, а именно:

public class DialogFragmentShowBox extends DialogFragment {

    private Context         mContext;
    private EditText        mBoxName;
    private ImageView       mBoxImage;
    private HybridBox       mBox;

    public DialogFragmentShowBox() {}

    public static DialogFragmentShowBox newInstance() {
        return new DialogFragmentShowBox();
    }

    @Override
    public View onCreateView(
            @NonNull LayoutInflater inflater, 
            ViewGroup container, Bundle savedInstanceState) {

        return inflater.inflate(
                R.layout.dialog_fragment_show_box, container, false);

    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        mBoxImage        = view.findViewById(R.id.iv_box_image);
        mBoxName         = view.findViewById(R.id.tv_box_name);

        show_details();
        draw_iv();

    }

    // Pass in Box object
    public void setBox(HybridBox box) {

        mBox = box;

        show_details();
        draw_iv();

    }

    // Set up Context
    public void setContext(Context context) { mContext = context; }

    // Show details of the Box (currently just name)
    private void show_details() {

        if(mBox == null) return;

        if(mBoxName != null) {
            mBoxName(mBox.getName());
        }
    }

    // Draw the Box image
    private void draw_iv() {
        if(mBox == null) return;

        if(mBoxImage != null) {

            FirebaseStorage mStorage = FirebaseStorage.getInstance();
            final StorageReference mStorageRef = mStorage.getReference();

            final String drawableUrl = mBox.getUrl();

            if(drawableUrl != null) {
                mStorageRef.child(mBox.getUrl())
                           .getDownloadUrl()
                           .addOnSuccessListener(new OnSuccessListener<Uri>() {
                    @Override
                    public void onSuccess(Uri uri) {
                        // Got the download URL
                        ContentResolver res = mContext.getContentResolver();
                        try {
                            Bitmap bitmap
                                    = MediaStore.Images.Media.getBitmap(
                                    res,
                                    uri);
                            mBoxImage.setImageBitmap(bitmap);
                        }
                        catch (IOException e)
                        {
                            e.printStackTrace();
                        }
                    }
                });

            }
        }

    }
}

Когда я запускаю это, я получаю следующее предупреждение, и изображение на коробке пустое:

W/System.err: java.io.FileNotFoundException: No content provider: https://firebasestorage.googleapis.com/v0/b/tickybox-d8888.appspot.com/o/images%2F561e1408-3b17-4eaa-b0ff-d3b00479d1c0.jpg?alt=media&token=9656ea28-2493-447b-aa30-9dbc4c39b3fc
W/System.err:     at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1396)
W/System.err:     at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1247)
W/System.err:     at android.content.ContentResolver.openInputStream(ContentResolver.java:967)
        at android.provider.MediaStore$Images$Media.getBitmap(MediaStore.java:888)
        at sharongilmore.tickybox.fragments.dialogFragments.DialogFragmentShowBox$6.onSuccess(DialogFragmentShowBox.java:295)
W/System.err:     at sharongilmore.tickybox.fragments.dialogFragments.DialogFragmentShowBox$6.onSuccess(DialogFragmentShowBox.java:288)
        at com.google.android.gms.tasks.zzn.run(Unknown Source:4)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6494)
W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

URI, передаваемый слушателю успеха, имеет вид:

https://firebasestorage.googleapis.com/v0/b/tickybox-d8888.appspot.com/o/images%2F561e1408-3b17-4eaa-b0ff-d3b00479d1c0.jpg?alt=media&token=9656ea28-2493-447b-aa30-9dbc4c39b3fc

(я изменил некоторые URL для публикации здесь, но когда я захожу на них в браузере, они показывают правильное изображение, поэтому я думаю, что все в порядке).

ContentResolver res заполнен; не уверен, что это значит, но в списке переменных в отладчике первая строка:

res = {ContextImpl$ApplicationContentResolver@8456}

Есть идеи, что здесь происходит?

Ответы [ 2 ]

1 голос
/ 14 мая 2019

Этот ответ может помочь вашей ситуации, брат!

Предположительно, currentTrack имеет объект File.Если это так, замените Uri.parse(currentTrack.getPath()) на currentTrack.getUri(), где вы реализуете getUri () для возврата значения Uri.fromFile() для File.

Это решает вашу непосредственную проблему, то есть то, что вы создалинедействительный Ури, так как у него нет схемы.Он также настраивает вас на работу с Uri типами, которые не являются файлами (например, content Uri значения), которые могут вам понадобиться в будущем.

Скопировано!

0 голосов
/ 11 июня 2019

Я добился этого следующим образом:

FirebaseStorage mStorage = FirebaseStorage.getInstance();
final StorageReference mStorageRef = mStorage.getReference();

mStorageRef.child(mBox.getUrl()).getDownloadUrl()
    .addOnSuccessListener(new OnSuccessListener<Uri>() {
         @Override
         public void onSuccess(Uri uri) {                           
             Glide.with(getContext()).load(uri).into(mBoxImage);
         }
    })
    .addOnFailureListener(new OnFailureListener() {
         @Override
         public void onFailure(@NonNull Exception exception) {
             // Handle any errors
         }
   });
...