【问题标题】:Opening local files in edit mode with Microsoft Office mobile app using Android使用 Android 使用 Microsoft Office 移动应用程序以编辑模式打开本地文件
【发布时间】:2017-08-04 11:06:38
【问题描述】:

我正在开发一个 Android 应用程序,我想从该应用程序启动 MS Office 应用程序以查看和编辑 Office 文件。例如,打开存储在设备本地的文档,以便在 MS-Word 移动应用中进行编辑。

以前,我们打开此类文件时会使用在意图中传递的文件 URI,例如“com.microsoft.office.word”包名。该文件将在 Word for Android 中打开,用户可以对其进行编辑和保存。没问题。

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

这似乎是其他人也会遇到的常见问题,如其他 stackoverflow 问题所示:

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|file 以便识别它,它总是抱怨找不到文件)。

有谁知道使用 FileProvider 从 microsoft office for Android 中的 android 应用程序以编辑模式打开本地文件的方法?

我没有发布任何代码,因为它没有问题。任何其他应用都可以正常工作,但 Microsoft Office 应用除外。

【问题讨论】:

    标签: android android-intent ms-office android-fileprovider


    【解决方案1】:

    我编写了一个通用的打开例程,然后分解出单个文件类型,如下所示。执行以下操作后我没有遇到问题。希望这会有所帮助。 (注意 - 我只添加了单词 call - 但在这里使用 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 Forms 访问它

    【讨论】:

      猜你喜欢
      • 2011-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多