2017-08-04 3 views
1

Je développe une application Android à partir de laquelle je souhaite lancer des applications MS Office pour afficher et modifier des fichiers Office. Par exemple, ouvrez un fichier docx stocké localement dans l'appareil pour l'éditer dans l'application mobile MS-Word.Ouverture de fichiers locaux en mode édition avec l'application mobile Microsoft Office à l'aide d'Android

Auparavant, nous ouvrions un tel fichier avec un URI de fichier transmis dans un but avec, par ex. le nom du package "com.microsoft.office.word". Le fichier s'ouvrirait dans Word pour Android et l'utilisateur pourrait le modifier et l'enregistrer. Aucun problème.

Maintenant nous avons dû changer de sorte que nous utilisions le FileProvider class of Android avec les permissions pour lire et écrire. Avec cette implémentation, d'autres applications peuvent modifier les fichiers, mais les applications Microsoft Office pour Android sont ouvertes en mode lecture seule, sans possibilité de les modifier.

Cela semble être un problème commun qui arrive aux autres aussi, comme on le voit dans d'autres questions stackoverflow:

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

et

Xamarin.Forms Android FileProvider: GrantWriteUriPermission not always working

J'ai aussi trouvé ce link with information about how to invoke the office apps in msdn, mais il semble assez incomplet et je n'ai pas réussi à le faire fonctionner avec une intention et un fichier local (je ne sais tout simplement pas comment envoyer le ms-word: ofe | u | fichier pour qu'il le reconnaisse es, il se plaint toujours qu'il ne trouve pas le fichier).

Est-ce que quelqu'un sait un moyen d'ouvrir un fichier local en mode édition à partir d'une application Android dans Microsoft Office pour Android en utilisant FileProvider?

Je n'ai pas posté de code car ce n'est pas un problème. Toute autre application fonctionne correctement, mais les applications Microsoft Office.

Répondre

0

J'ai écrit une routine ouverte commune, puis j'ai lancé des types de fichiers individuels comme ci-dessous. Je n'ai pas eu de problèmes après avoir fait ce qui suit. Espérons que cela aide. (Note - je n'ajoute le mot appel - mais utiliser les types de l'article SO ici (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; 
} 

Placer tout cela dans le projet Android et faire un moteur de rendu personnalisé pour y accéder à partir Xamarin Forms