在使用Android的Microsoft Office移动应用程序在编辑模式下打开本地文件

问题描述:

我正在开发一个Android应用程序,我想从中启动MS Office应用程序来查看和编辑Office文件。例如,打开MS-Word移动应用程序中本地存储在设备中的docx进行编辑。在使用Android的Microsoft Office移动应用程序在编辑模式下打开本地文件

此前,我们打开的文件的URI文件的URI意图传递与例如“com.microsoft.office.word”包名称。该文件将在Word for Android中打开,用户可以编辑并保存该文件。没问题。

现在我们必须改变,以便我们使用具有读写权限的FileProvider class of Android。通过该实施,其他应用程序可以编辑文件,但Android版Microsoft Office应用程序以只读模式打开,无法更改。

这似乎是发生在其他人也一样,看到其他计算器问题的一个常见问题:

When using Android file provider, files don't have correct permissions despite FLAG_GRANT_WRITE_URI_PERMISSION being flagged in intent

Xamarin.Forms Android FileProvider: GrantWriteUriPermission not always working

我还发现这link with information about how to invoke the office apps in msdn,但它似乎很不完整,我一直无法使它与一个意图和本地文件(我只是不知道如何发送ms-word:ofe | u |文件,以便它可以识别它,它总是抱怨它无法找到该文件)。

有没有人知道一种方法来打开一个本地文件编辑模式从Android应用程序在Android的微软Office使用FileProvider?

我还没有发布任何代码,因为它没有问题。任何其他应用程序工作正常,但Microsoft Office应用程序。

我写了一个常见的打开例程,然后打破了下面的单个文件类型。做完以下事情后我没有问题。希望这有助于。 (注意 - 我只加了字通​​话 - 但是从SO文章在这里(What is a correct mime type for docx, pptx etc?

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访问窗体