Xamarin.Forms 在本地存储中保存文件 (pdf) 并使用默认查看器打开
Xamarin.Forms save file (pdf) in local storage and open with the default viewer
编辑以完善问题
在Android中,我需要下载一个pdf文件到"Documents"文件夹,然后用默认程序打开它。
我下载了文档并将其存储在一个字节数组中。
然后我调用这个方法:
/// <summary>
/// Save data bytes on "My documents" folder and open
/// </summary>
/// <param name="fileName">Filename, for example: "Test.pdf"</param>
/// <param name="data">Array of bytes to save</param>
/// <returns>True if success or false if error</returns>
public bool SaveAndOpen(string fileName, byte[] data)
{
try
{
// Get my documents path
string filePath = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, Android.OS.Environment.DirectoryDownloads);
// Combine with filename
string fullName = Path.Combine(filePath, fileName);
// If the file exist on device delete it
if (File.Exists(fullName))
{
// Note: In the second run of this method, the file exists
File.Delete(fullName);
}
// Write bytes on "My documents"
File.WriteAllBytes(fullName, data);
// Launch file as process
Process.Start(fullName);
return true;
}
catch (Exception ex)
{
Console.WriteLine("ERROR: " + ex.Message + ex.StackTrace);
return false;
}
}
问题是用默认pdf打开pdf文档reader。
第"Process.Start(fullName);"行抛出异常
System.ComponentModel.Win32Exception (0x80004005): Access denied
感谢您的宝贵时间!
我找到了保存和打开文件的方法:
/// <summary>
/// Save data bytes on "My documents" folder and open
/// </summary>
/// <param name="fileName">Filename, for example: "Test.pdf"</param>
/// <param name="data">Array of bytes to save</param>
/// <returns>True if success or false if error</returns>
public bool SaveAndOpen(string fileName, byte[] data)
{
try
{
// Get my downloads path
string filePath = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, Android.OS.Environment.DirectoryDownloads);
// Combine with filename
string fullName = Path.Combine(filePath, fileName);
// If the file exist on device delete it
if (File.Exists(fullName))
{
// Note: In the second run of this method, the file exists
File.Delete(fullName);
}
// Write bytes on "My documents"
File.WriteAllBytes(fullName, data);
// Get the uri for the saved file
Android.Net.Uri file = Android.Support.V4.Content.FileProvider.GetUriForFile(
this,
this.PackageName + ".fileprovider",
new Java.IO.File(fileName));
Intent intent = new Intent(Intent.ActionView);
intent.SetDataAndType(file, "application/pdf");
intent.SetFlags(ActivityFlags.ClearWhenTaskReset | ActivityFlags.NewTask | ActivityFlags.GrantReadUriPermission | ActivityFlags.NewTask);
this.ApplicationContext.StartActivity(intent);
return true;
}
catch (Exception ex)
{
Console.WriteLine("ERROR: " + ex.Message + ex.StackTrace);
return false;
}
}
需要在运行时请求权限。我使用了 Nuget 上可用的 Plugin.Permisions:
Plugin.Permissions.PermissionsImplementation.Current.RequestPermissionsAsync(
new Plugin.Permissions.Abstractions.Permission[]
{
Plugin.Permissions.Abstractions.Permission.Storage,
Plugin.Permissions.Abstractions.Permission.MediaLibrary
});
还在 AndroidManifest.xml 文件中添加提供程序:
<application android:label="My app" android:icon="@mipmap/icon">
<provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"></meta-data>
</provider>
</application>
在同一个 AndroidManifest 中添加权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
并在Resources/xml/file_paths中添加一个外部路径。xml
<external-path name="external_files" path="."/>
不知道我是不是不需要权限,但是用这个方法可以。
编辑以完善问题
在Android中,我需要下载一个pdf文件到"Documents"文件夹,然后用默认程序打开它。 我下载了文档并将其存储在一个字节数组中。 然后我调用这个方法:
/// <summary>
/// Save data bytes on "My documents" folder and open
/// </summary>
/// <param name="fileName">Filename, for example: "Test.pdf"</param>
/// <param name="data">Array of bytes to save</param>
/// <returns>True if success or false if error</returns>
public bool SaveAndOpen(string fileName, byte[] data)
{
try
{
// Get my documents path
string filePath = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, Android.OS.Environment.DirectoryDownloads);
// Combine with filename
string fullName = Path.Combine(filePath, fileName);
// If the file exist on device delete it
if (File.Exists(fullName))
{
// Note: In the second run of this method, the file exists
File.Delete(fullName);
}
// Write bytes on "My documents"
File.WriteAllBytes(fullName, data);
// Launch file as process
Process.Start(fullName);
return true;
}
catch (Exception ex)
{
Console.WriteLine("ERROR: " + ex.Message + ex.StackTrace);
return false;
}
}
问题是用默认pdf打开pdf文档reader。
第"Process.Start(fullName);"行抛出异常
System.ComponentModel.Win32Exception (0x80004005): Access denied
感谢您的宝贵时间!
我找到了保存和打开文件的方法:
/// <summary>
/// Save data bytes on "My documents" folder and open
/// </summary>
/// <param name="fileName">Filename, for example: "Test.pdf"</param>
/// <param name="data">Array of bytes to save</param>
/// <returns>True if success or false if error</returns>
public bool SaveAndOpen(string fileName, byte[] data)
{
try
{
// Get my downloads path
string filePath = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, Android.OS.Environment.DirectoryDownloads);
// Combine with filename
string fullName = Path.Combine(filePath, fileName);
// If the file exist on device delete it
if (File.Exists(fullName))
{
// Note: In the second run of this method, the file exists
File.Delete(fullName);
}
// Write bytes on "My documents"
File.WriteAllBytes(fullName, data);
// Get the uri for the saved file
Android.Net.Uri file = Android.Support.V4.Content.FileProvider.GetUriForFile(
this,
this.PackageName + ".fileprovider",
new Java.IO.File(fileName));
Intent intent = new Intent(Intent.ActionView);
intent.SetDataAndType(file, "application/pdf");
intent.SetFlags(ActivityFlags.ClearWhenTaskReset | ActivityFlags.NewTask | ActivityFlags.GrantReadUriPermission | ActivityFlags.NewTask);
this.ApplicationContext.StartActivity(intent);
return true;
}
catch (Exception ex)
{
Console.WriteLine("ERROR: " + ex.Message + ex.StackTrace);
return false;
}
}
需要在运行时请求权限。我使用了 Nuget 上可用的 Plugin.Permisions:
Plugin.Permissions.PermissionsImplementation.Current.RequestPermissionsAsync(
new Plugin.Permissions.Abstractions.Permission[]
{
Plugin.Permissions.Abstractions.Permission.Storage,
Plugin.Permissions.Abstractions.Permission.MediaLibrary
});
还在 AndroidManifest.xml 文件中添加提供程序:
<application android:label="My app" android:icon="@mipmap/icon">
<provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"></meta-data>
</provider>
</application>
在同一个 AndroidManifest 中添加权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
并在Resources/xml/file_paths中添加一个外部路径。xml
<external-path name="external_files" path="."/>
不知道我是不是不需要权限,但是用这个方法可以。