Filtr intencji Androida dla określonego rozszerzenia pliku?

93

Chcę móc pobrać plik z określonym rozszerzeniem z sieci i przekazać go do mojej aplikacji, aby sobie z tym poradzić, ale nie byłem w stanie określić filtru intencji. Typ pliku nie jest uwzględniony w typach MIME i próbowałem użyć

<data android:path="*.ext" />

ale nie mogłem zmusić tego do pracy.

Wredny
źródło

Odpowiedzi:

120

Oto jak zdefiniowałem swoją aktywność w moim AndroidManifest.xml, aby to zadziałało.

<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>

Symbol schemeof filewskazuje, że powinno to nastąpić po otwarciu pliku lokalnego (zamiast protokołu takiego jak HTTP).

mimeTypemożna ustawić, */*aby dopasować dowolny typ MIME.

pathPatternto miejsce, w którym określasz, które rozszerzenie chcesz dopasować (w tym przykładzie .kdb). Na .*początku odpowiada dowolnemu składowi znaków. Te ciągi wymagają podwójnego znaku ucieczki, więc \\\\.dopasowuje dosłowny okres. Następnie kończysz z rozszerzeniem pliku. Jedynym zastrzeżeniem dotyczącym pathPattern jest to, że .*nie jest to zachłanne dopasowanie, jakiego można by się spodziewać, gdyby było to wyrażenie regularne. Ten wzorzec nie będzie pasował do ścieżek zawierających .przed rozszerzeniem .kdb. Bardziej szczegółowe omówienie tego problemu i obejścia można znaleźć tutaj

Wreszcie, zgodnie z dokumentacją Android, jak hosti schemeatrybuty są wymagane dla pathPatternatrybutu do pracy, więc po prostu ustawić, że do zamiennika pasujące do niczego.

Teraz, jeśli wybierzesz .kdbplik w aplikacji takiej jak Linda File Manager, moja aplikacja pojawi się jako opcja. Powinienem zauważyć, że samo to nie pozwala na pobranie tego typu pliku w przeglądarce, ponieważ rejestruje się to tylko w schemacie pliku. Posiadanie aplikacji, takiej jak Linda File Manager w telefonie, generalnie opiera się, umożliwiając pobieranie dowolnego typu plików.

Brian Pellin
źródło
3
To nie działa tutaj. Najpierw z mimeType = " ", pakiet nie jest instalowany w systemie Android 2.1, pojawia się wyjątek MalformedMimeTypeException. Użycie „* / ” rozwiązuje ten problem, ale wtedy ten filtr nie działa. Obecnie testuję z przeglądarką Skyfire, która nie zachowuje pobierania typu MIME, tak jak robi to standardowa przeglądarka Androida. Po kliknięciu pliku na liście pobrań Skyfire, wraz z danymi pliku nadawany jest uproszczony cel WIDOKU. A ten filtr intencji nie pasuje.
olivierg
@Brian Pellin: Właściwie szukałem sposobu na powiązanie typu MIME z .kdbxrozszerzeniem, aby umożliwić eksploratorowi plików ES otwieranie plików kdbx, kiedy wskazano mi ten post. Najwyraźniej jeśli intencja ma pusty typ MIME, ten filtr intencji nie zadziała !! Możliwe jest również posiadanie intencji z EMPTY jako akcją i tylko identyfikatorem URI. Dokumenty Google odpowiedziały na ten zamiar, więc musi być ważny.
billc.cn,
2
Żeby było jasne, mimeType powinno mieć wartość „* / *”. Myślę, że niektórzy ludzie zapomnieli uciec przed * s
Brian Pellin,
1
To nie zadziała z Androidem 4. Powinieneś użyć <data>tagu z czterema atrybutami. Posiadanie 4 tagów jest logiczne LUB - które działało z Androidem 2 - ale Android 4 jest bardziej rygorystyczny. Zobacz stackoverflow.com/questions/20650378/…
Martin
3
jeśli \\\\.meczów okres dosłowne, dlaczego nie użyć go tworzą .kdbprzedłużenie takiego: \\\\.kdb?
Lealo,
37

Istnieje wiele błędnych informacji na ten temat, nie tylko z własnej dokumentacji Google. Najlepszą i biorąc pod uwagę dziwną logikę, prawdopodobnie jedyną prawdziwą dokumentacją jest kod źródłowy.

Zamiarem wdrożenia filtr ma logiki, że prawie przeciwstawia opis. Kod parser jest inny istotny element układanki.

Następujące filtry są bardzo zbliżone do rozsądnego zachowania. Wzory ścieżek mają zastosowanie do "file"intencji schematu.

Globalne dopasowanie wzorca typu MIME będzie pasować do wszystkich typów, o ile będzie zgodne rozszerzenie pliku. Nie jest to idealne, ale jest to jedyny sposób na dopasowanie zachowania menedżerów plików, takich jak ES File Explorer, i jest ograniczone do intencji, w których pasuje identyfikator URI / rozszerzenie pliku.

Nie zamieściłem innych schematów, takich jak "http"tutaj, ale prawdopodobnie będą działać dobrze na wszystkich tych filtrach.

Dziwny schemat jest taki "content", dla którego rozszerzenie nie jest dostępne dla filtra. Ale dopóki dostawca podaje typ MIME (np. Gmail bez przeszkód przekaże typ MIME dla załącznika), filtr będzie pasował.

Problemy, o których należy pamiętać:

  1. Należy mieć świadomość, że w filtrach nic nie zachowuje się konsekwentnie, to labirynt przypadków specjalnych, a naruszenie zasady najmniejszego zaskoczenia traktuje jako cel projektowy. Żaden z algorytmów dopasowywania wzorców nie ma takiej samej składni ani zachowania. Brak pola czasami jest symbolem wieloznacznym, a czasami nie. Atrybuty w elemencie danych czasami muszą iść razem, a czasami ignorować grupowanie. Naprawdę można było zrobić lepiej.
  2. schemeORAZ hostmusi być określona dla pathzasady, aby dopasować (w przeciwieństwie do przewodnika API Google, obecnie).
  3. Przynajmniej ES File Explorer generuje intencje z typem MIME "", który jest filtrowany bardzo inaczej null, nie można go jednoznacznie dopasować i może być dopasowany tylko przez ryzykowny "*/*"filtr.
  4. "*/*"Filtra nie będzie pasował z intencjami nulltypu MIME - że wymaga osobnego filtr dla tego konkretnego przypadku, bez typu MIME w ogóle.
  5. "content"Schemat można dopasować tylko według typu MIME, ponieważ oryginalna nazwa pliku nie jest dostępny w intencji (przynajmniej w Gmailu).
  6. Grupowanie atrybutów w oddzielne "data"elementy jest (prawie) nieistotne dla interpretacji, z szczególnym wyjątkiem hosti port- które łączą się w pary. Wszystko inne nie ma określonego powiązania w "data"elemencie lub między "data"elementami.

