2016-11-07 13 views
0

ファイルプロバイダを使用してPDFファイルを表示しようとしています。ただし、PDFリーダーを開くと、ファイルの内容は含まれません。ファイルは、ファイルフォルダ内のアプリケーションの内部ストレージに保存されます。FileProvider Xamarinにファイルが表示されない

マニフェスト:

<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をコピーして外部アプリケーションは、アプリケーションのサンドボックス内でそのファイルにアクセスすることを許可するファイルベースのUriFileProvider権限を付与することができます。

providerを追加するには、AndroidManifestapplication要素:

<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ファイルを追加するには、許可されているパスが含まれているあなたのResources/xmlにプロバイダのandroid:resource:アクセス:

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

注:xmlディレクトリをResourcesフォルダに追加する必要がある場合があります。デフォルトでは、Xamarin.Androidプロジェクトテンプレートを使用して追加されません。

あなた.pdfAssetsディレクトリに追加し、それがAndroidAssetビルドタイプとしてフラグ付けされていることを確認します(そしてそれは、小文字がxml命名されなければならない):

enter image description here

あなたはAssetのことをコピーすることができますあなたのアプリのキャッシュディレクトリは、FileProviderベースのUriを作成し、それに読み取りアクセス権を与え、それを開こうとします。あなたはそれがapplication/pdf MIMEタイプを処理することを公開する少なくとも一つのインストールされたアプリケーション必要がある。この場合:

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

これはよさそうだが、しかし、結果はPDFビューア内で、これはオープンになるの.tmpを生成しますか? – Simon

+0

@Simonは、私が使用したすべてのPDFビューアでうまく動作しますが、 'GetTempPath'を使用して、あなたの選択したファイル名を追加することができます.. i.e.'var savePath = Path.Combine(Path.GetTempPath()、pdfAssetName ); ' – SushiHangover

+0

私はちょうどそれと昨日働いた...そして、あなたの解決策は、しかし、私に同じ問題を与えてくれました。さらに見ると、権限に問題があることがわかりました。受信しているアプリが許可拒否を取得していました。 URIパーミッションを付与することでこれが解決され、私は元のコードを使用することができました。内部ストレージを使用するのは間違っていますか? – Simon

関連する問題