Opening local files in edit mode with Microsoft Office mobile app using Android
我正在开发一个 Android 应用程序,我想从该应用程序启动 MS Office 应用程序来查看和编辑 Office 文件。例如,打开存储在设备本地的 docx,以便在 MS-Word 移动应用程序中进行编辑。
以前,我们打开此类文件时会使用在意图中传递的文件 URI,例如"com.microsoft.office.word" 包名称。该文件将在 Word for Android 中打开,用户可以对其进行编辑和保存。没问题。
现在我们必须进行更改,以便我们使用具有读写权限的 Android 的 FileProvider 类。通过此实施,其他应用程序可以编辑文件,但适用于 Android 的 Microsoft Office 应用程序以只读模式打开,无法更改它。
这似乎是其他人也会遇到的常见问题,如其他 stackoverflow 问题所示:
使用 Android 文件提供程序时,尽管在意图中标记了 FLAG_GRANT_WRITE_URI_PERMISSION,但文件没有正确的权限
和
Xamarin.Forms Android FileProvider:GrantWriteUriPermission 并不总是有效
我还找到了这个链接,其中包含有关如何在 msdn 中调用 office 应用程序的信息,但它似乎很不完整,我无法使其与意图和本地文件一起工作(我只是不\\ '不知道如何发送 ms-word:ofe|u|file 以便它识别它,它总是抱怨它找不到文件)。
有谁知道使用 FileProvider 从 microsoft office for Android 中的 android 应用程序以编辑模式打开本地文件的方法?
我没有发布任何代码,因为它没有问题。任何其他应用都可以正常工作,但 Microsoft Office 应用除外。
我编写了一个通用的打开例程,然后分解出单个文件类型,如下所示。执行以下操作后我没有遇到问题。希望这会有所帮助。 (注意 - 我只添加了单词 call - 但在这里使用 SO 文章中的类型(docx、pptx 等的正确 mime 类型是什么?)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | public static Java.IO.File CopyDocuments(Java.IO.File source, string realName) { //string path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments); <-- old method string path = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).AbsolutePath; if (!System.IO.Directory.Exists(Path.Combine(path,"appname"))) System.IO.Directory.CreateDirectory(Path.Combine(path,"appname")); string dbPath = Path.Combine(path,"appname", realName); Java.IO.File destination = new Java.IO.File(dbPath); try { //if (destination.Exists()) // destination.Delete(); if (!destination.Exists()) { using (FileStream fs = new FileStream(source.AbsolutePath, FileMode.Open, FileAccess.Read)) { using (var br = new BinaryReader(fs)) { using (var bw = new BinaryWriter(new FileStream(dbPath, FileMode.Create))) { byte[] buffer = new byte[2048]; int length = 0; while ((length = br.Read(buffer, 0, buffer.Length)) > 0) { bw.Write(buffer, 0, length); } } } } } return destination; } catch (Exception ex) { Toast.MakeText(Xamarin.Forms.Forms.Context,"Error Copying:" + ex.Message, ToastLength.Long).Show(); } return null; } public void LaunchApp(string fileLocation, string realName) { var file = new Java.IO.File(fileLocation); if (!file.Exists()) return; file = CopyDocuments(file, realName); Intent intent = null; var extension = System.IO.Path.GetExtension(fileLocation).ToLower(); switch (extension) { case ContentService.DocxExtension: intent = ReturnWord(file, true); break; case ContentService.DocExtension: intent = ReturnWord(file, false); break; case ContentService.TxtExtension: case PlayerLync.Services.ContentService.RtfExtension: intent = ReturnText(file); break; case ContentService.XlsExtension: intent = ReturnExcel(file, false); break; case ContentService.XlsxExtension: intent = ReturnExcel(file, true); break; case ContentService.PPExtension: intent = ReturnPowerPoint(file, false); break; case ContentService.PPXExtension: intent = ReturnPowerPoint(file, true); break; case ContentService.Mp3Extension: //contentType = ContentType.Audio; break; default: //contentType = ContentType.Unknown; break; } try { Xamarin.Forms.Forms.Context.StartActivity(intent); } catch (Exception ex) { ... log error } } private Intent ReturnWord(Java.IO.File file, bool isEx) { var intent = new Intent(Intent.ActionView); Android.Net.Uri uri = FileProvider.GetUriForFile(Xamarin.Forms.Forms.Context,"your_package.fileprovider", file);// --> old method Android.Net.Uri.FromFile(file); // intent.AddFlags(ActivityFlags.GrantReadUriPermission); intent.AddFlags(ActivityFlags.GrantWriteUriPermission); intent.AddFlags(ActivityFlags.GrantPersistableUriPermission); intent.PutExtra(Intent.ExtraStream, uri); if (!isEx) { intent.SetDataAndType(uri,"application/vnd.msword"); } else { intent.SetDataAndType(uri,"application/vnd.openxmlformats-officedocument.wordprocessingml.document"); } return intent; } |
将这一切都放在 Android 项目中并执行自定义渲染器以从 Xamarin Forms 访问它