Mając to wszystko na uwadze, oto przykład z komentarzami:

<!--
     Capture content by MIME type, which is how Gmail broadcasts
     attachment open requests.  pathPattern and file extensions
     are ignored, so the MIME type *MUST* be explicit, otherwise
     we will match absolutely every file opened.
-->
<intent-filter
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    android:priority="50" >
    <action android:name="android.intent.action.VIEW" />

    <category android:name="android.intent.category.BROWSABLE" />
    <category android:name="android.intent.category.DEFAULT" />

    <data android:scheme="file" />
    <data android:scheme="content" />
    <data android:mimeType="application/vnd.my-type" />
</intent-filter>

<!--
     Capture file open requests (pathPattern is honoured) where no
     MIME type is provided in the Intent.  An Intent with a null
     MIME type will never be matched by a filter with a set MIME
     type, so we need a second intent-filter if we wish to also
     match files with this extension and a non-null MIME type
     (even if it is non-null but zero length).
-->
<intent-filter
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    android:priority="50" >
    <action android:name="android.intent.action.VIEW" />

    <category android:name="android.intent.category.BROWSABLE" />
    <category android:name="android.intent.category.DEFAULT" />

    <data android:scheme="file" />
    <data android:host="*" />

    <!--
         Work around Android's ugly primitive PatternMatcher
         implementation that can't cope with finding a . early in
         the path unless it's explicitly matched.
    -->
    <data android:pathPattern=".*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.my-ext" />
