如何从 Firebase 存储中检索图像并显示它?收到 "No content provider" 错误
How do I retrieve an image from Firebase Storage and show it? Getting "No content provider" error
我的应用正在 Firebase 存储中保存图像,但我无法检索和查看它们。图像已上传到名为 "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.onSuccess(DialogFragmentShowBox.java:295)
W/System.err: at sharongilmore.tickybox.fragments.dialogFragments.DialogFragmentShowBox.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 更改为 post,但是当我在浏览器中访问它时,它显示了正确的图像,所以我认为没问题)。
ContentResolver
res
已填充;不确定它是什么意思,但在调试器的变量列表中,第一行是:
res = {ContextImpl$ApplicationContentResolver@8456}
知道这里出了什么问题吗?
这个可以帮到你的情况兄弟!
据推测,currentTrack
有一个 File
对象。如果是这样,请将 Uri.parse(currentTrack.getPath())
替换为 currentTrack.getUri()
,在其中实现 getUri() 以 return File
的 Uri.fromFile()
的值。
这解决了您当前的问题,即您创建了一个无效的 Uri,因为它没有方案。它还使您能够处理将来可能需要的 Uri
非文件类型(例如 content
Uri
值)。
已复制!
我是这样实现的:
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
}
});
我的应用正在 Firebase 存储中保存图像,但我无法检索和查看它们。图像已上传到名为 "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.onSuccess(DialogFragmentShowBox.java:295)
W/System.err: at sharongilmore.tickybox.fragments.dialogFragments.DialogFragmentShowBox.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 更改为 post,但是当我在浏览器中访问它时,它显示了正确的图像,所以我认为没问题)。
ContentResolver
res
已填充;不确定它是什么意思,但在调试器的变量列表中,第一行是:
res = {ContextImpl$ApplicationContentResolver@8456}
知道这里出了什么问题吗?
这个
据推测,currentTrack
有一个 File
对象。如果是这样,请将 Uri.parse(currentTrack.getPath())
替换为 currentTrack.getUri()
,在其中实现 getUri() 以 return File
的 Uri.fromFile()
的值。
这解决了您当前的问题,即您创建了一个无效的 Uri,因为它没有方案。它还使您能够处理将来可能需要的 Uri
非文件类型(例如 content
Uri
值)。
已复制!
我是这样实现的:
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
}
});