ネットから特定の拡張子のファイルをダウンロードし、それをアプリケーションに渡して処理できるようにしたいのですが、インテント フィルターがわかりません。ファイルタイプはMIMEタイプに含まれていません。使用してみました
<data android:path="*.ext" />
しかし、私はそれを機能させることができませんでした。
ネットから特定の拡張子のファイルをダウンロードし、それをアプリケーションに渡して処理できるようにしたいのですが、インテント フィルターがわかりません。ファイルタイプは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>
のは、(HTTP のようなプロトコルではなく) ローカル ファイルが開かれたときにこれが発生することを示しますscheme
。file
mimeType
*/*
任意の MIME タイプに一致するように設定できます。
pathPattern
一致させたい拡張子を指定する場所です (この例では.kdb
)。先頭の.*
は、任意の文字列に一致します。これらの文字列には二重のエスケープが必要なため\\\\.
、リテラルのピリオドに一致します。次に、ファイル拡張子で終了します。pathPattern に関する 1 つの注意点は.*
、これが正規表現である場合に予想されるような貪欲な一致ではないということです。.
このパターンは、 の前にを含むパスと一致しません.kdb
。この問題と回避策の詳細については、こちらを参照してください。
最後に、Android のドキュメントによると、属性が機能するにはhost
とscheme
属性の両方が必要なpathPattern
ので、ワイルドカードに設定するだけで何にでも一致します。
.kdb
これで、 Linda File Manager などのアプリでファイルを選択すると、私のアプリがオプションとして表示されます。これだけでは、ブラウザでこのファイル タイプをダウンロードできないことに注意してください。これは、ファイル スキームにしか登録されないためです。Linda File Manager のようなアプリを携帯電話にインストールすると、それ自体が一般的に登録され、あらゆる種類のファイルをダウンロードできるようになります。
このトピックについては、特に Google 自身のドキュメントから多くの誤った情報があります。最良の、そして奇妙なロジックを考えると、おそらく唯一の本当のドキュメントはソースコードです。
インテント フィルターの実装には、ほとんど説明に反するロジックがあります。パーサー コードは、パズルのもう 1 つの関連するピースです。
次のフィルターは、賢明な動作にかなり近づきます。"file"
スキームの意図のために、パスパターンは適用されます。
グローバル MIME タイプ パターン マッチは、ファイル拡張子が一致する限り、すべてのタイプに一致します。これは完全ではありませんが、ES ファイル エクスプローラーなどのファイル マネージャーの動作に一致させる唯一の方法であり、URI/ファイル拡張子が一致するインテントに限定されます。
ここにあるような他のスキームは含めていません"http"
が、おそらくこれらすべてのフィルターでうまく機能するでしょう。
奇妙なスキーム out は"content"
であり、その拡張子はフィルターで使用できません。ただし、プロバイダーが MIME タイプを指定している限り (たとえば、Gmail は添付ファイルの MIME タイプを妨げられずに渡します)、フィルターは一致します。
注意すべき点:
scheme
ANDhost
を指定する必要がありますpath
(現在、Google の API ガイドに反しています)。""
。これは、とは非常に異なる方法でフィルター処理され、明示的に一致させることは不可能であり、危険なフィルターnull
によってのみ一致させることができます。"*/*"
"*/*"
を一致させません。MIMEタイプがまったくないこの特定のケースでは、別のフィルタが必要です。null
"content"
ファイル名はインテントで利用できないため (少なくとも Gmail では)、スキームは MIME タイプによってのみ照合できます。"data"
要素で属性をグループ化することは、(ほとんど) 解釈とは無関係ですが、特定の例外host
とport
- はペアになります。"data"
それ以外は、要素内または要素間に特定の関連付けはありません"data"
。これらすべてを念頭に置いて、コメント付きの例を次に示します。
<!--
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>
メールの添付ファイルや 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="*"
属性を追加すると、Gmail アプリが自分のアプリをチューザーにリストすることを拒否しました。intent-filter
これらのブロックがマージされていれば、おそらくまだ機能しますが、これは確認していません。android:scheme="http"
使用できます。特定のブラウザが混乱する可能性があることに注意してください。デバッガーで実際に何が渡されるかをandroid:mimeType
試してチェックインし、フィルタリングを強化して、すべてを処理する迷惑なアプリにならないようにします。android:mimeType="*/*"
intent-filter
は、Galaxy S3 の Samsung の「My Files」アプリでテストされました。FX Explorer はまだファイルを正しく開くことを拒否しており、アプリ アイコンがファイルに使用されていないことにも気付きました。繰り返しますが、誰かがそれを機能させた場合は、以下にコメントしてください。これが便利であり、考えられるすべての組み合わせを何日も無駄にする必要がないことを願っています。まだまだ改善の余地ありですのでコメントお待ちしております。
上記のブライアンの答えにより、90%の方法が得られました。最後に、使用した MIME タイプに
android:mimeType="*/*"
以前の投稿者が同じ詳細を投稿しようとしたと思われますが、スター スラッシュ スターをコードとして引用せずに、stackoverflow はそれを単なるスラッシュとして表示します。
ではなく、この特定のコンテンツのMIMEタイプの値を使用してandroid:path
試してください。android:mimeType
また、android:path
ワイルドカードを受け入れません-そのために使用android:pathPattern
します。
サフィックスが Android の system=wide MIME データベースの MIME タイプに登録されていない場合、VIEW または SEND アクションで上記のいずれも適切に機能しません。指定された接尾辞が含まれているために起動することがわかった唯一の設定ですがandroid:mimeType="*/*"
、アクションはすべてのファイルに対して起動します。明らかにあなたが望むものではありません!
mime とサフィックスを Android mime データベースに追加しないと、適切な解決策を見つけることができません。これまでのところ、それを行う方法は見つかりませんでした。誰かが知っていれば、ポインターは素晴らしいでしょう。
ブライアンの答えは非常に近いですが、独自のカスタム拡張子を持つファイルを開こうとしたときにアプリを呼び出すためのクリーンでエラーのない方法は次のとおりです(スキームやホストは必要ありません)。
<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>
私自身、カスタムファイル拡張子のためにこれにかなり苦労してきました。何度も検索した結果、Android の patternMatcher クラス (Intent-Filters での pathPattern マッチングに使用される) が、パスに一致パターンの最初の文字が含まれている場合に予期しない動作をすることを投稿者が発見したこの Web ページを見つけました。 (「*.xyz」に一致させようとしている場合のように、パスの前に「x」がある場合、patternMatcher クラスは停止します)。これは彼が回避策として見つけたもので、私のために働いていましたが、それは少しハックです:
IntentFilter の pathPattern には PatternMatcher を使用していますが、PatternMatcher のアルゴリズムは私にはかなり奇妙です。これが Android PatternMatcher のアルゴリズムです。
文字列の途中に「.*」パターンの「次の文字」がある場合、PatternMatcher はその時点でループを停止します。(Android フレームワークの PatternMatcher.java を参照してください。)
元。string : "これは私の添付ファイルです" pattern : ". att. ". Android PatternMatcher はループに入って一致する '. ' pattern の次の文字 (この例では '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>
これは特に、カスタム ファイル拡張子と一致する場合に発生します。