小程序初始提交

This commit is contained in:
jdc
2025-11-13 10:36:23 +08:00
parent f26b4f9a2f
commit 5db3b180eb
447 changed files with 83351 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="uts.sdk.modules.coolShare">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application>
<meta-data android:name="ScopedStorage" android:value="true" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true"
tools:replace="android:authorities">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
</manifest>

View File

@@ -0,0 +1,3 @@
{
"minSdkVersion": "21"
}

View File

@@ -0,0 +1,459 @@
import Intent from "android.content.Intent";
import Uri from "android.net.Uri";
import Context from "android.content.Context";
import File from "java.io.File";
import FileProvider from "androidx.core.content.FileProvider";
import { ShareWithSystemOptions } from "../interface.uts";
/**
* 分享类型枚举
*/
const ShareType = {
TEXT: "text", // 纯文本分享
IMAGE: "image", // 图片分享
VIDEO: "video", // 视频分享
AUDIO: "audio", // 音频分享
FILE: "file", // 文件分享
LINK: "link" // 链接分享
};
/**
* MIME 类型映射
*/
const MimeTypes = {
IMAGE: "image/*",
VIDEO: "video/*",
AUDIO: "audio/*",
TEXT: "text/plain",
PDF: "application/pdf",
WORD: "application/msword",
EXCEL: "application/vnd.ms-excel",
PPT: "application/vnd.ms-powerpoint",
ZIP: "application/zip",
DEFAULT: "*/*"
};
/**
* 判断是否为网络 URL
* @param url 地址
* @returns 是否为网络 URL
*/
function isNetworkUrl(url: string): boolean {
return url.startsWith("http://") || url.startsWith("https://");
}
/**
* 根据文件路径获取 File 对象
* 按优先级尝试多种路径解析方式
* @param filePath 文件路径
* @returns File 对象或 null
*/
function getFileFromPath(filePath: string): File | null {
// 1. 尝试直接路径
let file = new File(filePath);
if (file.exists()) {
return file;
}
// 2. 尝试资源路径
file = new File(UTSAndroid.getResourcePath(filePath));
if (file.exists()) {
return file;
}
// 3. 尝试绝对路径转换
file = new File(UTSAndroid.convert2AbsFullPath(filePath));
if (file.exists()) {
return file;
}
return null;
}
/**
* 根据文件扩展名获取 MIME 类型
* @param filePath 文件路径
* @param defaultType 默认类型
* @returns MIME 类型字符串
*/
function getMimeTypeByPath(filePath: string, defaultType: string): string {
const ext = filePath.split(".").pop()?.toLowerCase() ?? "";
if (ext == "") {
return defaultType;
}
// 常见文件类型映射
const mimeMap = {
// 文档类型
pdf: MimeTypes["PDF"],
doc: MimeTypes["WORD"],
docx: MimeTypes["WORD"],
xls: MimeTypes["EXCEL"],
xlsx: MimeTypes["EXCEL"],
ppt: MimeTypes["PPT"],
pptx: MimeTypes["PPT"],
// 压缩包类型
zip: MimeTypes["ZIP"],
rar: "application/x-rar-compressed",
"7z": "application/x-7z-compressed",
tar: "application/x-tar",
gz: "application/gzip"
};
return (mimeMap[ext] as string) ?? defaultType;
}
/**
* 下载网络文件到本地缓存
* @param url 网络地址
* @param success 成功回调,返回本地文件路径
* @param fail 失败回调
*/
function downloadNetworkFile(
url: string,
success: (localPath: string) => void,
fail: (error: string) => void
): void {
uni.downloadFile({
url: url,
success: (res) => {
if (res.statusCode == 200) {
success(res.tempFilePath);
} else {
fail("下载失败,状态码: " + res.statusCode);
}
},
fail: (err) => {
fail("下载失败: " + (err.errMsg ?? "未知错误"));
}
});
}
/**
* 创建文件 Uri
* @param filePath 文件路径(支持本地路径和网络 URL
* @param success 成功回调
* @param fail 失败回调
*/
function createFileUriAsync(
filePath: string,
success: (uri: Uri) => void,
fail: (error: string) => void
): void {
// 创建文件Uri支持网络和本地文件。网络文件先下载到本地缓存再获取Uri。
const handleFileToUri = (localPath: string) => {
const file = getFileFromPath(localPath);
if (file == null) {
fail(`文件不存在: ${localPath}`);
return;
}
const context = UTSAndroid.getAppContext();
if (context == null) {
fail("无法获取App Context");
return;
}
const authority = context.getPackageName() + ".fileprovider";
const uri = FileProvider.getUriForFile(context, authority, file);
success(uri);
};
if (isNetworkUrl(filePath)) {
// 网络路径需先下载,下载完成后处理
downloadNetworkFile(filePath, handleFileToUri, fail);
} else {
// 本地文件直接处理
handleFileToUri(filePath);
}
}
/**
* 创建图片分享 Intent异步
* @param url 图片路径(支持本地路径和网络 URL
* @param title 分享标题
* @param success 成功回调
* @param fail 失败回调
*/
function createImageShareIntent(
url: string,
title: string,
success: (intent: Intent) => void,
fail: (error: string) => void
): void {
if (url == "") {
fail("图片路径不能为空");
return;
}
createFileUriAsync(
url,
(uri: Uri) => {
const intent = new Intent(Intent.ACTION_SEND);
intent.setType(MimeTypes["IMAGE"] as string);
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.putExtra(Intent.EXTRA_TITLE, title);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
success(intent);
},
(error: string) => {
fail(error);
}
);
}
/**
* 创建视频分享 Intent异步
* @param url 视频路径(支持本地路径和网络 URL
* @param title 分享标题
* @param success 成功回调
* @param fail 失败回调
*/
function createVideoShareIntent(
url: string,
title: string,
success: (intent: Intent) => void,
fail: (error: string) => void
): void {
if (url == "") {
fail("视频路径不能为空");
return;
}
createFileUriAsync(
url,
(uri: Uri) => {
const intent = new Intent(Intent.ACTION_SEND);
intent.setType(MimeTypes["VIDEO"] as string);
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.putExtra(Intent.EXTRA_TITLE, title);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
success(intent);
},
(error: string) => {
fail(error);
}
);
}
/**
* 创建音频分享 Intent异步
* @param url 音频路径(支持本地路径和网络 URL
* @param title 分享标题
* @param success 成功回调
* @param fail 失败回调
*/
function createAudioShareIntent(
url: string,
title: string,
success: (intent: Intent) => void,
fail: (error: string) => void
): void {
if (url == "") {
fail("音频路径不能为空");
return;
}
createFileUriAsync(
url,
(uri: Uri) => {
const intent = new Intent(Intent.ACTION_SEND);
intent.setType(MimeTypes["AUDIO"] as string);
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.putExtra(Intent.EXTRA_TITLE, title);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
success(intent);
},
(error: string) => {
fail(error);
}
);
}
/**
* 创建文件分享 Intent异步
* @param filePath 文件路径(支持本地路径和网络 URL
* @param title 分享标题
* @param success 成功回调
* @param fail 失败回调
*/
function createFileShareIntent(
filePath: string,
title: string,
success: (intent: Intent) => void,
fail: (error: string) => void
): void {
if (filePath == "") {
fail("文件路径不能为空");
return;
}
createFileUriAsync(
filePath,
(uri: Uri) => {
// 根据文件扩展名确定 MIME 类型
const mimeType = getMimeTypeByPath(filePath, MimeTypes["DEFAULT"] as string);
const intent = new Intent(Intent.ACTION_SEND);
intent.setType(mimeType);
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.putExtra(Intent.EXTRA_TITLE, title);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
success(intent);
},
(error: string) => {
fail(error);
}
);
}
/**
* 创建链接分享 Intent
* @param url 链接地址
* @param title 分享标题
* @param summary 分享描述
* @param success 成功回调
* @param fail 失败回调
*/
function createLinkShareIntent(
url: string,
title: string,
summary: string,
success: (intent: Intent) => void,
fail: (error: string) => void
): void {
if (url == "") {
fail("链接地址不能为空");
return;
}
// 组合分享内容:标题 + 描述 + 链接
let content = "";
if (title != "") {
content = title;
}
if (summary != "") {
content = content == "" ? summary : content + "\n" + summary;
}
if (url != "") {
content = content == "" ? url : content + "\n" + url;
}
const intent = new Intent(Intent.ACTION_SEND);
intent.setType(MimeTypes["TEXT"] as string);
intent.putExtra(Intent.EXTRA_TEXT, content);
success(intent);
}
/**
* 创建文本分享 Intent
* @param title 分享标题
* @param summary 分享描述
* @param url 附加链接(可选)
* @param success 成功回调
*/
function createTextShareIntent(
title: string,
summary: string,
url: string,
success: (intent: Intent) => void
): void {
// 组合分享内容
let content = "";
if (title != "") {
content = title;
}
if (summary != "") {
content = content == "" ? summary : content + "\n" + summary;
}
if (url != "") {
content = content == "" ? url : content + "\n" + url;
}
// 如果内容为空,使用默认文本
if (content == "") {
content = "分享内容";
}
const intent = new Intent(Intent.ACTION_SEND);
intent.setType(MimeTypes["TEXT"] as string);
intent.putExtra(Intent.EXTRA_TEXT, content);
success(intent);
}
/**
* 启动分享 Activity
* @param intent 分享 Intent
* @param title 选择器标题
* @param success 成功回调
* @param fail 失败回调
*/
function startShareActivity(
intent: Intent,
title: string,
success: () => void,
fail: (error: string) => void
): void {
const chooserTitle = title != "" ? title : "选择分享方式";
const chooser = Intent.createChooser(intent, chooserTitle);
try {
UTSAndroid.getUniActivity()!.startActivity(chooser);
success();
} catch (e: Exception) {
const errorMsg = e.message ?? "分享失败";
fail(errorMsg);
}
}
/**
* 系统分享功能
* @param options 分享参数
* @param options.type 分享类型: text(文本) | image(图片) | video(视频) | audio(音频) | file(文件) | link(链接)
* @param options.title 分享标题
* @param options.summary 分享描述/内容
* @param options.url 资源路径(图片/视频/音频/文件路径或链接地址,支持本地路径和网络 URL
* @param options.success 成功回调
* @param options.fail 失败回调
*/
export function shareWithSystem(options: ShareWithSystemOptions): void {
const type = options.type;
const title = options.title ?? "";
const summary = options.summary ?? "";
const url = options.url ?? "";
// 成功和失败回调
const onSuccess = (intent: Intent) => {
startShareActivity(
intent,
title,
() => {
options.success?.();
},
(error: string) => {
options.fail?.(error);
}
);
};
const onFail = (error: string) => {
options.fail?.(error);
};
// 根据分享类型创建对应的 Intent
if (type == ShareType["IMAGE"]) {
createImageShareIntent(url, title, onSuccess, onFail);
} else if (type == ShareType["VIDEO"]) {
createVideoShareIntent(url, title, onSuccess, onFail);
} else if (type == ShareType["AUDIO"]) {
createAudioShareIntent(url, title, onSuccess, onFail);
} else if (type == ShareType["FILE"]) {
createFileShareIntent(url, title, onSuccess, onFail);
} else if (type == ShareType["LINK"]) {
createLinkShareIntent(url, title, summary, onSuccess, onFail);
} else {
// 默认为文本分享
createTextShareIntent(title, summary, url, onSuccess);
}
}

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 外部存储路径 -->
<external-path name="external_files" path="." />
<!-- 外部缓存路径 -->
<external-cache-path name="external_cache" path="." />
<!-- 应用缓存路径(用于 uni.downloadFile 下载的临时文件) -->
<cache-path name="cache" path="." />
<!-- 应用内部文件路径 -->
<files-path name="files" path="." />
<!-- 根路径(谨慎使用) -->
<root-path name="root" path="." />
</paths>