</intent-filter>

<!--
     Capture file open requests (pathPattern is honoured) where a
     (possibly blank) MIME type is provided in the Intent.  This
     filter may only be necessary for supporting ES File Explorer,
     which has the probably buggy behaviour of using an Intent
     with a MIME type that is set but zero-length.  It's
     impossible to match such a type except by using a global
     wildcard.
-->
<intent-filter
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    android:priority="50" >
    <action android:name="android.intent.action.VIEW" />

    <category android:name="android.intent.category.BROWSABLE" />
    <category android:name="android.intent.category.DEFAULT" />

    <data android:scheme="file" />
    <data android:host="*" />
    <data android:mimeType="*/*" />

    <!--
         Work around Android's ugly primitive PatternMatcher
         implementation that can't cope with finding a . early in
         the path unless it's explicitly matched.
    -->
    <data android:pathPattern=".*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.my-ext" />
</intent-filter>
David Sainty
źródło
Świetnie, że stawiasz czoła wielu udokumentowanym potrzebom \\ .. w kółko i innym dziwactwom. Google powinien naprawić to w 4.2, do diabła. Niestety, nadal mam przypadki, których Twój przykład nie rozwiązuje. Czy jest jakiś problem z rozszerzeniami 6 cha, takimi jak „.gblorb”, że mój kod działa poprawnie z 3 literami lub mniej?
RoundSparrow hilltx
Moim zdaniem najlepsza odpowiedź na to pytanie i podobne pytania! Niestety, dopóki nie jest możliwe dopasowanie intencji treści według rozszerzenia pliku (jak wskazałeś w 5.), nie jest możliwe niezawodne filtrowanie pod kątem WSZYSTKICH poprawnych intencji bez dopasowania niewłaściwych. Dotyczy to przypadku, gdy nie można użyć niestandardowego typu MIME. Tak długo, jak Android nie zapewni rozwiązania tego problemu, będzie to dla mnie selektor plików w aplikacji ... Nie chcę mylić użytkownika z niespójnym zachowaniem.
Benjamin Bisinger,
1
Wielkie dzięki ... Dopiero co zrobiłem mój dzień ... W moim przypadku musiałem zmienić MimeType jak <data android:mimeType="*/*" /> we wszystkich trzech opcjach i działało to jak urok dla wszystkich aplikacji, w tym Dysku Google i Gmaila.
Rishabh Wadhwa
1
Bardzo dziękuję, @David Sainty. Położyłeś kres mojej 24-godzinnej agonii, próbując wymyślić, jak sobie z tym poradzić. Próbowałem stackoverflow.com/q/18577860/6110285 , stackoverflow.com/a/8599921/6110285 i wiele innych, które były podobne. Tylko ten działał.
pittix
24

Muszę przyznać, że proste zadanie otwierania załączników z wiadomości e-mail i plików z systemu plików na Androidzie było jednym z bardziej irytujących doświadczeń w historii. Łatwo jest obsłużyć zbyt wiele lub zbyt mało plików. Ale zrobienie tego dobrze jest trudne. Większość rozwiązań opublikowanych na stackoverflow nie działała poprawnie dla mnie.

Moje wymagania były następujące:

  • niech moja aplikacja obsługuje załączniki udostępnione przez moją aplikację
  • moja aplikacja obsługuje pliki w magazynie plików, które zostały wygenerowane przez moją aplikację i mają określone rozszerzenie

Prawdopodobnie najlepszym sposobem wykonania tego zadania jest określenie niestandardowego typu MIME dla załączników. Prawdopodobnie zdecydujesz się również na niestandardowe rozszerzenie pliku. Powiedzmy więc, że nasza aplikacja nazywa się „Cool App” i generujemy załączniki zawierające na końcu „.cool”.

To jest najbliżej mojego celu i działa ... zadowalająco.

