'netから特定の拡張子を持つファイルをダウンロードし、それを処理するためにアプリケーションに渡してもらいたいのですが、インテントフィルターを理解できませんでした。ファイルタイプはMIMEタイプに含まれていません。
<data android:path="*.ext" />
しかし、私はそれを機能させることができませんでした。
回答:
これが動作するようにAndroidManifest.xmlでアクティビティを定義する方法です。
<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>
scheme
のfile
ローカルファイルを開いたときに、これは(むしろHTTPなどのプロトコルよりも)起こるべきであることを示しています。
mimeType
\*/\*
任意のMIMEタイプに一致するように設定できます。
pathPattern
照合する拡張子を指定する場所です(この例では.kdb
)。.*
先頭のは、任意の文字シーケンスに一致します。これらの文字列はダブルエスケープが必要であるため\\\\.
、文字どおりのピリオドに一致します。次に、ファイル拡張子で終了します。pathPatternの注意点の1つ.*
は、これが正規表現である場合に予想されるような貪欲な一致ではないことです。このパターンは、.
before を含むパスに一致しません.kdb
。この問題と回避策の詳細については、こちらをご覧ください
最後に、Androidのドキュメントによると、属性を機能させるにはhost
とscheme
属性の両方が必要であるためpathPattern
、これをワイルドカードに設定してすべてに一致させます。
これで、.kdb
Linda File Managerなどのアプリでファイルを選択すると、私のアプリがオプションとして表示されます。これはファイルスキームに登録するだけなので、これだけではブラウザでこのファイルタイプをダウンロードできません。自分の携帯電話にLinda File Managerのようなアプリを登録することで、あらゆる種類のファイルをダウンロードできるようになります。
.kdbx
この投稿を指摘されたとき、ESファイルエクスプローラーがkdbxファイルを開くことができるように、MIMEタイプを拡張子にバインドする方法を実際に探していました。インテントに空のMIMEタイプがある場合、このインテントフィルターは機能しません。また、アクションとしてEMPTY文字列を使用し、URIのみを使用するインテントを作成することもできます。Googleドキュメントはその意図に応えたため、有効である必要があります。
<data>
。4つの属性を持つタグで使用する必要があります。4つのタグを持つことは論理的ORです—これはAndroid 2で機能しました—しかし、Android 4はより厳密です。stackoverflow.com/questions/20650378/…を
\\\\.
リテラルのピリオドと一致する場合、なぜこれを使用して次の.kdb
ような拡張子を形成しないの\\\\.kdb
ですか?
このトピックには、特にGoogle自身のドキュメントからの多くの誤った情報があります。最高の、そして奇妙なロジックを考えると、おそらく唯一の実際のドキュメントはソースコードです。
インテントフィルタの実装では、ほとんどの説明を覆すのロジックを持っています。パーサコードパズルの他の関連する作品です。
次のフィルターは、賢明な動作にかなり近づきます。パスパターンは、「ファイル」スキームインテントに適用されます。
グローバルMIMEタイプのパターンマッチは、ファイル拡張子が一致する限り、すべてのタイプに一致します。これは完璧ではありませんが、ESファイルエクスプローラーなどのファイルマネージャーの動作を一致させる唯一の方法であり、URI /ファイル拡張子が一致するインテントに限定されます。
ここには "http"のような他のスキームを含めていませんが、これらすべてのフィルターでおそらく正常に機能します。
奇妙なスキームは「コンテンツ」であり、その拡張はフィルターで利用できません。ただし、プロバイダーがMIMEタイプを指定している限り(Gmailは添付ファイルのMIMEタイプを妨げられずに渡す)、フィルターは一致します。
注意すべき点:
これらすべてを念頭に置いて、コメント付きの例を次に示します。
<!--
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>
<data android:mimeType="*/*" />
、3つのオプションすべてでMimeTypeを変更する必要が あり、GoogleドライブやGmailを含むすべてのアプリの魅力のように機能しました。
メールの添付ファイルやAndroidのファイルシステムのファイルを開くという簡単なタスクは、これまでで最も面倒な経験の1つであったことを認めざるを得ません。処理するファイルが多すぎたり少なすぎたりすることは簡単です。しかし、それを適切に理解することは困難です。stackoverflowに投稿されたソリューションのほとんどは、私にとって正しく機能しませんでした。
私の要件は:
おそらく、このタスクを実行する最良の方法は、添付ファイルのカスタムMIMEタイプを指定することです。また、カスタムファイル拡張子を選択することもできます。それでは、アプリの名前が「Cool App」で、末尾に「.cool」が付いた添付ファイルを生成するとします。
これは私が目標に到達した最も近いものであり、機能します...満足です。
<!-- 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>
ノート:
pathPattern
使用している場合(多かれ少なかれの添付ファイルについては無視しているようですandroid:scheme="content"
)。誰かがpathPatternを取得して特定のパターンにのみ応答する場合、その方法を見てわくわくします。android:host="*"
属性。intent-filter
ブロックがマージされたますが、私はこれを確認していません。android:scheme="http"
に使用できます。特定のブラウザは混乱する可能性があるandroid:mimeType
のでandroid:mimeType="*/*"
、実際に通過するものを試し、デバッガで確認してから、フィルタリングを強化して、すべてを処理する迷惑なアプリにならないようにしてください。ください。intent-filter
はGalaxy S3上のSamsungの「マイファイル」アプリでテストされました。FXエクスプローラーはファイルを適切に開くことを拒否し、アプリアイコンがファイルに使用されていないことにも気付きました。繰り返しになりますが、誰かがそれを機能させる場合は、以下にコメントしてください。これが役に立つこと、そしてすべての可能な組み合わせを実行する日を無駄にする必要がないことを願っています。改善の余地があるので、コメントを歓迎します。
android:label
インテントフィルターに使用される文字列は、ユーザーがセレクターメニューに表示する文字列です。デフォルトでは、アプリケーション名が使用されます。
ではなく、この特定のコンテンツのMIMEタイプの値を使用してandroid:path
みてくださいandroid:mimeType
。また、android:path
ワイルドカードを受け入れません-そのために使用android:pathPattern
します。
私はこれを長い間機能させるようにしており、提案されたすべての解決策を基本的に試しましたが、Androidに特定のファイル拡張子を認識させることができません。私はインテントフィルターを持っています"*/*"
いるように見える唯一の方法 MIME、ファイルブラウザーがファイルを開くためのオプションとして自分のアプリをリストするようになりましたが、私のアプリは今でもすべての種類のファイルを開くためのオプションとして表示されていますpathPatternタグを使用して特定のファイル拡張子を指定しました。これまでのところ、連絡先リストで連絡先を表示/編集しようとしても、Androidでアプリを使用して連絡先を表示するかどうかを尋ねられます。これは、これが発生する多くの状況の1つであり、非常に煩わしいものです。
ついに、このGoogleグループの投稿に、実際のAndroidフレームワークエンジニアが返信した同様の質問が見つかりました。彼女は、androidはファイル拡張子については何も知らず、MIMEタイプのみを知っていると説明しています(https://groups.google.com/forum/#!topic/android-developers/a7qsSl3vQq0)。
したがって、私が見て、試して、読んだことから、Androidはファイル拡張子を単に区別することができず、pathPatternタグは基本的に時間とエネルギーの巨大な無駄です。幸運なことに、特定のMIMEタイプ(テキスト、ビデオ、オーディオなど)のファイルのみが必要な場合は、MIMEタイプでインテントフィルターを使用できます。特定のファイル拡張子が必要な場合や、Androidで認識されていないMIMEタイプが必要な場合は、運が悪いです。
これについて私が間違っている場合は教えてください。これまでのところ、すべての投稿を読んで、提案された解決策をすべて試しましたが、どれもうまくいきませんでした。
これらの種類のことがAndroidでどのように一般的であり、開発者のエクスペリエンスが台無しになっているのかについて、別のページを1つまたは2つ書くことができますが、怒りの怒りを救います;)私は誰かをいくつかのトラブルを救ったことを願っています。
ブライアンの答えは非常に近いですが、独自のカスタム拡張子を持つファイルを開こうとしたときにアプリを呼び出すクリーンでエラーのない方法を次に示します(スキームやホストは必要ありません)。
<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>
<data>
4つの属性を持つ1つのタグを使用する必要があります。あなたのソリューションは、Android 2で動作するかもしれない-しかし、ルールはより厳しくなっていますstackoverflow.com/questions/20650378/...
host
そしてscheme
必要とされます!
私自身、カスタムファイル拡張子についてこれにかなり苦労しています。何度も検索したところ、このWebページで、パスの他の場所に一致パターンの最初の文字がパスに含まれていると、AndroidのpatternMatcherクラス(Intent-FiltersでのpathPatternマッチングに使用される)が予期しない動作をすることがポスターで発見されました。 (たとえば、「*。xyz」と一致させようとしている場合、パスの前に「x」があると、patternMatcherクラスは停止します)。これは彼が回避策を見つけて私のために働いたものですが、それは少しハックです:
PatternMatcherはIntentFilterのpathPatternに使用されますが、PatternMatcherのアルゴリズムは私にはかなり奇妙です。こちらがAndroid PatternMatcherのアルゴリズムです。
文字列の途中に「。*」パターンの「次の文字」がある場合、PatternMatcherはその時点でループを停止します。(AndroidフレームワークのPatternMatcher.javaを参照してください。)
例 文字列:「これは私の添付ファイルです」パターン:「。att。」。Android PatternMatcherがループに入る 'に一致します。'パターンは、パターンの次の文字(この例では' a ')に出会うまで続きます。'一致するループはインデックス8で停止します-' is 'と' my 'の間の' a '。したがって、この一致の結果は「false」を返します。
かなり奇妙ですね。これを回避するには-実際には可能性を減らします-開発者は迷惑な愚かなpathPatternを使用する必要があります。
例 目標:「メッセージ」を含むURIパスに一致。
<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>
これは、カスタムファイルの拡張子と一致する場合に特に発行されます。
Androidのsystem = wide MIMEデータベースでサフィックスがMIMEタイプに登録されていない場合、VIEWまたはSENDアクションの場合、上記のいずれも適切に機能しません。指定されたサフィックスandroid:mimeType="*/*"
に対して起動することがわかった唯一の設定にはが含まれますが、その後、すべてのファイルに対してアクションが起動します。明らかにあなたが望むものではありません!
Android MIMEデータベースにMIMEとサフィックスを追加せずに適切な解決策を見つけることはできません。これまでのところ、それを行う方法が見つかりません。誰かが知っているなら、ポインタは素晴らしいでしょう。
インテントがを満たしている場合intent-filter
のintent-filter
要件は次のとおりです(チェックリストを想像してください)。
<action>
<category>
<data mimeType>
(簡単な修正: " / ")オプション:
どれマッチング<data scheme>
(簡単な修正:<data android:scheme="file" /> <data android:scheme="content" />
)
すべての一致<data host>
(簡単な修正: "*")
<data pathPattern/etc.>
(例.*\\.0cc
)複数の<data $type="">
要素を定義すると、と<data $type=>
一致する場合に$ typeボックスがチェックされますIntent
。
mimeTypeを省略するとintent-filter
、重複しているように見えますが、が壊れます。省略する<data scheme/host/pathPattern>
と、フィルターはすべてに一致します。
https://f-droid.org/en/packages/de.k3b.android.intentintercept/は、すべてのインテントを受け取るように設計されたアプリで、インテントを検査できます。Simple File Managerを介して開かれた認識されないファイル拡張子がMIMEタイプで配信されることを知りましたapplication/octet-stream
。
https://stackoverflow.com/a/4621284/2683842は<data pathPattern=>
.*xyz
、最初x
に異常終了したことを報告し、が続かない場合はすぐに失敗しyz
ます。あなたが代わりにしようとしない限りそう/sdcard/.hidden/foo.0cc
なりません。.*\\.0cc
.*\\..*\\.0cc
最終結果:
<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>
Gmail、Dropbox、または組み込みのAndroidファイルツールからファイルを直接開く場合は、次のコードを使用します(Gmailでファイルにアクセスできなくなった 'android:host = "*"を削除します):
<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>
データフィルターは、Androidバージョン4.xのように1つのステートメントで記述する必要があります。
以下のフィルターを使用して、ブラウザー、Gmail、ファイルブラウザーから開きます(テスト済み)。注:2つのフィルターをマージしないでください。マージすると、ブラウザーでアプリが無視されます(テスト済み)。
<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>
Androidは、インテントフィルターのコンテンツURIとMIMEタイプに移行しました。
コンテンツURIは必ずしもファイルの拡張子または名前を含む必要はなく、コンテンツ/ファイルを提供している異なるアプリケーション間で異なります。
以下は、同じメール添付ファイルに対する異なるメールアプリケーションのコンテンツURIの例です。
Gmail-> content://com.google.android.gm.sapi/some_email@gmail.com/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
Samsungメールアプリ-> content://com.samsung.android.email.attachmentprovider/1/1/RAW
ご覧のとおり、これらはすべて異なり、実際のファイルに関連するものを含むことが保証されていません。したがって、android:pathPattern
ほとんどの人が提案しているような方法は使用できません。
<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>
テストの結果、Gmail、Outlook、Samsung Emailが使用しているMIMEタイプが見つかり、それらをインテントフィルターに追加しました。
上記の解決策で、バイナリタイプのファイルを開くと、アプリが自動的に起動することがわかりました。私は、ファイルを解析できなかった場合に失敗状態を表示することで、アクティビティでこれを処理しました。私はこれがかなりまれなイベントだと思ったので、それは許容できるでしょう。
<data android:mimeType="*/*"/>
インテントフィルターに追加しないと、ファイルブラウザーを介してアプリを起動する方法が見つかりませんでした。ユーザーがクリックするたびに、それはその後、私のアプリを起動しますので、私はこれを使用することができませんでした任意の自分の携帯電話上のファイル(だけでなく、カスタムファイル拡張子のものを)。これをインテントフィルターに追加することはお勧めしません。