2016-11-07 7 views
0

Я пытаюсь показать файл PDF с помощью поставщика файлов. Однако, когда открывается программа чтения PDF, она не содержит содержимого файла. Файл хранится во внутренней папке приложения в папке с файлами.FileProvider Xamarin не отображает файл

Manifest:

<provider android:name="android.support.v4.content.FileProvider" android:authorities="com.mycom.myapp.fileprovider" android:exported="false" android:grantUriPermissions="true"> 
     <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> 
    </provider> 

File_paths:

<paths xmlns:android="http://schemas.android.com/apk/res/android"> 
    <files-path name="export" /> 
</paths> 

pdfViewRenderer.cs:

string libraryPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); 
var path = Path.Combine(libraryPath, fileName); 


string application = "application/pdf"; 
Java.IO.File javaFile = new Java.IO.File(fileName);//externalPath 


Android.Net.Uri androidURI = FileProvider.GetUriForFile(Forms.Context.ApplicationContext, "com.mycom.myapp.fileprovider", javaFile); 


Intent intent = new Intent(Intent.ActionView); 
intent.SetDataAndType(androidURI, Filetype); 
intent.AddFlags(ActivityFlags.GrantReadUriPermission); 
intent.SetFlags(ActivityFlags.NoHistory); 
intent.SetFlags(ActivityFlags.ClearWhenTaskReset); 


Forms.Context.StartActivity(Intent.CreateChooser(intent, "Open PDF")); 

ответ

0

Вы не можете непосредственно доступа файл внутри приложения .apk, то `. apk 'не представляет собой файловая система.

Вы можете скопировать AndroidAsset в каталог кэша приложений, а затем предоставить FileProvider разрешения на основе файлы Uri разрешенных внешние приложений доступа к этому файлу в песочнице вашего приложения.

Добавить provider в ваших AndroidManifest «ы application элемент:

<provider 
android:name="android.support.v4.content.FileProvider" 
android:authorities="com.sushihangover.artificialgravitycalc" 
android:exported="false" 
android:grantUriPermissions="true"> 
<meta-data 
    android:name="android.support.FILE_PROVIDER_PATHS" 
    android:resource="@xml/cache_path" /> 

Затем добавьте файл XML, чье имя файла совпадает с провайдера android:resource: к вашему Resources/xml, который содержит путь, который вы предоставляете доступ к:

<paths xmlns:android="http://schemas.android.com/apk/res/android"> 
    <cache-path name="appcache" path="." /> 
</paths> 

Примечание: вам может потребоваться добавить каталог xml в папку Resources, так как по умолчанию он не добавляется через базовый шаблон проекта Xamarin.Android. (И он должен быть назван xml, в нижнем регистре)

Добавить свой .pdf в каталог Assets и убедитесь, что он помечен как тип в AndroidAsset сборки:

enter image description here

Теперь вы можете скопировать этот Asset в каталог вашего кеша приложения, создайте FileProvider на основе Uri, предоставите доступ к нему для чтения и попытайтесь открыть его. В этом случае вам нужно по крайней мере одно установленное приложение, которое публикует, что он обрабатывает application/pdf мим-тип:

var pdfAssetName = "PlayScriptLanguageSpecification.pdf"; 
var savePath = Path.GetTempFileName(); 
using (var assetStream = Application.Context.Assets.Open(pdfAssetName)) 
using (var fileStream = new FileStream(savePath, FileMode.Create, FileAccess.Write)) 
{ 
    byte[] buffer = new byte[1024]; 
    int readCount = 0; 
    do 
    { 
     readCount = assetStream.Read(buffer, 0, buffer.Length); 
     fileStream.Write(buffer, 0, readCount); 
    } while (readCount > 0); 
} 
var targetIntent = new Intent(Intent.ActionView); 
var file = new Java.IO.File(savePath); 
var uri = FileProvider.GetUriForFile(this, PackageName, file); 
targetIntent.SetDataAndType(uri, "application/pdf"); 
targetIntent.SetFlags(ActivityFlags.NoHistory); 
targetIntent.SetFlags(ActivityFlags.GrantReadUriPermission); 
Intent intent = Intent.CreateChooser(targetIntent, "Open File"); 
StartActivity(intent); 
+0

Это выглядит хорошо, однако результат дает .tmp это будет открыт в программе просмотра PDF? – Simon

+0

@Simon Работает отлично для всех зрителей PDF, которые я использовал, но вы можете использовать 'GetTempPath' и добавлять имя файла по вашему выбору .. i..e.var savePath = Path.Combine (Path.GetTempPath(), pdfAssetName); ' – SushiHangover

+0

Я только вчера работал с ним ... И ваше решение хорошо, но все же дало мне ту же проблему. В дальнейшем я обнаружил, что в разрешениях есть проблема. Получающее приложение получало отказ от разрешения. Предоставляя разрешение URI, это разрешило его, и я мог использовать свой оригинальный код. Неправильно ли использовать внутреннее хранилище, если оно работает? – Simon

Смежные вопросы