Skip to content
Tauri 中文网

移动设备上的文件关联

Tauri 支持在 Android 和 iOS 上的文件关联,允许你的应用被注册为特定文件类型的处理程序。当用户打开与你声明的关联匹配的文件时,操作系统会启动你的应用并传递文件 URL。

🌐 Tauri supports file associations on Android and iOS, allowing your app to be registered as a handler for specific file types. When a user opens a file that matches your declared associations, the operating system launches your app and delivers the file URL.

Android 上,文件关联是通过 intent filters 实现的,这些过滤器由 Tauri 构建系统根据你的配置自动生成。

🌐 On Android, file associations are implemented using intent filters that the Tauri build system generates automatically from your configuration.

iOS 上,文件关联使用 CFBundleDocumentTypes,并可选地使用 UTExportedTypeDeclarations 来支持自定义文件类型。

🌐 On iOS, file associations use CFBundleDocumentTypes and optionally UTExportedTypeDeclarations for custom file types.

🌐 Configuration

文件关联在 tauri.conf.jsonbundle.fileAssociations 下声明。Tauri CLI 使用此配置生成适当的特定平台元数据(在 AndroidManifest.xml 中的 Android intent 过滤器,在 Info.plist 中的 iOS 文档类型)。

🌐 File associations are declared in tauri.conf.json under bundle.fileAssociations. The Tauri CLI uses this configuration to generate the appropriate platform-specific metadata (Android intent filters in AndroidManifest.xml, iOS document types in Info.plist).

数组中的每个条目表示你的应用可以处理的文件类型:

🌐 Each entry in the array represents a file type your app can handle:

src-tauri/tauri.conf.json
{
"bundle": {
"fileAssociations": [
{
"ext": ["png"],
"mimeType": "image/png"
},
{
"ext": ["jpg", "jpeg"],
"mimeType": "image/jpeg"
}
]
}
}

🌐 Configuration Options

  • ext — 要关联的文件扩展名列表(不带前导点)。
  • mimeType — 文件的 MIME 类型(例如 image/png)。在 Android 上,意图过滤匹配时需要指定。Tauri 在未指定时会根据扩展名推断常见的 MIME 类型。
  • role — 应用相对于文件类型的角色。在苹果平台上对应 CFBundleTypeRole。值:Editor(默认),ViewerShellQLGeneratorNone
  • rank — 处理此文件类型的应用的排名。在苹果平台上对应 LSHandlerRank。值:Default(默认)、OwnerAlternateNone
  • name — 文件类型的显示名称。默认为第一个扩展名。
  • exportedType — 定义由你的应用拥有的自定义文件类型。在 Apple 平台上将其与非标准文件扩展名关联时是必须的。
  • androidIntentActionFilters — 要注册的 Android 意图操作。可选值:SendSendMultipleView。默认情况下都会使用这三个。

🌐 Custom File Types

对于非标准文件扩展名,你应定义一个 exportedType,以便 Apple 平台可以识别文件类型。identifier 应该是一个对你的应用唯一的反向 DNS 字符串,conformsTo 列出了父类型:

🌐 For non-standard file extensions, you should define an exportedType so Apple platforms can identify the file type. The identifier should be a reverse-DNS string unique to your app, and conformsTo lists the parent types:

src-tauri/tauri.conf.json
{
"bundle": {
"fileAssociations": [
{
"ext": ["mydata"],
"mimeType": "application/octet-stream",
"exportedType": {
"identifier": "com.example.myapp.mydata",
"conformsTo": ["public.data"]
}
}
]
}
}

常见的 conformsTo 值包括 public.datapublic.imagepublic.jsonpublic.plain-text

🌐 Common conformsTo values include public.data, public.image, public.json, and public.plain-text.

🌐 Handling Opened Files

当使用你的应用打开文件时,Tauri 会发出一个包含文件 URL 的 RunEvent::Opened 事件。该事件在 macOS、iOS 和 Android 上可用。

🌐 When a file is opened with your app, Tauri emits a RunEvent::Opened event containing the file URLs. This event is available on macOS, iOS, and Android.

你需要处理两种情况:

🌐 You need to handle two cases:

  1. 应用已在运行 — 该事件在运行时传递。
  2. 应用由文件打开启动——此事件在启动过程中触发,因此你应该存储这些 URL 并让它们可供前端使用。

将传入的 URL 存储在托管状态中,通过前端在启动时可以调用的命令将其暴露出来,并在 RunEvent::Opened 触发时发出 Tauri 事件,以便前端在应用已经运行时可以做出反应:

🌐 Store incoming URLs in managed state, expose them with a command the frontend can call on startup, and emit a Tauri event whenever RunEvent::Opened fires so the frontend can react while the app is already running:

src-tauri/src/lib.rs
use std::sync::Mutex;
use tauri::Manager;
struct OpenedUrls(Mutex<Vec<tauri::Url>>);
#[tauri::command]
fn opened_urls(app: tauri::AppHandle) -> Vec<tauri::Url> {
app.state::<OpenedUrls>().0.lock().unwrap().clone()
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.manage(OpenedUrls(Mutex::new(vec![])))
.invoke_handler(tauri::generate_handler![opened_urls])
.build(tauri::generate_context!())
.expect("error while running tauri application")
.run(|app, event| {
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "android"))]
if let tauri::RunEvent::Opened { urls } = event {
use tauri::Emitter;
app.state::<OpenedUrls>()
.0
.lock()
.unwrap()
.extend(urls.clone());
app.emit("opened", urls).unwrap();
}
});
}

下面的前端在两个地方连接到了那个 Rust 代码:

🌐 The frontend below is wired to that Rust code in two places:

  • invoke('opened_urls') 调用 opened_urls 命令,因此网页视图可以读取在 UI 加载完成之前存储的 URL(从文件打开的冷启动)。
  • listen('opened', …) 订阅了在 Rust 中传递给 app.emit("opened", urls) 的相同事件名称,因此在应用已经运行时触发的文件打开事件会立即传递。
import { listen } from '@tauri-apps/api/event';
import { invoke } from '@tauri-apps/api/core';
// Cold start: URLs may already be in Rust state before the frontend loads
const initialUrls = await invoke('opened_urls');
if (initialUrls.length > 0) {
handleFiles(initialUrls);
}
// Warm: Rust emits the "opened" event when RunEvent::Opened fires
await listen('opened', (event) => {
handleFiles(event.payload);
});

Tauri 中文网 - 粤ICP备13048890号
Nodejs.cn 旗下网站