View File

@@ -0,0 +1,13 @@
import { ShareWithSystemOptions } from "../interface.uts";
import { share } from "./share.ets";
export function shareWithSystem(options: ShareWithSystemOptions) {
share(
options.type,
options.title ?? "",
options.summary ?? "",
options.url ?? "",
options.success ?? (() => {}),
options.fail ?? (() => {})
);
}

View File

@@ -0,0 +1,265 @@
import { UTSHarmony } from '@dcloudio/uni-app-x-runtime';
import { systemShare } from '@kit.ShareKit';
import { uniformTypeDescriptor as utd } from '@kit.ArkData';
import { common } from '@kit.AbilityKit';
import { fileUri } from '@kit.CoreFileKit';
import { BusinessError } from '@kit.BasicServicesKit';
/**
* 分享类型枚举
*/
enum ShareType {
TEXT = "text", // 纯文本分享
IMAGE = "image", // 图片分享
VIDEO = "video", // 视频分享
AUDIO = "audio", // 音频分享
FILE = "file", // 文件分享
LINK = "link" // 链接分享
}
/**
* 根据文件路径获取统一数据类型标识符
* @param filePath 文件路径
* @param defaultType 默认数据类型
* @returns 统一数据类型标识符
*/
function getUtdTypeByPath(filePath: string, defaultType: string): string {
const ext = filePath?.split('.')?.pop()?.toLowerCase() ?? '';
if (ext === '') {
return defaultType;
}
return utd.getUniformDataTypeByFilenameExtension('.' + ext, defaultType);
}
/**
* 创建图片分享数据
* @param url 图片路径(支持本地路径和网络 URL
* @param title 分享标题
* @param summary 分享描述
* @returns 分享数据对象
*/
function createImageShareData(url: string, title: string, summary: string): systemShare.SharedData | null {
if (url === '') {
return null;
}
const filePath = UTSHarmony.getResourcePath(url);
const utdTypeId = getUtdTypeByPath(filePath, utd.UniformDataType.IMAGE);
return new systemShare.SharedData({
utd: utdTypeId,
uri: fileUri.getUriFromPath(filePath),
title: title,
description: summary,
});
}
/**
* 创建视频分享数据
* @param url 视频路径(支持本地路径和网络 URL
* @param title 分享标题
* @param summary 分享描述
* @returns 分享数据对象
*/
function createVideoShareData(url: string, title: string, summary: string): systemShare.SharedData | null {
if (url === '') {
return null;
}
const filePath = UTSHarmony.getResourcePath(url);
const utdTypeId = getUtdTypeByPath(filePath, utd.UniformDataType.VIDEO);
return new systemShare.SharedData({
utd: utdTypeId,
uri: fileUri.getUriFromPath(filePath),
title: title,
description: summary,
});
}
/**
* 创建音频分享数据
* @param url 音频路径(支持本地路径和网络 URL
* @param title 分享标题
* @param summary 分享描述
* @returns 分享数据对象
*/
function createAudioShareData(url: string, title: string, summary: string): systemShare.SharedData | null {
if (url === '') {
return null;
}
const filePath = UTSHarmony.getResourcePath(url);
const utdTypeId = getUtdTypeByPath(filePath, utd.UniformDataType.AUDIO);
return new systemShare.SharedData({
utd: utdTypeId,
uri: fileUri.getUriFromPath(filePath),
title: title,
description: summary,
});
}
/**
* 创建文件分享数据
* @param filePath 文件路径(支持本地路径和网络 URL
* @param title 分享标题
* @param summary 分享描述
* @returns 分享数据对象
*/
function createFileShareData(filePath: string, title: string, summary: string): systemShare.SharedData | null {
if (filePath === '') {
return null;
}
const resourcePath = UTSHarmony.getResourcePath(filePath);
const ext = resourcePath?.split('.')?.pop()?.toLowerCase() ?? '';
// 根据文件扩展名确定数据类型
let utdType = utd.UniformDataType.FILE;
let utdTypeId = '';
// 支持常见的文件类型
switch (ext) {
case 'zip':
case 'rar':
case '7z':
case 'tar':
case 'gz':
utdType = utd.UniformDataType.ARCHIVE;
break;
case 'pdf':
utdType = utd.UniformDataType.PDF;
break;
case 'doc':
case 'docx':
utdType = utd.UniformDataType.WORD_DOC;
break;
case 'xls':
case 'xlsx':
utdType = utd.UniformDataType.EXCEL;
break;
case 'ppt':
case 'pptx':
utdType = utd.UniformDataType.PPT;
break;
default:
utdType = utd.UniformDataType.FILE;
break;
}
utdTypeId = utd.getUniformDataTypeByFilenameExtension('.' + ext, utdType);
return new systemShare.SharedData({
utd: utdTypeId,
uri: fileUri.getUriFromPath(resourcePath),
title: title,
description: summary,
});
}
/**
* 创建链接分享数据
* @param url 链接地址
* @param title 分享标题
* @param summary 分享描述
* @returns 分享数据对象
*/
function createLinkShareData(url: string, title: string, summary: string): systemShare.SharedData {
return new systemShare.SharedData({
utd: utd.UniformDataType.HYPERLINK,
title: title,
content: url,
description: summary
});
}
/**
* 创建文本分享数据
* @param title 分享标题
* @param summary 分享内容
* @returns 分享数据对象
*/
function createTextShareData(title: string, summary: string): systemShare.SharedData {
return new systemShare.SharedData({
utd: utd.UniformDataType.TEXT,
title: title,
content: summary
});
}
/**
* 系统分享功能
* @param options 分享参数
* @param options.type 分享类型: text(文本) | image(图片) | video(视频) | audio(音频) | file(文件) | link(链接)
* @param options.title 分享标题
* @param options.summary 分享描述/内容
* @param options.url 资源路径(图片/视频/音频/文件路径或链接地址,支持本地路径和网络 URL
* @param options.success 成功回调
* @param options.fail 失败回调
*/
export function share(type: string, title: string, summary: string, url: string, success: () => void, fail: (error: string) => void): void {
// 获取UI上下文
const uiContext: UIContext = UTSHarmony.getCurrentWindow()?.getUIContext();
const context: common.UIAbilityContext = uiContext.getHostContext() as common.UIAbilityContext;
// 根据分享类型创建分享数据
let shareData: systemShare.SharedData | null = null;
let errorMsg = '';
switch (type) {
case ShareType.IMAGE:
shareData = createImageShareData(url, title, summary);
errorMsg = '图片路径不能为空';
break;
case ShareType.VIDEO:
shareData = createVideoShareData(url, title, summary);
errorMsg = '视频路径不能为空';
break;
case ShareType.AUDIO:
shareData = createAudioShareData(url, title, summary);
errorMsg = '音频路径不能为空';
break;
case ShareType.FILE:
shareData = createFileShareData(url, title, summary);
errorMsg = '文件路径不能为空';
break;
case ShareType.LINK:
shareData = createLinkShareData(url, title, summary);
break;
default:
// 默认为文本分享
shareData = createTextShareData(title, summary);
errorMsg = '分享内容不能为空';
break;
}
// 验证分享数据
if (shareData === null) {
fail(errorMsg);
return;
}
// 创建分享控制器
const controller: systemShare.ShareController = new systemShare.ShareController(shareData);
// 显示分享面板,配置分享选项
controller.show(context, {
selectionMode: systemShare.SelectionMode.SINGLE, // 单选模式
previewMode: systemShare.SharePreviewMode.DEFAULT, // 默认预览模式
})
.then(() => {
// 分享成功
success();
})
.catch((error: BusinessError) => {
// 分享失败,返回错误信息
const errorMessage = error?.message ?? '分享失败';
fail(errorMessage);
});
}

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array/>
<key>NSPrivacyCollectedDataTypes</key>
<array/>
<key>NSPrivacyTracking</key>
<false/>
<key>NSPrivacyTrackingDomains</key>
<array/>
</dict>
</plist>