<!-- Register to handle email attachments -->
<!-- WARNING: Do NOT use android:host="*" for these as they will not work properly -->
<intent-filter>
    <!-- needed for properly formatted email messages -->
    <data
        android:scheme="content"
        android:mimeType="application/vnd.coolapp"
        android:pathPattern=".*\\.cool" />
    <!-- needed for mangled email messages -->
    <data
        android:scheme="content"
        android:mimeType="application/coolapp"
        android:pathPattern=".*\\.cool" />
    <!-- needed for mangled email messages -->
    <data
        android:scheme="content"
        android:mimeType="application/octet-stream"
        android:pathPattern=".*\\.cool" />

    <action android:name="android.intent.action.VIEW" />

    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
</intent-filter>

<!-- Register to handle file opening -->
<intent-filter>
    <data android:scheme="file"
          android:mimeType="*/*"
          android:pathPattern=".*\\.cool"
          android:host="*"/>

    <action android:name="android.intent.action.VIEW" />

    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
</intent-filter>

Uwagi:

  • pathPatternWydaje się być mniej lub bardziej ignorowane załączniki (przy użyciu android:scheme="content"). Jeśli ktoś otrzyma ścieżkę, która reaguje tylko na określone wzorce, z przyjemnością zobaczę, jak to zrobić.
  • Aplikacja Gmail odmówiła umieszczenia mojej aplikacji w selektorze, jeśli dodałem android:host="*"atrybut.
  • Prawdopodobnie nadal działa, jeśli te intent-filterbloki są scalone, ale nie zweryfikowałem tego.
  • Do obsługi żądań z przeglądarki podczas pobierania pliku android:scheme="http"można użyć. Zwróć uwagę, że niektóre przeglądarki mogą zepsuć to, android:mimeTypewięc eksperymentuj android:mimeType="*/*"i sprawdzaj w debugerze, przez co faktycznie przechodzi, a następnie zaostrzaj filtrowanie, aby nie być tą irytującą aplikacją, która obsługuje wszystko .
  • Niektóre eksploratory plików mogą również zepsuć typy MIME dla twoich plików. Powyższe intent-filterzostało przetestowane z aplikacją „Moje pliki” firmy Samsung na Galaxy S3. Eksplorator FX nadal odmawia prawidłowego otwarcia pliku, a także zauważyłem, że ikona aplikacji nie jest używana dla plików. Ponownie, jeśli komuś to zadziała, prosimy o komentarz poniżej.

Mam nadzieję, że okaże się to przydatne i nie będziesz musiał tracić dni na przeglądanie wszystkich możliwych kombinacji. Jest miejsce na ulepszenia, więc komentarze są mile widziane.

omahena
źródło
To dla mnie działające rozwiązanie. Zarejestrowanie oddzielnego <intent-filter> dla Content-Scheme i File-Scheme załatwiło sprawę! Dzięki!
Mehlyfication
Dzięki! Pracował dla mnie. Zarówno aplikacja Gmail, jak i aplikacja Samsung My Files na Galaxy S6 mogły otwierać plik w mojej aplikacji przy użyciu Twojego rozwiązania!
Haris
Czym dokładnie jest „nazwa aplikacji”? (W moim przypadku, czytelny dla człowieka nazwa aplikacja ma miejsca w nim.)
William Jockusch
@WilliamJockusch wygląda na to, że @DavidSainty po prostu przechowuje nazwę aplikacji w pliku zasobów ciągu. Spacje powinny być w porządku. Łańcuch użyty jako android:labelfiltr intencji to ciąg, który użytkownik zobaczy w menu wyboru. Domyślnie używana jest nazwa aplikacji.
omahena
Czego należy używać z aplikacją „Dysk Google”?
programista Androida
9

Odpowiedź Briana powyżej doprowadziła mnie do tego w 90%. Na koniec użyłem typu mime

android:mimeType="*/*"

Podejrzewam, że poprzednie plakaty próbowały zamieścić ten sam szczegół, ale bez podania gwiazdy slash star jako kodu, stackoverflow wyświetla to jako zwykły slash.

Dawson
źródło
2
Dzięki temu poradzisz sobie ze WSZYSTKIMI typami plików i to jest naprawdę denerwujące (no cóż, z wyjątkiem sytuacji, gdy twoja aplikacja rzeczywiście obsługuje wszystko) ...
Tim Autin
To jest złe. Nie rób tego w swoich aplikacjach.
Mars
8

Zamiast android:pathpróbować android:mimeType, z wartością typu MIME tej konkretnej treści. Również android:pathnie akceptuje symboli wieloznacznych - wykorzystanie android:pathPatterndo tego.

