You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET7 Blazor Server Hybrid安卓端文件下载故障及存储优化需求

问题描述

基于.NET7开发Blazor Server Hybrid应用,Razor组件封装在RCL中,同时部署Web端与Blazor MAUI安卓端,遇到如下问题:

  • Web端通过BlazorDownloadFile NuGet包可正常从SQL表Blob字段下载图片,但安卓端完全失效
  • 已在AndroidManifest.xml配置ACCESS_NETWORK_STATE、INTERNET、WRITE_EXTERNAL_STORAGE权限,无调用栈报错,仅Output日志出现[libEGL]相关错误
  • 尝试多线程下载、调整MainPage代码后仍无效,还出现Blob错误
  • 自行实现文件写入逻辑后,文件可保存至/data/user/0/com.companyname.myappname/files,但无下载提示,且该路径不易查找,希望将文件保存至手机相册目录并添加下载完成提示
解决方案

1. 适配安卓端存储到相册

要将图片保存到手机相册,需针对安卓版本做不同处理:

  • 权限适配:Android 13及以上需额外申请READ_MEDIA_IMAGES/WRITE_MEDIA_IMAGES权限,且必须动态申请(仅清单配置无效)
  • 媒体存储API调用:直接写入相册需通过MediaStore API,避免直接操作文件路径,示例代码:
using Android.Content;
using Android.OS;
using Android.Provider;
using System.IO;

public async Task SaveImageToGallery(byte[] imageBytes, string fileName)
{
    var mimeType = "image/jpeg";
    var values = new ContentValues();
    values.Put(MediaStore.Images.Media.Columns.DisplayName, fileName);
    values.Put(MediaStore.Images.Media.Columns.MimeType, mimeType);

    if (Build.VERSION.SdkInt >= BuildVersionCodes.Q)
    {
        values.Put(MediaStore.Images.Media.Columns.RelativePath, "DCIM/MyAppImages");
        values.Put(MediaStore.Images.Media.Columns.IsPending, 1);
        var uri = Android.App.Application.Context.ContentResolver.Insert(MediaStore.Images.Media.ExternalContentUri, values);
        
        using (var stream = Android.App.Application.Context.ContentResolver.OpenOutputStream(uri))
        {
            await stream.WriteAsync(imageBytes);
        }

        values.Put(MediaStore.Images.Media.Columns.IsPending, 0);
        Android.App.Application.Context.ContentResolver.Update(uri, values, null, null);
    }
    else
    {
        var directoryPath = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, "DCIM/MyAppImages");
        Directory.CreateDirectory(directoryPath);
        var filePath = Path.Combine(directoryPath, fileName);
        await File.WriteAllBytesAsync(filePath, imageBytes);
        
        // 通知媒体扫描器刷新相册
        MediaScannerConnection.ScanFile(Android.App.Application.Context, new[] { filePath }, new[] { mimeType }, null);
    }
}

2. 添加下载完成提示

通过原生Toast实现安卓端的下载提示:

  • 定义跨平台接口:
public interface IToastService
{
    void ShowToast(string message);
}
  • 安卓端实现:
using Android.Widget;

public class AndroidToastService : IToastService
{
    public void ShowToast(string message)
    {
        Toast.MakeText(Platform.CurrentActivity, message, ToastLength.Long).Show();
    }
}
  • 在MauiProgram.cs注册服务:
builder.Services.AddSingleton<IToastService, AndroidToastService>();
  • 在Razor组件中注入并调用:
@inject IToastService ToastService

// 下载完成后触发提示
ToastService.ShowToast("图片已成功保存至相册");

3. 跨端下载的适配方案

由于BlazorDownloadFile在安卓端存在兼容性问题,建议通过依赖注入+平台特定实现做跨端适配:

  • 在RCL中定义下载接口,Web端继续用BlazorDownloadFile实现,安卓端用上述原生存储逻辑实现,通过依赖注入自动匹配平台实现

内容的提问来源于stack exchange,提问作者user13714356

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 00:07:39