View File

@@ -0,0 +1,3 @@
{
"deploymentTarget": "12"
}

View File

@@ -0,0 +1,287 @@
import { UIActivityViewController, UIImage } from "UIKit";
import { URL, Data } from "Foundation";
import { ShareWithSystemOptions } from "../interface.uts";
/**
* 分享类型枚举
*/
const ShareType = {
TEXT: "text", // 纯文本分享
IMAGE: "image", // 图片分享
VIDEO: "video", // 视频分享
AUDIO: "audio", // 音频分享
FILE: "file", // 文件分享
LINK: "link" // 链接分享
};
/**
* 判断是否为网络 URL
* @param url 地址
* @returns 是否为网络 URL
*/
function isNetworkUrl(url: string): boolean {
return url.startsWith("http://") || url.startsWith("https://");
}
/**
* 下载网络文件到本地缓存
* @param url 网络地址
* @param success 成功回调,返回本地文件路径
* @param fail 失败回调
*/
function downloadNetworkFile(
url: string,
success: (localPath: string) => void,
fail: (error: string) => void
): void {
uni.downloadFile({
url: url,
success: (res) => {
if (res.statusCode == 200) {
success(res.tempFilePath);
} else {
fail(`下载失败,状态码: ${res.statusCode}`);
}
},
fail: (err) => {
fail(`下载失败: ${err.errMsg ?? "未知错误"}`);
}
});
}
/**
* 处理文件路径并加载数据
* @param filePath 文件路径
* @returns Data 对象或 null
*/
function loadFileData(filePath: string): Data | null {
const absolutePath = UTSiOS.convert2AbsFullPath(filePath);
const fileURL = new URL((fileURLWithPath = absolutePath));
const data = UTSiOS.try(new Data((contentsOf = fileURL)), "?");
return data;
}
/**
* 创建文本分享内容
* @param title 标题
* @param summary 描述
* @param url 链接
* @returns 分享内容数组
*/
function createTextShareItems(title: string, summary: string, url: string): any[] {
// 组合分享内容
let content = "";
if (title != "") {
content = title;
}
if (summary != "") {
content = content == "" ? summary : content + "\n" + summary;
}
if (url != "") {
content = content == "" ? url : content + "\n" + url;
}
// 如果内容为空,使用默认文本
if (content == "") {
content = "分享内容";
}
return [content];
}
/**
* 创建图片分享内容
* @param url 图片路径
* @param success 成功回调
* @param fail 失败回调
*/
function createImageShareItems(
url: string,
success: (items: any[]) => void,
fail: (error: string) => void
): void {
if (url == "") {
fail("图片路径不能为空");
return;
}
const handleImagePath = (localPath: string) => {
const absolutePath = UTSiOS.convert2AbsFullPath(localPath);
const image = new UIImage((contentsOfFile = absolutePath));
if (image == null) {
fail("图片加载失败");
return;
}
success([image]);
};
if (isNetworkUrl(url)) {
// 网络图片先下载
downloadNetworkFile(url, handleImagePath, fail);
} else {
// 本地图片直接处理
handleImagePath(url);
}
}
/**
* 创建文件分享内容(视频、音频、文件)
* @param filePath 文件路径
* @param success 成功回调
* @param fail 失败回调
*/
function createFileShareItems(
filePath: string,
success: (items: any[]) => void,
fail: (error: string) => void
): void {
if (filePath == "") {
fail("文件路径不能为空");
return;
}
const handleFilePath = (localPath: string) => {
const data = loadFileData(localPath);
if (data == null) {
fail("文件加载失败");
return;
}
const absolutePath = UTSiOS.convert2AbsFullPath(localPath);
const fileURL = new URL.init((fileURLWithPath = absolutePath));
success([data, fileURL]);
};
if (isNetworkUrl(filePath)) {
// 网络文件先下载
downloadNetworkFile(filePath, handleFilePath, fail);
} else {
// 本地文件直接处理
handleFilePath(filePath);
}
}
/**
* 启动系统分享界面
* @param items 分享内容数组
* @param success 成功回调
* @param fail 失败回调
*/
function presentShareController(
items: any[],
success: () => void,
fail: (error: string) => void
): void {
DispatchQueue.main.async(
(execute = (): void => {
const activityViewController = new UIActivityViewController(
(activityItems = items),
(applicationActivities = nil)
);
const currentVC = UTSiOS.getCurrentViewController();
if (currentVC == null) {
fail("无法获取当前视图控制器");
return;
}
currentVC.present(
activityViewController,
(animated = true),
(completion = () => {
success();
})
);
})
);
}
/**
* 系统分享功能
* @param options 分享参数
* @param options.type 分享类型: text(文本) | image(图片) | video(视频) | audio(音频) | file(文件) | link(链接)
* @param options.title 分享标题
* @param options.summary 分享描述/内容
* @param options.url 资源路径(图片/视频/音频/文件路径或链接地址,支持本地路径和网络 URL
* @param options.success 成功回调
* @param options.fail 失败回调
*/
export function shareWithSystem(options: ShareWithSystemOptions): void {
const type = options.type;
const title = options.title ?? "";
const summary = options.summary ?? "";
const url = options.url ?? "";
// 根据分享类型创建对应的内容
if (type == (ShareType["TEXT"] as string) || type == (ShareType["LINK"] as string)) {
// 文本或链接分享
const items = createTextShareItems(title, summary, url);
presentShareController(
items,
() => {
options.success?.();
},
(error: string) => {
options.fail?.(error);
}
);
} else if (type == (ShareType["IMAGE"] as string)) {
// 图片分享
createImageShareItems(
url,
(items: any[]) => {
presentShareController(
items,
() => {
options.success?.();
},
(error: string) => {
options.fail?.(error);
}
);
},
(error: string) => {
options.fail?.(error);
}
);
} else if (
type == (ShareType["VIDEO"] as string) ||
type == (ShareType["AUDIO"] as string) ||
type == (ShareType["FILE"] as string)
) {
// 视频、音频、文件分享
createFileShareItems(
url,
(items: any[]) => {
presentShareController(
items,
() => {
options.success?.();
},
(error: string) => {
options.fail?.(error);
}
);
},
(error: string) => {
options.fail?.(error);
}
);
} else {
// 未知类型,默认使用文本分享
const items = createTextShareItems(title, summary, url);
presentShareController(
items,
() => {
options.success?.();
},
(error: string) => {
options.fail?.(error);
}
);
}
}

View File

@@ -0,0 +1,29 @@
export type ShareWithSystemOptions = {
/**
* 分享类型:
* text(文本) | image(图片) | video(视频) | audio(音频) | file(文件) | link(链接)
*/
type: string;
/**
* 分享标题
*/
title?: string;
/**
* 分享描述或内容
*/
summary?: string;
/**
* 分享资源路径:
* 如果是图片/视频/音频/文件填写资源路径或网络URL
* 如果是link填写链接地址
*/
url?: string;
/**
* 分享成功回调
*/
success?: () => void;
/**
* 分享失败回调,返回错误信息
*/
fail?: (error: string) => void;
};