Crates.io | tauri-plugin-sharetarget |
lib.rs | tauri-plugin-sharetarget |
version | |
source | src |
created_at | 2024-11-01 12:46:49.585953 |
updated_at | 2024-11-02 19:57:19.879835 |
description | tauri apps: receive share intents on Android |
homepage | |
repository | https://gitlab.com/lafleurdeboum/tauri-plugin-sharetarget |
max_upload_size | |
id | 1431753 |
Cargo.toml error: | TOML parse error at line 26, column 1 | 26 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include` |
size | 0 |
A plugin for Tauri applications to appear as a share target under Android. Desktop OSes are unsupported (they lack the feature). Behaviour on iOs is indeterminate.
In src-tauri/Cargo.toml
:
[dependencies]
tauri-plugin-sharetarget = "LATEST_VERSION_HERE"
In src-tauri/src/lib.rs
, add the plugin entry :
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_sharetarget::init())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
To build for Android, you must first tauri android init
successfully. This gets some files
generated. To signal your app as a share target to Android, you then need to modify your
AndroidManifest.xml
.
In src-tauri/gen/android/app/src/main/AndroidManifest.xml
, add your intent-filter
s :
<?xml version="1.0" encoding="utf-8">
<manifest ...>
...
<application ...>
...
<activity ...>
<intent-filter>
<!-- Support receiving share events. -->
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<!-- You can scope any MIME type here. You'll see what Intent Android returns. -->
<data android:mimeType="text/*" />
</intent-filter>
</activity ...>
...
First you need permissions in tauri, just to get ipc events in javascript.
In src-tauri/capabilities/default.json
, add sharetarget
to the permissions :
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "anything_you_like",
"windows": ["main"],
"permissions": [
...
"sharetarget:default"
]
}
Use the provided API in javascript/typescript. For example in React, in src/main.tsx
:
import { useEffect, useState } from 'react';
import { listenForShareEvents, type ShareEvent } from 'tauri-plugin-sharetarget-api';
import { PluginListener } from '@tauri-apps/api/core';
function App() {
const [logs, setLogs] = useState('');
useEffect(() => {
let listener: PluginListener;
const setupListener = async () => {
listener = await listenForShareEvents((intent: ShareEvent) => {
setLogs(intent.uri);
});
};
return () => { listener?.unregister(); };
};
return (<>
<h3>Share this</h3>
<p>{ logs }</p>
<button onClick={ yourCallbackFunction }>share</button>
</>);
}
To receive shared images, you need
intent
targeting image/*
@tauri-apps/plugin-fs
in package.json
dependencies to read the sent datafs:default
in the capabilities of your appreadFile()
from @tauri-apps/plugin-fs
on the
intent's stream
.Here is the previous example revamped to fetch binary contents. Upload({ file })
is not implemented because users may do whatever they like with the File
object.
This just showcases how to grab the binary data.
import { useEffect, useState } from 'react';
import { listenForShareEvents, type ShareEvent } from 'tauri-plugin-sharetarget-api';
import { PluginListener } from '@tauri-apps/api/core';
import { readFile } from '@tauri-apps/plugin-fs';
function App() {
const [logs, setLogs] = useState('');
const [file, setFile] = useState<File>();
useEffect(() => {
let listener: PluginListener;
const setupListener = async () => {
listener = await listenForShareEvents(async (intent: ShareEvent) => {
if(event.stream) {
const contents = await readFile(intent.stream).catch((error: Error) => {
console.warn('fetching shared content failed:');
throw error;
});
setFile(new File([contents], intent.name, { type: intent.content_type }));
} else {
// This intent contains no binary bundle.
console.warn('unused share intent', intent.uri);
}
setLogs(intent.uri);
});
};
setupListener();
return () => { listener?.unregister(); };
};
return (<>
<h3>Sharing { intent.name }</h3>
<Upload file={ file } />
</>);
}
Unfortunately, multiple files in a single share intent are not supported right now. iOs is also unsupported - I don't have the platform. PRs welcome !