CommonsWare
źródło
„Typ pliku nie jest uwzględniony w typach MIME”? Nadal powinien istnieć typ MIME dla typu pobieranej zawartości, nawet jeśli nie zawiera tego samego słowa.
Eric Mill
Istnieje typ MIME dla typu zawartości, ale plik jest tworzony przez aplikację innej firmy, która umieszcza na nim inne rozszerzenie, więc nie sądzę, aby został rozpoznany jako ten typ MIME.
Curyous
7

Próbowałem, aby to działało od lat i wypróbowałem wszystkie sugerowane rozwiązania, ale nadal nie mogę sprawić, by Android rozpoznał określone rozszerzenia plików. Mam filtr intencji z rozszerzeniem"*/*" typem MIME, który jest jedyną rzeczą, która wydaje się działać, a przeglądarki plików wyświetlają teraz moją aplikację jako opcję otwierania plików, jednak moja aplikacja jest teraz wyświetlana jako opcja do otwierania DOWOLNEGO RODZAJU pliku, mimo że Określone rozszerzenia plików zostały określone za pomocą znacznika pathPattern. To sięga tak daleko, że nawet gdy próbuję wyświetlić / edytować kontakt na mojej liście kontaktów, Android pyta mnie, czy chcę użyć mojej aplikacji do wyświetlenia kontaktu, a to tylko jedna z wielu sytuacji, w których to się dzieje, BARDZO BARDZO irytujące.

W końcu znalazłem ten post w grupach Google z podobnym pytaniem, na które odpowiedział prawdziwy inżynier platformy Android. Wyjaśnia, że ​​android po prostu nie wie nic o rozszerzeniach plików, tylko o typach MIME ( https://groups.google.com/forum/#!topic/android-developers/a7qsSl3vQq0 ).

Tak więc z tego, co widziałem, wypróbowałem i przeczytałem, Android po prostu nie może odróżnić rozszerzeń plików od tagu pathPattern to w zasadzie gigantyczna strata czasu i energii. Jeśli masz szczęście, że potrzebujesz tylko plików określonego typu MIME (powiedzmy tekst, wideo lub audio), możesz użyć filtru intencji z typem MIME. Jeśli potrzebujesz określonego rozszerzenia pliku lub typu MIME nieznanego przez Androida, nie masz szczęścia.

Jeśli się mylę, powiedz mi, do tej pory przeczytałem każdy post i wypróbowałem wszystkie proponowane rozwiązania, które mogłem znaleźć, ale żadne nie zadziałało.

Mógłbym napisać kolejną stronę lub dwie o tym, jak powszechne są tego typu rzeczy w Androidzie i jak schrzanione jest doświadczenie programisty, ale oszczędzę ci moich gniewnych tyrad;). Mam nadzieję, że zaoszczędziłem komuś kłopotów.

PeeGee85
źródło
1
Głosował za Tobą, ponieważ Twoja odpowiedź zawiera przydatny link, a przeciwnik nie zostawił komentarza. Przepraszam, SO może czasami być nieprzyjazny, ale nie rezygnuj z tego.
John Hatton,
4

Zaktualizuj 2020

Android przeszedł w kierunku identyfikatorów URI treści i typów MIME dla filtrów intencji.

Problem

Identyfikator URI treści niekoniecznie musi zawierać rozszerzenie lub nazwę pliku i będzie różny w różnych aplikacjach, które dostarczają zawartość / plik.

Oto kilka przykładowych identyfikatorów URI treści z różnych aplikacji e-mail dla tego samego załącznika wiadomości e-mail:

Gmail -> 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

Outlook -> content://com.microsoft.office.outlook.fileprovider/outlookfile/data/data/com.microsoft.office.outlook/cache/file-download/file--2146063402/filename.customextention

Aplikacja e-mail Samsung -> content://com.samsung.android.email.attachmentprovider/1/1/RAW

Jak widać, wszystkie są różne i nie gwarantujemy, że zawierają one coś związanego z twoim rzeczywistym plikiem. Dlatego nie możesz użyć tego, android:pathPatternco sugerowała większość.

Obejście problemu dla załączników do wiadomości e-mail

