Há muita desinformação sobre este assunto, principalmente da própria documentação do Google. O melhor, e dada a lógica estranha, possivelmente a única documentação real é o código-fonte.
A implementação do filtro de intenção tem uma lógica que quase desafia a descrição. O código do analisador é a outra peça relevante do quebra-cabeça.
Os filtros a seguir chegam muito perto de um comportamento sensato. Os padrões de caminho se aplicam, para intenções de esquema de "arquivo".
A correspondência de padrão de tipo MIME global corresponderá a todos os tipos, desde que a extensão do arquivo corresponda. Isso não é perfeito, mas é a única maneira de corresponder ao comportamento de gerenciadores de arquivos como o ES File Explorer, e é limitado a intenções em que o URI / extensão de arquivo corresponde.
Não incluí outros esquemas como "http" aqui, mas provavelmente funcionarão bem em todos esses filtros.
O esquema estranho é "conteúdo", para o qual a extensão não está disponível para o filtro. Mas, desde que o provedor indique seu tipo MIME (por exemplo, o Gmail passará o tipo MIME para o anexo sem impedimentos), o filtro corresponderá.
Tenho que estar ciente de:
- Esteja ciente de que nada se comporta de forma consistente nos filtros, é um labirinto de casos especais e trata a violação do princípio da menor surpresa como um objetivo de design. Nenhum dos algoritmos de correspondência de padrões segue a mesma sintaxe ou comportamento. A ausência de um campo às vezes é um caractere curinga e às vezes não é. Os atributos dentro de um elemento de dados às vezes devem estar juntos e às vezes ignorar o agrupamento. Realmente poderia ter sido feito melhor.
- O esquema E o host devem ser especificados para que as regras de caminho correspondam (ao contrário do guia de API do Google, atualmente).
- Pelo menos o ES File Explorer gera intents com um tipo MIME de "", que é filtrado de forma muito diferente para nulo, é impossível de corresponder explicitamente e só pode ser correspondido pelo filtro de risco "* / *".
- O filtro "* / *" NÃO corresponderá a Intents com um tipo MIME nulo - isso requer um filtro separado para este caso específico sem nenhum tipo MIME.
- O esquema de "conteúdo" só pode ser correspondido pelo tipo MIME, porque o nome do arquivo original não está disponível na intenção (pelo menos com o Gmail).
- O agrupamento de atributos em elementos de "dados" separados é (quase) irrelevante para a interpretação, com a exceção específica de host e porta - que são pareados. Todo o resto não tem associação específica dentro de um elemento de "dados" ou entre elementos de "dados".
Com tudo isso em mente, aqui está um exemplo com comentários:
<!--
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>