尝试让Android选择器显示可用的操作,以便用户启动存储在我的本地文件夹中的PDF文件。 当我传递像 /data/user/0/myappappname/files/output.pdf 这样的文件名时(当然,它存在),我得到了一个很好的选择,包含了所有可以接受的应用程序pdf文件。但当我选择其中任何一个时,我收到错误(来自外部应用程序)文档路径无效。不会抛出任何异常。
然后我尝试(出于测试目的)将 fname 设置为 /storage/emulated/0/Download/TLCL.pdf (文件也存在),以及一切正常。
起初,我认为这与文件权限有关(因为第一个路径是我的应用程序的私有路径),但后来我发现标志 ActivityFlags.GrantReadUriPermission 正是为了暂时授予的目的而构建的文件访问其他应用程序。结果仍然相同。
由于这是一个Xamarin.forms项目,我选择文件创建位置是有限的(我使用PCLStorage,它总是写入app-private,本地文件夹),所以我没有选择生成文件/文件,/下载等。
我显然做错了什么。任何想法都赞赏。
是否有从系统获取完整路径的选项,包括 / storage / emulated / 0 部分(或其他设备上的任何内容)?也许这会有所帮助吗?
一段代码:
(mimeType早先定义为“application / pdf”)
SqlPrompt
答案 0 :(得分:1)
我的解决方案可能不是您想要的,是生成一个文件(在我的情况下是一个zip文件),将其导出到公共文件夹,并将该文件用于选择器。
使用这些:
private readonly string PublicDocsPath = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + "/AppName";
private readonly string PrivateDocsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData);
和一些基本功能:
public Stream GetOutputStream(string destFilePath)
{
string destFolderPath = Path.GetDirectoryName(destFilePath);
if (!Directory.Exists(destFolderPath))
Directory.CreateDirectory(destFolderPath);
return new FileStream(destFilePath, FileMode.Create, FileAccess.Write, FileShare.None);
}
public Stream GetInputStream(string sourceFilePath)
{
if (!File.Exists(sourceFilePath)) throw new FileNotFoundException();
string sourceFolderPath = Path.GetDirectoryName(sourceFilePath);
return new FileStream(sourceFilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
}
您可以将文件复制到公用文件夹(或子文件夹,只需组装路径)并将该文件用于选择器:
public void SendEmail(string subject, string body, string recipient, string mimeType, string attachmentFilePath, string activityTitle)
{
var emailIntent = new Intent(Intent.ActionSendMultiple);
if (string.IsNullOrEmpty(subject)) throw new ArgumentException();
emailIntent.PutExtra(Intent.ExtraSubject, subject);
if (!string.IsNullOrEmpty(recipient))
emailIntent.PutExtra(Intent.ExtraEmail, new[] { recipient });
if (!string.IsNullOrEmpty(body))
emailIntent.PutExtra(Intent.ExtraText, body);
if (!string.IsNullOrEmpty(attachmentFilePath))
{
var file = new Java.IO.File(attachmentFilePath);
file.SetReadable(true, true);
var uri = Android.Net.Uri.FromFile(file);
emailIntent.PutParcelableArrayListExtra(Intent.ExtraStream, new List<IParcelable>(){uri});
}
emailIntent.SetType(mimeType);
_activity.StartActivity(Intent.CreateChooser(emailIntent, activityTitle));
}
此选择器专门允许用户通过电子邮件或谷歌驱动器发送文件,但您可以随意组装它。此函数的attachmentFilePath与传递给上面的GetOutputStream函数的字符串相同。
答案 1 :(得分:0)
我们正在使用Acr.IO而不是PCLStorage,我记得有一个属性可以为您返回完整路径。 我们正在使用的代码如下,但我想知道您是否只是缺少&#34; file://&#34;在你的路径的开头,我注意到在我们的代码中,以及之前的stackoverflow回答了与此问题类似的问题,open a PDF in Xamarin.Forms (Android) 我们在Android上使用依赖FileService并使用此代码打开PDF:
updateDataset = function(target, chart, label, color, data) {
var store = chart.data.datasets[0].label;
var bgcolor = chart.data.datasets[0].backgroundColor;
var dataSets = chart.data.datasets[0].data;
var exists = false;
for (var i = 0; i < chart.data.datasets[0].label.length; i++) {
if (chart.data.datasets[0].label[i] === label) {
chart.data.datasets[0].label
exists = true;
chart.data.datasets[0].label.push(store.splice(i, 1)[0][1]);
chart.data.datasets[0].backgroundColor.push(bgcolor.splice(i, 1)[0][1]);
chart.data.datasets[0].data.push(dataSets.splice(i, 1)[0][1]);
}
}
if (!exists) {
chart.data.datasets[0].label.push(label);
chart.data.datasets[0].backgroundColor.push(color);
chart.data.datasets[0].data.push(data);
exists = false;
}
chart.update();
};