<intent-filter>
    <action android:name="android.intent.action.VIEW"/>

    <category android:name="android.intent.category.BROWSABLE"/>
    <category android:name="android.intent.category.DEFAULT"/>

    <data android:scheme="content"/>
    <data android:host="*"/>

    <!--  Required for Gmail and Samsung Email App  -->
    <data android:mimeType="application/octet-stream"/>

    <!--  Required for Outlook  -->
    <data android:mimeType="application/my-custom-extension"/>
</intent-filter>

Dzięki testom znalazłem typy MIME używane w Gmailu, Outlooku i Samsung Email i dodałem je do mojego filtra intencji.

Ostrzeżenia / kłopoty

  • Zauważyłem, że przy powyższym rozwiązaniu, jeśli otworzę dowolny plik, który był typem binarnym, automatycznie uruchomi moją aplikację. Poradziłem sobie z tym w mojej działalności, wyświetlając stan niepowodzenia, jeśli nie mogliśmy przeanalizować pliku. Pomyślałem, że to dość rzadkie wydarzenie, więc byłoby to do zaakceptowania.

  • Nie mogłem znaleźć sposobu na uruchomienie aplikacji przez przeglądarkę plików bez dodania jej <data android:mimeType="*/*"/>do mojego filtra intencji. Nie mogłem tego użyć, ponieważ uruchomiłoby to moją aplikację za każdym razem, gdy użytkownik kliknął dowolny plik na swoim telefonie (nie tylko pliki z rozszerzeniem niestandardowym). Nie polecałbym dodawania tego do filtra intencji.

Końcowe przemyślenia

  • Obecnie nie ma eleganckiego rozwiązania umożliwiającego powiązanie aplikacji z określonym typem rozszerzenia w systemie Android. To było najlepsze, co mogłem zrobić w mojej sytuacji.
alexander antaya
źródło
wielkie dzięki, działa, testowano październik 2020, od Androida 7
Harsh
3

Odpowiedź Briana jest bardzo bliska, ale oto czysty i bezbłędny sposób na wywołanie aplikacji podczas próby otwarcia pliku z własnym niestandardowym rozszerzeniem (bez schematu ani hosta):

<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:mimeType="*/*" />
    <data android:pathPattern="*.*\\.kdb" />
</intent-filter>
Kon
źródło
2
Dokumentacja systemu Android stwierdza, że ​​atrybut pathPattern ma znaczenie tylko wtedy, gdy określono schemat i hosta, i zweryfikowałem to: developer.android.com/guide/topics/manifest/data-element.html
Brian Pellin,
4
-1; to będzie pasować do każdego pliku; Komentarz Briana jest poprawny i po niewielkiej modyfikacji mimeType = " / " jego oryginalny przykład jest doskonały.
Nick
Ten post jest dawno temu, ale nie "/" nie instaluje się. Potrzebujesz „* / *”, który będzie pasował do dowolnego typu pliku (nie jestem pewien, czy chcesz to powiedzieć). Twój program może więc zostać poproszony o otwarcie plików wideo lub mp3. Nie znalazłem jeszcze rozwiązania tego problemu.
Rene
Należy użyć jednego <data>tagu z czterema atrybutami. Twoje rozwiązanie może działać z Androidem 2 - ale zasady stały się bardziej rygorystyczne: stackoverflow.com/questions/20650378/ ...
Martin
O co chodzi z tą dziwną ścieżką ? A hosti schemesą wymagane!
IgorGanapolsky
3

Na Androidzie 4 zasady stały się bardziej rygorystyczne niż kiedyś. Posługiwać się:

    <data
      android:host=""
      android:mimeType="*/*"
      android:pathPattern=".*\\.ext"
      android:scheme="file"
    ></data>
Jaskółka oknówka
źródło
3

Sam bardzo się z tym zmagałem w przypadku niestandardowego rozszerzenia pliku. Po wielu poszukiwaniach znalazłem tę stronę internetową, na której plakat odkrył, że klasa patternMatcher systemu Android (która jest używana do dopasowania pathPattern w filtrach intencji) zachowuje się nieoczekiwanie, gdy ścieżka zawiera pierwszy znak wzorca dopasowania w innym miejscu ścieżki (np. jeśli próbujesz dopasować „* .xyz”, klasa patternMatcher zatrzymuje się, jeśli wcześniej na ścieżce znajduje się „x”). Oto, co znalazł w celu obejścia problemu i zadziałał dla mnie, chociaż jest to trochę hack:

