2016-11-07 62 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「不會將其本身表現爲a 文件系統。

您可以將AndroidAsset複製到您的應用程序緩存目錄,然後授予FileProvider權限基於文件的Uri以允許外部應用程序訪問你的應用程序的沙箱範圍內的文件。

添加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文件提供者的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,小寫)

添加您.pdfAssets目錄,並確保它被標記爲AndroidAsset構建類型:

enter image description here

現在,您可以複製Asset到您的應用的緩存目錄,創建一個基於FileProviderUri,授予對其的讀取訪問權限,並嘗試將其打開。在這種情況下,你需要一個發佈,它處理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

這看起來不錯,但其結果產生的.tmp將一個PDF瀏覽器中這種開放? – Simon

+0

@Simon對我使用過的所有PDF查看器都很好,但是您可以使用'GetTempPath'並添加您選擇的文件名.. i..e.'var savePath = Path.Combine(Path.GetTempPath(),pdfAssetName );' – SushiHangover

+0

我昨天就和它一起工作......而且你的解決方案很好,但是仍然給我帶來了同樣的問題。進一步看,我發現有一個權限問題。接收應用程序正在獲得權限拒絕。通過授予URI許可,這解決了它,我可以使用我的原始代碼..我使用內部存儲如果它的工作是錯誤的嗎? – Simon