Hier ist, wie ich meine Aktivität in meiner AndroidManifest.xml definiert habe, damit dies funktioniert.
<activity android:name="com.keepassdroid.PasswordActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="file" />
<data android:mimeType="*/*" />
<data android:pathPattern=".*\\.kdb" />
<data android:host="*" />
</intent-filter>
</activity>
Das scheme
von file
gibt an, dass dies passieren soll, wenn eine lokale Datei geöffnet wird (anstelle eines Protokolls wie HTTP).
mimeType
kann so eingestellt werden, dass sie \*/\*
zu jedem MIME-Typ passt.
pathPattern
Hier geben Sie an, mit welcher Erweiterung Sie übereinstimmen möchten (in diesem Beispiel .kdb
). Das .*
am Anfang entspricht einer beliebigen Anzahl von Zeichen. Diese Zeichenfolgen müssen doppelt maskiert werden, entsprechen also \\\\.
einer wörtlichen Periode. Dann beenden Sie mit Ihrer Dateierweiterung. Eine Einschränkung bei pathPattern ist, dass .*
es sich nicht um eine gierige Übereinstimmung handelt, wie Sie es erwarten würden, wenn dies ein regulärer Ausdruck wäre. Dieses Muster stimmt nicht mit Pfaden überein, die ein .
vor dem enthalten .kdb
. Eine ausführlichere Beschreibung dieses Problems und eine Problemumgehung finden Sie hier
Gemäß der Android-Dokumentation sind schließlich sowohl host
als auch scheme
Attribute erforderlich, damit das pathPattern
Attribut funktioniert. Setzen Sie dies also einfach auf den Platzhalter, damit alles übereinstimmt.
Wenn Sie nun eine .kdb
Datei in einer App wie Linda File Manager auswählen , wird meine App als Option angezeigt. Ich sollte beachten, dass dies allein nicht das Herunterladen dieses Dateityps in einem Browser ermöglicht, da dies nur beim Dateischema registriert wird. Wenn Sie eine App wie Linda File Manager auf Ihrem Telefon haben, können Sie jeden Dateityp generisch herunterladen.
.kdbx
Erweiterung zu binden , damit der ES-Datei-Explorer kdbx-Dateien öffnen kann, als ich auf diesen Beitrag verwiesen wurde. Anscheinend funktioniert dieser Absichtsfilter nicht, wenn die Absicht einen leeren MIME-Typ hat !! Es ist auch möglich, eine Absicht mit einer LEEREN Zeichenfolge als Aktion und nur einer URI zu haben. Google Text & Tabellen hat auf diese Absicht reagiert, daher muss sie gültig sein.<data>
Tag mit vier Attributen verwenden. 4 Tags zu haben ist logisch ODER - was mit Android 2 funktioniert hat - aber Android 4 ist strenger. Siehe stackoverflow.com/questions/20650378/…\\\\.
eine Literalperiode übereinstimmt, warum verwenden Sie sie nicht, um eine.kdb
Erweiterung wie diese zu bilden :\\\\.kdb
?Es gibt viele Fehlinformationen zu diesem Thema, nicht zuletzt aus Googles eigener Dokumentation. Die beste und angesichts der seltsamen Logik möglicherweise einzige Quelldokumentation ist der Quellcode.
Die Absichtsfilterimplementierung hat eine Logik, die sich fast jeder Beschreibung entzieht. Der Parser-Code ist das andere relevante Puzzleteil.
Die folgenden Filter kommen einem vernünftigen Verhalten ziemlich nahe. Die Pfadmuster gelten für "Datei" -Schemaabsichten.
Die globale Übereinstimmung des MIME-Typmusters stimmt mit allen Typen überein, solange die Dateierweiterung übereinstimmt. Dies ist nicht perfekt, aber die einzige Möglichkeit, das Verhalten von Dateimanagern wie ES File Explorer anzupassen, und es ist auf Absichten beschränkt, bei denen die URI / Dateierweiterung übereinstimmt.
Ich habe hier keine anderen Schemata wie "http" aufgenommen, aber sie werden wahrscheinlich bei all diesen Filtern gut funktionieren.
Das ungerade Schema ist "Inhalt", für den die Erweiterung dem Filter nicht zur Verfügung steht. Solange der Anbieter Ihren MIME-Typ angibt (z. B. gibt Google Mail den MIME-Typ für den Anhang ungehindert weiter), stimmt der Filter überein.
Zu beachtende Fallstricke:
In diesem Sinne hier ein Beispiel mit Kommentaren:
quelle
<data android:mimeType="*/*" />
in allen drei Optionen ändern und es funktionierte wie ein Zauber für alle Apps, einschließlich Google Drive und Google Mail.Ich muss zugeben, dass die einfache Aufgabe, Anhänge aus E-Mails und Dateien aus dem Dateisystem auf Android zu öffnen, eine der verrücktesten Erfahrungen war, die es je gab. Es ist einfach, mit zu vielen oder zu wenigen Dateien umzugehen. Aber es ist schwer, es genau richtig zu machen. Die meisten auf stackoverflow veröffentlichten Lösungen funktionierten bei mir nicht richtig.
Meine Anforderungen waren:
Der wahrscheinlich beste Weg, um diese Aufgabe zu erledigen, besteht darin, einen benutzerdefinierten MIME-Typ für Ihre Anhänge anzugeben. Und Sie werden sich wahrscheinlich auch für eine benutzerdefinierte Dateierweiterung entscheiden. Nehmen wir also an, unsere App heißt "Cool App" und wir generieren Dateianhänge mit ".cool" am Ende.
Dies ist der Punkt, an dem ich meinem Ziel am nächsten gekommen bin und der funktioniert ... zufriedenstellend.
Anmerkungen:
pathPattern
scheint für Anhänge (bei Verwendungandroid:scheme="content"
) mehr oder weniger ignoriert zu werden . Wenn jemand das pathPattern dazu bringt, nur auf bestimmte Muster zu reagieren, würde ich mich freuen zu sehen, wie.android:host="*"
Attribut hinzugefügt habe .intent-filter
Blöcke zusammengeführt werden, aber ich habe dies nicht überprüft.android:scheme="http"
kann die verwendet werden. Beachten Sie, dass bestimmte Browser dasandroid:mimeType
Experimentieren durcheinander bringenandroid:mimeType="*/*"
und im Debugger überprüfen können, was tatsächlich durchlaufen wird, und dann die Filterung verschärfen, um nicht die nervige App zu werden, die alles handhabt .intent-filter
wurde mit der Samsung-App "My Files" auf einem Galaxy S3 getestet. Der FX Explorer weigert sich immer noch, die Datei ordnungsgemäß zu öffnen, und ich habe auch festgestellt, dass das App-Symbol nicht für die Dateien verwendet wird. Wenn jemand das zum Laufen bringt, kommentieren Sie bitte unten.Ich hoffe, Sie finden dies nützlich und müssen keine Tage damit verschwenden, alle möglichen Kombinationen durchzugehen. Es gibt Raum für Verbesserungen, daher sind Kommentare willkommen.
quelle
android:label
für den Intent-Filter verwendet wird, ist die Zeichenfolge, die der Benutzer im Auswahlmenü sieht. Standardmäßig wird der Anwendungsname verwendet.Brians Antwort hat mich zu 90% dorthin gebracht. Zum Abschluss habe ich für MIME-Typ verwendet
Ich vermute, dass frühere Poster versucht haben, das gleiche Detail zu veröffentlichen, aber wenn der Stern-Schrägstrich-Stern nicht als Code angegeben wird, wird er durch den Stapelüberlauf nur als Schrägstrich dargestellt.
quelle
Anstatt
android:path
, versuchen Sieandroid:mimeType
, mit einem Wert des MIME - Typ dieser bestimmten Inhalt. Auchandroid:path
akzeptiert keine Platzhalter - Verwendungandroid:pathPattern
dafür.quelle
Ich habe seit Ewigkeiten versucht, dies zum Laufen zu bringen, habe im Grunde alle vorgeschlagenen Lösungen ausprobiert und kann Android immer noch nicht dazu bringen, bestimmte Dateierweiterungen zu erkennen. Ich habe einen Intent-Filter mit einem
"*/*"
Mimetyp, der das einzige ist, was zu funktionieren scheint, und Dateibrowser listen meine App jetzt als Option zum Öffnen von Dateien auf. Meine App wird jetzt jedoch als Option zum Öffnen einer beliebigen Art von Datei angezeigt, obwohl Ich habe mithilfe des pathPattern-Tags bestimmte Dateierweiterungen angegeben. Dies geht so weit, dass Android mich fragt, ob ich meine App zum Anzeigen des Kontakts verwenden möchte, selbst wenn ich versuche, einen Kontakt in meiner Kontaktliste anzuzeigen / zu bearbeiten. Dies ist nur eine von vielen Situationen, in denen dies auftritt, SEHR SEHR ärgerlich.Schließlich fand ich diesen Google-Gruppenbeitrag mit einer ähnlichen Frage, auf die ein tatsächlicher Android-Framework-Ingenieur antwortete. Sie erklärt, dass Android einfach nichts über Dateierweiterungen weiß, sondern nur MIME-Typen ( https://groups.google.com/forum/#!topic/android-developers/a7qsSl3vQq0 ).
Nach dem, was ich gesehen, ausprobiert und gelesen habe, kann Android einfach nicht zwischen Dateierweiterungen unterscheiden, und das pathPattern-Tag ist im Grunde eine gigantische Zeit- und Energieverschwendung. Wenn Sie das Glück haben, nur Dateien eines bestimmten MIME-Typs (z. B. Text, Video oder Audio) zu benötigen, können Sie einen Intent-Filter mit einem MIME-Typ verwenden. Wenn Sie jedoch eine bestimmte Dateierweiterung oder einen MIME-Typ benötigen, den Android nicht kennt, haben Sie kein Glück.
Wenn ich mich in irgendetwas irre, sag es mir bitte. Bisher habe ich jeden Beitrag gelesen und jede vorgeschlagene Lösung ausprobiert, die ich finden konnte, aber keine hat funktioniert.
Ich könnte noch ein oder zwei Seiten darüber schreiben, wie häufig solche Dinge in Android zu sein scheinen und wie durcheinander die Entwicklererfahrung ist, aber ich werde Ihnen meine wütenden Beschimpfungen ersparen;). Hoffe, ich habe jemandem Ärger erspart.
quelle
Brians Antwort ist sehr nah, aber hier ist eine saubere und fehlerfreie Möglichkeit, Ihre App aufzurufen, wenn Sie versuchen, eine Datei mit Ihrer eigenen benutzerdefinierten Erweiterung zu öffnen (kein Schema oder Host erforderlich):
quelle
<data>
Tag mit vier Attributen verwenden. Ihre Lösung funktioniert möglicherweise mit Android 2 - aber die Regeln sind strenger geworden: stackoverflow.com/questions/20650378/…host
undscheme
sind erforderlich!Unter Android 4 wurden die Regeln strenger als früher. Verwenden:
quelle
Ich habe selbst ziemlich viel damit zu kämpfen, um eine benutzerdefinierte Dateierweiterung zu erhalten. Nach langem Suchen habe ich diese Webseite gefunden, auf der das Poster feststellte, dass die patternMatcher-Klasse von Android (die für den pathPattern-Abgleich in Absichtsfiltern verwendet wird) ein unerwartetes Verhalten aufweist, wenn Ihr Pfad das erste Zeichen Ihres Übereinstimmungsmusters an einer anderen Stelle im Pfad enthält (Wenn Sie beispielsweise versuchen, mit "* .xyz" übereinzustimmen, wird die patternMatcher-Klasse gestoppt, wenn sich früher in Ihrem Pfad ein "x" befindet.) Folgendes hat er für eine Problemumgehung gefunden und für mich gearbeitet, obwohl es ein bisschen hackt:
quelle
Keine der oben genannten Funktionen funktioniert ordnungsgemäß für VIEW- oder SEND-Aktionen, wenn das Suffix nicht mit einem MIME-Typ in der system = wide MIME-Datenbank von Android registriert ist. Die einzigen Einstellungen, die ich gefunden habe, sind das Auslösen für das angegebene Suffix
android:mimeType="*/*"
, aber dann wird die Aktion für ALLE Dateien ausgelöst. Ganz klar NICHT was du willst!Ich kann keine richtige Lösung finden, ohne die MIME und das Suffix zur Android-MIME-Datenbank hinzuzufügen. Bisher habe ich keinen Weg gefunden, dies zu tun. Wenn jemand weiß, wäre ein Zeiger großartig.
quelle
Wenn eine Absicht a erfüllt
intent-filter
, sind dies dieintent-filter
Anforderungen: (Stellen Sie sich eine Checkliste vor).<action>
<category>
<data mimeType>
(einfache Lösung: " / ")Optional:
Jede passende
<data scheme>
(einfache Lösung:<data android:scheme="file" /> <data android:scheme="content" />
)Beliebige Übereinstimmungen
<data host>
(einfache Lösung: "*")<data pathPattern/etc.>
(zum Beispiel.*\\.0cc
)Durch das Definieren mehrerer
<data $type="">
Elemente wird das Kontrollkästchen $ type aktiviert, wenn eines mit dem<data $type=>
übereinstimmtIntent
.Das Weglassen von mimeType unterbricht Ihre
intent-filter
, obwohl es scheinbar überflüssig ist. Durch das Weglassen stimmt<data scheme/host/pathPattern>
Ihr Filter mit allem überein.https://f-droid.org/en/packages/de.k3b.android.intentintercept/ ist eine App, die alle Absichten empfängt und es Ihnen ermöglicht, die Absicht zu überprüfen. Ich habe erfahren, dass nicht erkannte Dateierweiterungen, die über den Simple File Manager geöffnet wurden, vom Typ MIME geliefert werden
application/octet-stream
.https://stackoverflow.com/a/4621284/2683842 meldet, dass der
<data pathPattern=>
.*xyz
Vorgang beim ersten Mal abgebrochenx
wird und sofort fehlschlägt, wenn nicht gefolgt wirdyz
. So/sdcard/.hidden/foo.0cc
wird nicht passieren ,.*\\.0cc
wenn Sie versuchen ,.*\\..*\\.0cc
statt.Endresultat:
quelle
Wenn Sie möchten, dass die Dateien direkt über Google Mail, Dropbox oder eines der integrierten Android-Datei-Tools geöffnet werden, verwenden Sie den folgenden Code (löschen Sie 'android: host = "*"', wodurch die Datei für Google Mail nicht erreichbar war):
Der Datenfilter muss gemäß Android Version 4.x in einer Anweisung geschrieben sein
quelle
Verwenden Sie den Filter wie folgt, um ihn über Browser, Google Mail und den Dateibrowser zu öffnen (getestet). HINWEIS: Bitte führen Sie nicht zwei Filter zusammen, damit der Browser Ihre App ignoriert (getestet).
quelle
Update 2020
Android hat sich in Richtung Inhalts-URIs und MIME-Typen für Absichtsfilter bewegt.
Das Problem
Eine Inhalts-URI muss nicht unbedingt die Erweiterung oder den Namen der Datei enthalten und unterscheidet sich zwischen verschiedenen Anwendungen, die den Inhalt / die Datei bereitstellen.
Hier einige Beispiele für Inhalts-URIs aus verschiedenen E-Mail-Anwendungen für denselben E-Mail-Anhang:
Google Mail ->
content://com.google.android.gm.sapi/[email protected]/message_attachment_external/%23thread-a%3Ar332738858767305663/%23msg-a%3Ar-5439466788231005876/0.1?account_type=com.google&mimeType=application%2Foctet-stream&rendition=1
Ausblick ->
content://com.microsoft.office.outlook.fileprovider/outlookfile/data/data/com.microsoft.office.outlook/cache/file-download/file--2146063402/filename.customextention
Samsung Email App ->
content://com.samsung.android.email.attachmentprovider/1/1/RAW
Wie Sie sehen können, sind sie alle unterschiedlich und enthalten garantiert nichts, was mit Ihrer tatsächlichen Datei zusammenhängt. Daher können Sie nicht das verwenden, was die
android:pathPattern
meisten vorgeschlagen haben.Eine Workaround-Lösung für E-Mail-Anhänge
Durch Tests habe ich die von Google Mail, Outlook und Samsung Email verwendeten MIME-Typen gefunden und diese meinem Intent-Filter hinzugefügt.
Vorsichtsmaßnahmen / Fallstricke
Ich habe festgestellt, dass mit meiner obigen Lösung beim Öffnen einer Binärdatei automatisch meine App gestartet wird. Ich habe dies in meiner Aktivität behandelt, indem ich einen fehlgeschlagenen Status angezeigt habe, wenn wir die Datei nicht analysieren konnten. Ich dachte, dies sei ein ziemlich seltenes Ereignis, also wäre es akzeptabel.
Ich konnte keine Möglichkeit finden, meine App über den Dateibrowser zu starten, ohne
<data android:mimeType="*/*"/>
meinen Intent-Filter zu erweitern. Ich konnte dies nicht verwenden, da meine App dann immer dann gestartet wurde, wenn der Benutzer auf eine Datei auf seinem Telefon klickte (nicht nur auf die Dateien mit der benutzerdefinierten Dateierweiterung). Ich würde nicht empfehlen, dies Ihrem Intent-Filter hinzuzufügen.Abschließende Gedanken
quelle