PatternMatcher jest używany dla pathPattern w IntentFilter Ale algorytm PatternMatcher jest dla mnie dość dziwny. Oto algorytm Android PatternMatcher.

Jeśli w środku ciągu znajduje się „następny znak” wzorca „. *”, PatternMatcher zatrzymuje pętlę w tym miejscu. (Zobacz PatternMatcher.java platformy Android).

Dawny. string: "to jest mój załącznik" wzorzec: ". att. ". Android PatternMatcher wprowadź pętlę do dopasowania '. 'wzorzec, aż napotkasz następny znak wzorca (w tym przykładzie „a”) Tak, „. 'pasująca pętla kończy się na indeksie 8 -' a 'między' is 'i' my '. Dlatego wynik tego dopasowania zwraca „fałsz”.

Dość dziwne, prawda? Aby obejść ten problem - a właściwie zmniejszyć możliwość - programista powinien użyć irytującego głupiego pathPattern.

Dawny. Cel: Dopasowana ścieżka uri zawierająca „wiadomość”.

<intent-filter>
...
<data android:pathPattern=".*message.*" />
<data android:pathPattern=".*m.*message.*" />
<data android:pathPattern=".*m.*m.*message.*" />
<data android:pathPattern=".*m.*m.*m.*message.*" />
<data android:pathPattern=".*m.*m.*m.*m.*message.*" />
...
</intent-filter>

Jest to szczególnie widoczne podczas dopasowywania z niestandardowym rozszerzeniem pliku.

benjamin davis
źródło
Dla wszystkich zainteresowanych problem został zarejestrowany na code.google.com
benjamin davis
3

Żadne z powyższych nie działa poprawnie, dla akcji VIEW lub SEND, jeśli sufiks nie jest zarejestrowany z typem MIME w systemowej bazie danych MIME systemu Android. Jedyne ustawienia, które znalazłem, że uruchamiają się dla określonego sufiksu, obejmują android:mimeType="*/*", ale potem akcja uruchamia się dla WSZYSTKICH plików. Najwyraźniej NIE to, czego chcesz!

Nie mogę znaleźć żadnego odpowiedniego rozwiązania bez dodania mime i sufiksu do bazy danych mime systemu Android, jak dotąd nie znalazłem sposobu, aby to zrobić. Jeśli ktoś wie, wskaźnik byłby wspaniały.

Glenn Widener
źródło
2

Kiedy intencja spełnia a intent-filter, są to intent-filterwymagania: (wyobraź sobie listę kontrolną).

  • Dowolne dopasowanie <action>
  • Dowolne dopasowanie <category>
  • Dowolne dopasowanie <data mimeType>(łatwa naprawa: „ / ”)
  • Opcjonalnie:

    • Wszelkie dopasowanie <data scheme>(łatwo naprawić: <data android:scheme="file" /> <data android:scheme="content" />)

    • Dowolne dopasowanie <data host>(łatwa poprawka: „*”)

    • Dowolne dopasowanie <data pathPattern/etc.> (na przykład .*\\.0cc)

Definiowanie wielu <data $type="">elementów powoduje zaznaczenie pola $ type, jeśli którekolwiek z nich jest <data $type=>zgodne z Intent.

Pominięcie mimeType spowoduje uszkodzenie intent-filter , mimo że wydaje się zbędne. Pominięcie <data scheme/host/pathPattern>powoduje, że filtr pasuje do wszystkiego.

https://f-droid.org/en/packages/de.k3b.android.intentintercept/ to aplikacja przeznaczona do odbioru wszystkich zamiarów i umożliwia sprawdzenie zamiaru. Dowiedziałem się, że nierozpoznane rozszerzenia plików otwierane za pomocą Simple File Manager są dostarczane z typem MIME application/octet-stream.

