我尝试在单击按钮时从我的应用程序下载 PDF 文件,并在下载完成后立即打开它。我使用 expo-file-system 来保存下载的文件,并使用 expo-linking 在为 iOS 设备下载文件后触发文件的打开。我还使用 expo-intent-launcher 来触发 Android 设备上的文件打开。这对于 Android 来说非常有效,但在 iOS 上却不起作用,我已经研究了几个小时了。我不确定我做错了什么。我的代码片段如下所示:
import * as FileSystem from "expo-file-system";
import * as Linking from "expo-linking";
import * as IntentLauncher from "expo-intent-launcher";
import { Button } from "react-native"
export default function PdfDocumentsScreen() {
const { isAndroid } = useDevicePlatform();
const downloadPDF = async () => {
try {
const uri =
"https://${name}.s3.amazonaws.com/${bucket_name}/Certificate1.pdf";
const fileUri = FileSystem.documentDirectory + "Certificate.pdf";
const downloadObject = FileSystem.createDownloadResumable(uri, fileUri);
const response = await downloadObject.downloadAsync();
console.log(response);
if (response?.status === 200) {
openPDF(fileUri);
} else {
console.error("Failed to download the PDF");
}
} catch (error) {
console.error("Error downloading the PDF: ", error);
}
};
const openPDF = async (fileUri: string) => {
try {
const contentUri = await FileSystem.getContentUriAsync(fileUri);
console.log("Content URI: ", contentUri);
if (!isAndroid) {
if (await Linking.canOpenURL(contentUri)) {
Linking.openURL(contentUri);
}
} else {
IntentLauncher.startActivityAsync("android.intent.action.VIEW", {
data: contentUri,
flags: 1,
});
}
} catch (error) {
console.error("Error opening the PDF: ", error);
}
};
return (
<Button title="Download PDF" onPress={downloadPDF} />
)
}
更新!!
我早就解决了这个问题,但我认为发布我如何解决这个问题会很棒,因为这个问题没有得到有用的答案。
这适用于 Android 而不是 iOS 的原因是因为 expo-file-system
FileSystem.getContentUriAsync()
仅适用于 Android,如文档中所述:https://docs.expo.dev/versions/latest/sdk /文件系统/#filesystemgetcontenturiasyncfileuri
为了解决这个问题,我决定在 iOS 上使用 expo-sharing 来触发 PDF 的打开,在 Android 上使用 expo-intent-launcher 来触发打开。
更新后的代码如下所示:
const callback = (
downloadProgress: {
totalBytesExpectedToWrite: number;
totalBytesWritten: number;
},
id: string
) => {
const progress =
downloadProgress.totalBytesWritten /
downloadProgress.totalBytesExpectedToWrite;
setDownloadProgress({
progress,
id: item._id!,
});
};
const downloadPDF = async () => {
try {
const uri = item.url;
const fileUri = FileSystem.documentDirectory + `${fileName}.${extension}`;
const downloadObject = FileSystem.createDownloadResumable(
uri,
fileUri,
{},
(downloadOption) => {
callback(downloadOption, id);
}
);
const response = await downloadObject.downloadAsync();
if (response?.status === 200) {
await openPDF(response.uri, response.mimeType);
} else {
setDownloadProgress({ progress: 0, id: "" });
setDownloadError("Failed to download the PDF");
}
} catch (error) {
console.error("Error downloading the PDF: ", error);
if (error instanceof Error) {
setDownloadError(error.message);
} else {
setDownloadError(`Error: ${JSON.stringify(error)}`);
}
setDownloadProgress({ progress: 0, id: "" });
}
};
const openPDF = async (fileUri: string, mimeType: string | null) => {
try {
const contentUri = await FileSystem.getContentUriAsync(fileUri);
if (!isAndroid) {
Sharing.shareAsync(contentUri, { UTI: mimeType! });
} else {
IntentLauncher.startActivityAsync("android.intent.action.VIEW", {
data: contentUri,
flags: 1,
});
}
} catch (error) {
if (error instanceof Error) {
setDownloadError(error.message);
} else {
setDownloadError(`Error: ${JSON.stringify(error)}`);
}
}
};