2017-04-04 1 views
0

Ich begann an einem anderen Thema, das mich hierher führte, so krank nur von Anfang an beginnen. Ich habe eine App, die es dem Benutzer ermöglicht, Angebote für seine Kunden zu erstellen. Die App erstellt ein PDF für das Angebot und speichert es speziell im externen Speicher, damit andere Apps darauf zugreifen können. Kürzlich scheint es, dass ich die pdf in bestimmten apps nicht sehen kann, wenn sie von meiner App aus geöffnet werden (Google PDF Viewer, Google Drive Viewer zeigt einen leeren Bildschirm, während Adobe Acrobat völlig in Ordnung ist). Ich weiß, dass das pdf gut ist, weil ich es von einem Dateimanager ohne irgendwelche Probleme ansehen kann. Es ist nur beim Öffnen von meiner App, dass es nicht funktioniert.Probleme mit FileProvider

Ich war eine Absicht mit dem uri ähnlich wie content://path/to/external/storage/MyApp/customerName/quote.pdf Bereitstellung

Ich benutzen es als file://... zur Verfügung zu stellen, sondern lief in die exponierte uri Ausnahme in sdk 24 eingeführt, so dass ich einfach Datei umbenannt: // Zum Inhalt:// Und alles schien zu funktionieren, bis ich von den Google PDF-Viewer-Apps erfuhr.

Nun gehe ich davon aus, dass es etwas mit der FileProvider-Klasse zu tun hat, die ich anscheinend hätte verwenden sollen. Aber ich kann nicht scheinen es funktioniert überhaupt nicht und keine der anderen Fragen, die ich in Bezug auf das Problem gefunden habe, scheint zu funktionieren, also hier ist, was ich im Moment habe:

file_paths.xml (war ein paar verschiedene Wege Es scheint, dass es mehrere Kundenordner gibt, die vom Benutzer erstellt wurden, ich kann sie nicht in der XML-Datei angeben, da ich nicht weiß, wie sie benannt werden sollen, aber zum Testen habe ich einen da hineingeschickt, nur um zu sehen, ob das war das Problem und es immer noch nicht funktioniert)

<?xml version="1.0" encoding="utf-8"?> 
<paths> 
    <external-path name="external_files" path="." /> 
    <external-path name="myApp" path="MyApp/" /> 
    <external-path name="myAppa" path="MyApp/customerFolder/" /> 
    <external-path name="myAppb" path="/" /> 
</paths> 

Manifest-Datei (es gibt eine Datei Anbieter von einer der enthält verwendet, weshalb ich die Werkzeuge haben: ersetzen Linien drin, ich weiß nicht, ob dies verursacht ein Problem oder nicht, es ist zu speichern Fotos in dem gleichen Verzeichnis im Versuch, die PDF-Dateien aus)

<provider 
     android:name="android.support.v4.content.FileProvider" 
     android:authorities="${applicationId}.provider" 
     android:exported="false" 
     android:grantUriPermissions="true" 
     tools:replace="authorities" 
     > 
     <meta-data 
      android:name="android.support.FILE_PROVIDER_PATHS" 
      android:resource="@xml/file_paths" 
      tools:replace="android:resource"/> 
    </provider> 

Und um die Seite anzuzeigen, die die Absicht startet das pdf zu lesen:

String url = "file:///storage/emulated/0/MyApp/customerFolder/quote.pdf"; 
File mFile = new File(url); 
Uri pdfURI = FileProvider.getUriForFile(activity, activity.getApplicationContext().getPackageName() + ".provider", mFile); 

Intent intent = new Intent(android.content.Intent.ACTION_VIEW); 
      intent.setData(pdfURI); 
      intent.setType("application/pdf"); 
      intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);       
activity.startActivity(intent); 

dies mir folgende Fehler wurde zu geben java.lang.IllegalArgumentException: Failed to find configured root that contains /file:/storage/emulated/0/MyApp/customerFolder/quote.pdf in der Zeile, die FileProvider.getUriForFile() Methode enthält. Ich habe den Pfad überprüft und es ist korrekt,