https://stackoverflow.com/a/4621284/2683842 zgłasza, że <data pathPattern=> .*xyzprzerywa pracę przy pierwszym xnapotkaniu i zawiedzie natychmiast, jeśli nie nastąpi yz. Więc /sdcard/.hidden/foo.0ccnie przejdzie.*\\.0cc chyba że spróbujesz .*\\..*\\.0cczamiast tego.

  • Nie sprawdziłem, czy to obejście jest konieczne.

Wynik końcowy:

<activity android:name=".Ft2NsfActivity">

    <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:scheme="content" />
        <data android:host="*" />
        <data android:pathPattern=".*\\.ftm"/>
        <data android:pathPattern=".*\\..*\\.ftm"/>
        <data android:pathPattern=".*\\..*\\..*\\.ftm"/>
        <data android:pathPattern=".*\\..*\\..*\\..*\\.ftm"/>
        <data android:pathPattern=".*\\.0cc"/>
        <data android:pathPattern=".*\\..*\\.0cc"/>
        <data android:pathPattern=".*\\..*\\..*\\.0cc"/>
        <data android:pathPattern=".*\\..*\\..*\\..*\\.0cc"/>
        <data android:mimeType="*/*" />
    </intent-filter>

</activity>
nyanpasu64
źródło
1

Jeśli chcesz, aby pliki były otwierane bezpośrednio z Gmaila, Dropbox lub dowolnego narzędzia do tworzenia plików w systemie Android, użyj następującego kodu (usuń 'android: host = "*"', który sprawił, że plik był nieosiągalny dla Gmaila):

<intent-filter>
    <action android:name="android.intent.action.VIEW"/>
    <category android:name="android.intent.category.BROWSABLE"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data android:scheme="content" android:pathPattern=".*\\.kdb" 
          android:mimeType="application/octet-stream"/>


</intent-filter>

<intent-filter>
    <action android:name="android.intent.action.VIEW"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data android:scheme="file" android:mimeType="*/*"     
          android:pathPattern=".*\\.kdb"/>
</intent-filter>

Filtr danych musi być zapisany w jednej instrukcji zgodnie z wersją Androida 4.x.

AndreasReiff
źródło
Próbowałem wszystkiego, aby pobieranie i otwieranie przeglądarki Androida działało poprawnie. Twoje rozwiązanie działa dobrze w natywnej przeglądarce Androida i Chrome, jednak wydaje się, że Android Firefox nadal otwiera mój plik w oknie tekstowym. To niestandardowy typ MIME i niestandardowe rozszerzenie. Wcześniej tylko rozszerzenie działało tylko w przeglądarce Firefox. Teraz działa wszędzie oprócz Firefoksa (w tym Gmaila). Wciąż go testuję, ale chciałem tylko oznaczyć fakt, że pojawił się tutaj nowy zestaw problemów z różnymi przeglądarkami.
Damon Smith,
1

Korzystanie z filtru jak poniżej do otwierania z przeglądarki, Gmaila i przeglądarki plików (przetestowane). UWAGA: Proszę nie łączyć dwóch filtrów, co spowoduje, że przeglądarka zignoruje Twoją aplikację (przetestowana).

        <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" android:pathPattern=".*\\.ext" android:mimeType="application/*"/>
            <data android:scheme="content" android:pathPattern=".*\\.ext" android:mimeType="application/*"/>
        </intent-filter>

        <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="http"
                  android:host="*"
                  android:pathPattern=".*\\.ext" />
            <data android:scheme="https"
                  android:host="*"
                  android:pathPattern=".*\\.ext" />
            <data android:scheme="ftp"
                  android:host="*"
                  android:pathPattern=".*\\.ext" />

        </intent-filter>
Tran Hieu
źródło
Czy przetestowałeś tę odpowiedź z załącznikami Gmaila?
IgorGanapolsky
0

Przeczytaj ten https://developer.android.com/training/sharing/receive , to może pomóc w rozpoczęciu. następnie w pliku manifestu wypróbuj poniższy filtr intencji podczas rejestrowania odbiornika w działaniu, które ma zostać otwarte

<intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <data android:scheme="content"/>
            <category android:name="android.intent.category.BROWSABLE"/>
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="application/your_extension" />
</intent-filter>

upewnij się, że rozszerzenie jest podawane bez znaku „.” w tym

Szorstki
źródło