如何在Android上正确使用Tauri资源文件

问题描述 投票:0回答:1

我目前正在尝试使用 tauri 编写一个 Android 应用程序,该应用程序需要访问字体资源文件。

  • 我将这些文件添加到
    src-tauri
    文件夹中的
    fonts
    目录中。
  • 在我的
    tauri.conf.json
    中,我设置了
    "bundle": {"resources": ["fonts/*"]}
    说明符
  • 我检查了
    targe > debug
    目录,字体文件夹+字体文件都已创建

但是,当尝试使用以下代码片段访问该文件时,我收到 NotFound 错误。

let resource_path = app_handle
        .path()
        .resolve(format!("fonts/{}", name), BaseDirectory::Resource)
        .expect("failed to resolve resource");
let mut file = File::open(&resource_path).expect(&format!("Failed to open font file {}", resource_path.as_path().to_str().unwrap()));
10-19 16:22:58.189 19486 19600 I RustStdoutStderr: thread '<unnamed>' panicked at src\lib.rs:85:47:
10-19 16:22:58.189 19486 19600 I RustStdoutStderr: Failed to open font file asset://localhost/fonts/Calibri-Regular.ttf: Os { code: 2, kind: NotFound, message: "No such file or directory" }

我在Windows上尝试了相同的代码,一切正常,Android似乎以不同的方式处理资源,但我通常不开发Android应用程序,所以我不知道如何解决这个问题。感谢任何帮助:)

android rust resources tauri
1个回答
0
投票

这个问题似乎与Android处理Tauri应用程序中资源文件的方式有关,这与Windows不同。需要考虑的关键点是: 资源路径解析似乎正在工作,因为它正在生成路径。 File::open() 操作失败并出现 NotFound 错误。 生成的路径使用“asset://localhost/”方案,该方案特定于 Android。 该问题可能源于尝试在 Android 资产系统上使用标准 Rust 文件 I/O 操作。 Android 以特殊方式打包资源,并且无法像文件系统上的常规文件一样访问它们。 使用 Tauri 的 Assets API 来读取文件内容,而不是使用 File::open()。以下是如何执行此操作的示例:

use tauri::Assets;

fn read_font_file(assets: &Assets, name: &str) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
    let font_path = format!("fonts/{}", name);
    let font_data = assets.get(&font_path).ok_or("Font not found")?;
    Ok(font_data.into_owned())
}

// Usage in your code:
let app_handle = // ... get your app handle
let assets = app_handle.assets_handle();
match read_font_file(&assets, "Calibri-Regular.ttf") {
    Ok(font_data) => {
        // Use the font_data (Vec<u8>) as needed
        println!("Font data loaded, size: {} bytes", font_data.len());
    },
    Err(e) => eprintln!("Failed to load font: {}", e),
}

此方法使用 Tauri 的资产系统,该系统在包括 Android 在内的各个平台上一致工作。它将文件内容作为 Vec 返回,然后您可以根据需要在应用程序中使用它。

如果您需要将字体数据作为文件使用(例如,如果您使用的库需要文件路径),您可能需要首先将数据写入临时文件。以下是如何做到这一点的示例:


use std::io::Write;
use tempfile::NamedTempFile;

fn create_temp_font_file(font_data: Vec<u8>) -> Result<NamedTempFile, std::io::Error> {
    let mut temp_file = NamedTempFile::new()?;
    temp_file.write_all(&font_data)?;
    Ok(temp_file)
}

// Usage:
let font_data = read_font_file(&assets, "Calibri-Regular.ttf")?;
let temp_file = create_temp_font_file(font_data)?;
let temp_path = temp_file.path();
// Use temp_path as needed

这会创建一个临时文件,当超出范围时将自动删除。

© www.soinside.com 2019 - 2024. All rights reserved.