Alternativ, das ist der Code, den ich hatte, funktioniert es für Adobe Acrobat, aber nicht Google PDF-Viewer oder Google Drive Viewer. Wenn es eine Möglichkeit, diese zu fixieren, dass ich fehle, dann kann ich über die fileProvider vergessen:

String url = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ? "content://" : "file://") + "/storage/emulated/0/MyApp/customerFolder/quote.pdf"; 
Intent intent = new Intent(android.content.Intent.ACTION_VIEW); 
intent.setDataAndType(Uri.parse(url),"application/pdf"); 
activity.startActivity(intent); 

Antwort

1

i einfach Datei umbenannt: // Zum Inhalt: // und alles schien zu funktionieren, bis ich gefunden über die Google PDF-Viewer-Apps.

Das sollte auf Null-Geräten funktionieren. Wahrscheinlich versucht Adobe, fehlerhafte Eingaben so zu korrigieren.

String url = "file:///storage/emulated/0/MyApp/customerFolder/quote.pdf"; 
File mFile = new File(url); 

file:///storage/emulated/0/MyApp/customerFolder/quote.pdf ist kein Dateisystempfad. Das ist eine URL. Verwenden Sie für Ihre Experimente /storage/emulated/0/MyApp/customerFolder/quote.pdf. Und, schließlich, codieren Sie keine Pfade.

Das Element <external-path name="myApp" path="MyApp/" /> würde diesen bestimmten Dateisystempfad abdecken.

+0

Ich schrieb die URL einfach, damit ich sehen konnte, was der tatsächliche Pfad ist, verwende ich 'Environment.getExternalStorageDirectory()' normalerweise. Aber nachdem ich 'file: //' entfernt habe und einfach '/ storage/emulated/...' benutzt habe, scheint mir ein Schritt näher zu sein, da es eine URL von 'content: //com.com.MyApp.provider/myApp/ customerFolder/quote.pdf', aber keiner der PDF-Viewer öffnet es, sie geben Fehler wie "keine Datei empfangen" oder können Dateien nicht öffnen. – JStephen

+0

Die Datei ist dort und die Verwendung des Pfads external_files ergab eine andere URL, aber das gleiche Ergebnis. Ich habe das Gefühl, dass dies ähnlich ist wie vorher. Die PDF-Anwendungen geben mir jetzt zumindest Fehler, aber Adobe funktioniert überhaupt nicht. – JStephen

+0

@JStephen: Das ist seltsam. Normalerweise würde ich dieses Verhalten erwarten, wenn Sie 'FLAG_GRANT_READ_URI_PERMISSION' verpasst haben, aber Sie haben es. [Diese Beispiel-App von mir] (https://github.com/commonsguy/cw-omnibus/tree/master/ContentProvider/V4FileProvider) funktioniert, obwohl ich eine Korrektur einfüge, um die 'FileProvider'-Kompatibilität mit schlecht geschriebenen Client-Apps zu verbessern . – CommonsWare

0

Ended herauszufinden, es. Basierend auf der Beispiel-App von CommonsWare funktionierte ich, indem ich die Datei in den internen Speicher kopierte und diese interne Speicher-URL verwendete, aber sie funktionierte immer noch nicht mit der externen Speicher-URL derselben Datei. Das führte mich zu this answer here, wo offenbar setType() den Datensatz von setData() löschen wird. Doch das ist nicht der Fall war, als die interne URL, aber ich versuchte es trotzdem, änderte sich diese

Intent intent = new Intent(android.content.Intent.ACTION_VIEW); 
intent.setData(pdfURI); 
intent.setType("application/pdf"); 

dieser

Intent intent = new Intent(android.content.Intent.ACTION_VIEW); 
intent.setDataAndType(pdfURI,"application/pdf"); 

und plötzlich war es mit der externen URL als auch. Eine sehr frustrierende Inkonsistenz, besonders in meinem Fall, da ich ursprünglich Recht hatte, aber es in zwei Methoden aufteilte, die meinten, wenn einer von ihnen schief gelaufen wäre, würde ich es durch die Zeilennummer wissen.

blieb Mein Manifest der gleichen, aber ich reduzierte meine Pfade gerade diese

<paths> 
    <external-path name="external_files" /> 
</paths> 

hoffentlich hilft jemand andere Datei.

Verwandte Themen