| Crates.io | tauri-plugin-intent |
| lib.rs | tauri-plugin-intent |
| version | 0.1.0 |
| created_at | 2025-09-01 07:01:13.348391+00 |
| updated_at | 2025-09-01 07:01:13.348391+00 |
| description | Tauri plugin for handling Android and iOS intents. |
| homepage | https://github.com/modeckrus/tauri-plugin-intent |
| repository | https://github.com/modeckrus/tauri-plugin-intent |
| max_upload_size | |
| id | 1819222 |
| size | 172,023 |
tauri-plugin-intent — это плагин для Tauri, который позволяет работать с Android Intent и открывать системные обработчики на десктопных платформах.
A Tauri plugin for opening Android Intents and system default handlers on desktop platforms.
Cargo.toml:[dependencies]
tauri-plugin-intent = { git = "https://github.com/your-repo/tauri-plugin-intent" }
fn main() {
tauri::Builder::default()
.plugin(tauri_plugin_intent::init())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
{
"identifier": "main",
"description": "Capability for the main window",
"windows": ["main"],
"permissions": [
"core:default",
"intent:default"
]
}
npm install @tauri-apps/plugin-intent
import { openIntent, openPhoneDialer, openUrl, sendEmail } from '@tauri-apps/plugin-intent';
// Open phone dialer
await openPhoneDialer('+1234567890');
// Open URL
await openUrl('https://example.com');
// Send email
await sendEmail({
to: ['recipient@example.com'],
subject: 'Hello',
body: 'This is a test email'
});
// Custom intent
await openIntent({
action: 'android.intent.action.VIEW',
data: 'tel:+1234567890',
flags: ['FLAG_ACTIVITY_NEW_TASK']
});
// Send SMS with custom message
await openIntent({
action: 'android.intent.action.VIEW',
data: 'sms:+1234567890',
extras: {
'sms_body': 'Hello from Tauri!'
}
});
// Share content
await openIntent({
action: 'android.intent.action.SEND',
mimeType: 'text/plain',
extras: {
'android.intent.extra.TEXT': 'Check out this awesome app!',
'android.intent.extra.SUBJECT': 'Amazing Discovery'
}
});
use tauri_plugin_intent::IntentExt;
#[tauri::command]
async fn open_custom_intent(app: tauri::AppHandle) -> Result<(), String> {
let request = tauri_plugin_intent::OpenIntentRequest {
action: "android.intent.action.VIEW".to_string(),
data: Some("https://example.com".to_string()),
category: None,
mime_type: None,
package_name: None,
class_name: None,
flags: None,
extras: None,
};
let response = app.intent().open_intent(request).await
.map_err(|e| e.to_string())?;
if !response.success {
return Err(response.error.unwrap_or("Unknown error".to_string()));
}
Ok(())
}
For Leptos applications, you can use the JavaScript API with wasm-bindgen and serde-wasm-bindgen:
Cargo.toml:[dependencies]
leptos = { version = "0.8", features = ["csr"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde-wasm-bindgen = "0.6"
wasm-bindgen = "0.2"
js-sys = "0.3"
use leptos::task::spawn_local;
use leptos::{ev::SubmitEvent, prelude::*};
use serde::{Deserialize, Serialize};
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = ["window", "__TAURI__", "core"])]
async fn invoke(cmd: &str, args: JsValue) -> JsValue;
}
#[derive(Serialize, Deserialize)]
struct OpenIntentArgs {
payload: OpenIntentPayload,
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct OpenIntentPayload {
action: String,
data: Option<String>,
// ... other fields
}
#[derive(Serialize, Deserialize)]
struct OpenIntentResponse {
success: bool,
error: Option<String>,
}
#[component]
pub fn IntentExample() -> impl IntoView {
let (phone_number, set_phone_number) = signal(String::new());
let (result_message, set_result_message) = signal(String::new());
let open_dialer = move |ev: SubmitEvent| {
ev.prevent_default();
spawn_local(async move {
let number = phone_number.get_untracked();
if number.is_empty() { return; }
let payload = OpenIntentPayload {
action: "android.intent.action.VIEW".to_string(),
data: Some(format!("tel:{}", number)),
// ... other fields
};
let args = serde_wasm_bindgen::to_value(&OpenIntentArgs { payload }).unwrap();
match serde_wasm_bindgen::from_value::<OpenIntentResponse>(
invoke("plugin:intent|open_intent", args).await,
) {
Ok(response) => {
if response.success {
set_result_message.set("Phone dialer opened!".to_string());
} else {
set_result_message.set(format!("Error: {}",
response.error.unwrap_or("Unknown error".to_string())));
}
}
Err(e) => {
set_result_message.set(format!("Failed: {:?}", e));
}
}
});
};
view! {
<div>
<h2>"Phone Dialer"</h2>
<form on:submit=open_dialer>
<input
placeholder="Enter phone number..."
on:input=move |ev| set_phone_number.set(event_target_value(&ev))
/>
<button type="submit">"Open Dialer"</button>
</form>
<p>{move || result_message.get()}</p>
</div>
}
}
import { openPhoneDialer } from '@tauri-apps/plugin-intent';
function PhoneDialer() {
const [phoneNumber, setPhoneNumber] = useState('');
const [message, setMessage] = useState('');
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
try {
const result = await openPhoneDialer(phoneNumber);
if (result.success) {
setMessage('Phone dialer opened successfully!');
} else {
setMessage(`Error: ${result.error}`);
}
} catch (error) {
setMessage(`Failed to open dialer: ${error}`);
}
};
return (
<form onSubmit={handleSubmit}>
<input
type="tel"
value={phoneNumber}
onChange={(e) => setPhoneNumber(e.target.value)}
placeholder="Enter phone number..."
/>
<button type="submit">Open Dialer</button>
{message && <p>{message}</p>}
</form>
);
}
android.intent.action.VIEW - Open URLs, phone numbers, etc.android.intent.action.SEND - Send content to other appsandroid.intent.action.CALL - Initiate phone callsandroid.intent.action.SENDTO - Send to specific targetsandroid.intent.action.DIAL - Open phone dialerandroid.intent.action.EDIT - Edit contentandroid.intent.action.VIEW - Opens URLs with system default handler| Parameter | Type | Description |
|---|---|---|
action |
string |
The intent action (required) |
data |
string? |
The intent data URI |
category |
string? |
Intent category |
mimeType |
string? |
MIME type for the intent |
packageName |
string? |
Target package name |
className |
string? |
Target class name |
flags |
string[]? |
Intent flags |
extras |
Record<string, any>? |
Additional data |
FLAG_ACTIVITY_NEW_TASKFLAG_ACTIVITY_CLEAR_TOPFLAG_ACTIVITY_CLEAR_TASKFLAG_ACTIVITY_SINGLE_TOPFLAG_ACTIVITY_NO_HISTORYFLAG_ACTIVITY_MULTIPLE_TASK// Open phone dialer
await openIntent({
action: 'android.intent.action.VIEW',
data: 'tel:+1234567890'
});
// Send SMS
await openIntent({
action: 'android.intent.action.VIEW',
data: 'sms:+1234567890',
extras: { 'sms_body': 'Hello!' }
});
// Make a phone call (requires CALL_PHONE permission)
await openIntent({
action: 'android.intent.action.CALL',
data: 'tel:+1234567890'
});
// Open website
await openUrl('https://example.com');
// Open location in maps
await openIntent({
action: 'android.intent.action.VIEW',
data: 'geo:37.7749,-122.4194?q=San+Francisco'
});
// Open maps with specific app
await openIntent({
action: 'android.intent.action.VIEW',
data: 'google.navigation:q=San+Francisco',
packageName: 'com.google.android.apps.maps'
});
// Send email using mailto
await openIntent({
action: 'android.intent.action.VIEW',
data: 'mailto:test@example.com?subject=Hello&body=Message'
});
// Share text
await openIntent({
action: 'android.intent.action.SEND',
mimeType: 'text/plain',
extras: {
'android.intent.extra.TEXT': 'Check this out!',
'android.intent.extra.SUBJECT': 'Amazing Content'
}
});
// Share image (Android)
await openIntent({
action: 'android.intent.action.SEND',
mimeType: 'image/*',
extras: {
'android.intent.extra.STREAM': 'file:///path/to/image.jpg'
}
});
All functions return a Promise<OpenIntentResponse>:
interface OpenIntentResponse {
success: boolean;
error?: string;
}
Always check the success field:
const result = await openPhoneDialer('+1234567890');
if (!result.success) {
console.error('Failed to open dialer:', result.error);
// Handle error appropriately
}
For certain intents, you may need to add permissions to your AndroidManifest.xml:
<!-- For phone calls -->
<uses-permission android:name="android.permission.CALL_PHONE" />
<!-- For sending SMS -->
<uses-permission android:name="android.permission.SEND_SMS" />
<!-- For camera access -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- For location access -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
The plugin includes a Leptos example demonstrating various intent operations:
cd examples/leptos-example
cargo tauri dev
# Build Rust code
cargo build
# Build JavaScript/TypeScript API
npm run build
# Run tests
cargo test
tauri-plugin-intent/
├── src/ # Rust plugin code
├── android/ # Android-specific implementation
├── guest-js/ # JavaScript/TypeScript API
├── examples/ # Example applications
│ └── leptos-example/ # Leptos integration example
├── permissions/ # Plugin permissions
└── README.md # This file
git checkout -b feature/amazing-feature)git commit -m 'Add amazing feature')git push origin feature/amazing-feature)Ensure you have:
Cargo.tomlmain.rsintent:default to your capabilitiesAndroidManifest.xmladb logcat | grep IntentDesktop platforms have limited intent support:
android.intent.action.VIEW with URLs is supportedThis project is licensed under the MIT License - see the LICENSE file for details.