Aqui está como eu defini minha atividade em meu AndroidManifest.xml para fazer isso funcionar.
<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>
O scheme
de file
indica que isso deve acontecer quando um arquivo local é aberto (em vez de um protocolo como HTTP).
mimeType
pode ser definido para \*/\*
corresponder a qualquer tipo MIME.
pathPattern
é onde você especifica a extensão que deseja corresponder (neste exemplo .kdb
). O .*
no início corresponde a qualquer sequência de caracteres. Essas strings requerem escape duplo, portanto, \\\\.
corresponde a um período literal. Então, você termina com sua extensão de arquivo. Uma ressalva com pathPattern é que .*
não é uma correspondência gananciosa como você esperaria se fosse uma expressão regular. Este padrão não corresponderá aos caminhos que contêm um .
antes de .kdb
. Para uma discussão mais detalhada deste problema e uma solução alternativa, consulte aqui
Finalmente, de acordo com a documentação do Android, os atributos host
e scheme
são necessários para que o pathPattern
atributo funcione, então apenas defina-o como o caractere curinga para corresponder a qualquer coisa.
Agora, se você selecionar um .kdb
arquivo em um aplicativo como Linda File Manager, meu aplicativo aparecerá como uma opção. Devo observar que isso sozinho não permite que você baixe este tipo de arquivo em um navegador, uma vez que ele só é registrado no esquema de arquivo. Ter um aplicativo como o Linda File Manager em seu telefone resiste-se genericamente, permitindo que você baixe qualquer tipo de arquivo.
.kdbx
extensão para permitir que o ES explorer abrisse arquivos kdbx quando fui apontado para este post. Aparentemente, se o intent tiver um tipo MIME vazio, esse filtro de intent não funcionará !! Além disso, é possível ter um intent com uma string EMPTY como a ação e apenas um URI. O Google Docs respondeu a essa intenção, portanto, deve ser válida.<data>
tag com quatro atributos. Ter 4 tags é lógico OU - que funcionou com o Android 2 - mas o Android 4 é mais restrito. Consulte stackoverflow.com/questions/20650378/…\\\\.
corresponder a um período literal, por que você não o usa para formar uma.kdb
extensão como esta\\\\.kdb
:?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:
Com tudo isso em mente, aqui está um exemplo com comentários:
fonte
<data android:mimeType="*/*" />
em todas as três opções e funcionou perfeitamente para todos os aplicativos, incluindo Google Drive e Gmail.Devo admitir que a simples tarefa de abrir anexos de e-mails e arquivos do sistema de arquivos no Android foi uma das experiências mais enlouquecedoras de todos os tempos. É fácil lidar com muitos ou poucos arquivos. Mas acertar é difícil. A maioria das soluções postadas no stackoverflow não funcionou corretamente para mim.
Meus requisitos eram:
Provavelmente, a melhor maneira de realizar esta tarefa é especificar um tipo de MIME personalizado para seus anexos. E provavelmente você também escolherá uma extensão de arquivo personalizada. Então, digamos que nosso aplicativo se chama "Cool App" e geramos anexos de arquivo que têm ".cool" no final.
Este é o mais próximo que cheguei do meu objetivo e funciona ... satisfatório.
Notas:
pathPattern
parece ser mais ou menos ignorado para anexos (ao usarandroid:scheme="content"
). Se alguém fizer com que o pathPattern responda apenas a determinados padrões, ficaria entusiasmado em ver como.android:host="*"
atributo.intent-filter
blocos forem mesclados, mas eu não verifiquei isso.android:scheme="http"
pode ser usado. Observe que certos navegadores podem bagunçar o processo,android:mimeType
então experimenteandroid:mimeType="*/*"
e verifique no depurador o que realmente é passado e, em seguida, aperte a filtragem para não acabar sendo aquele aplicativo irritante que lida com tudo .intent-filter
foi testado com o aplicativo "Meus Arquivos" da Samsung em um Galaxy S3. O FX Explorer ainda se recusa a abrir o arquivo corretamente e também notei que o ícone do aplicativo não é usado para os arquivos. Novamente, se alguém fizer isso funcionar, comente abaixo.Espero que você ache isso útil e que não precise perder dias examinando todas as combinações possíveis. Há espaço para melhorias, portanto, comentários são bem-vindos.
fonte
android:label
filtro de intent é a string que o usuário verá no menu do seletor. Por padrão, o nome do aplicativo é usado.A resposta de Brian acima me levou a 90% do caminho até lá. Para finalizar, para o tipo mime usei
Suspeito que os pôsteres anteriores tentaram postar o mesmo detalhe, mas sem citar a estrela barra estrela como código, stackoverflow mostra isso apenas como uma barra.
fonte
Em vez de
android:path
tentarandroid:mimeType
, com um valor do tipo MIME desse conteúdo específico. Além disso,android:path
não aceita curingas - useandroid:pathPattern
para isso.fonte
Venho tentando fazer isso funcionar há muito tempo, tentei basicamente todas as soluções sugeridas e ainda não consigo fazer o Android reconhecer extensões de arquivo específicas. Eu tenho um filtro de intenção com um
"*/*"
tipo MIME que é a única coisa que parece funcionar e os navegadores de arquivos agora listam meu aplicativo como uma opção para abrir arquivos, no entanto, meu aplicativo agora é mostrado como uma opção para abrir QUALQUER TIPO de arquivo, embora Especifiquei extensões de arquivo específicas usando a tag pathPattern. Isso vai tão longe que, mesmo quando tento visualizar / editar um contato na minha lista de contatos, o Android me pergunta se eu quero usar meu aplicativo para visualizar o contato, e essa é apenas uma das muitas situações em que isso ocorre, MUITO MUITO irritante.Acabei encontrando esta postagem do Google Groups com uma pergunta semelhante à qual um engenheiro de estrutura Android real respondeu. Ela explica que o Android simplesmente não sabe nada sobre extensões de arquivo, apenas tipos MIME ( https://groups.google.com/forum/#!topic/android-developers/a7qsSl3vQq0 ).
Portanto, pelo que vi, experimentei e li, o Android simplesmente não consegue distinguir entre extensões de arquivo e a tag pathPattern é basicamente uma perda gigantesca de tempo e energia. Se você tiver a sorte de precisar apenas de arquivos de um certo tipo MIME (por exemplo, texto, vídeo ou áudio), você pode usar um filtro de intenção com um tipo MIME. Se você precisa de uma extensão de arquivo específica ou um tipo MIME não conhecido pelo Android, então você está sem sorte.
Se eu estiver errado sobre qualquer coisa, por favor me diga, até agora eu li todos os posts e tentei todas as soluções propostas que pude encontrar, mas nenhuma funcionou.
Eu poderia escrever mais uma ou duas páginas sobre como esse tipo de coisa parece comum no Android e como a experiência do desenvolvedor é complicada, mas vou poupar meus discursos furiosos;). Espero ter salvado alguém de alguns problemas.
fonte
A resposta de Brian é muito próxima, mas aqui está uma maneira limpa e sem erros de invocar seu aplicativo ao tentar abrir um arquivo com sua própria extensão personalizada (sem necessidade de esquema ou host):
fonte
<data>
tag com quatro atributos. Sua solução pode funcionar com Android 2 - mas as regras se tornaram mais rígidas: stackoverflow.com/questions/20650378/…host
escheme
são necessários!No Android 4, as regras tornaram-se mais rígidas do que costumavam ser. Usar:
fonte
Eu tenho lutado um pouco com isso para uma extensão de arquivo personalizada, eu mesmo. Depois de muita pesquisa, encontrei esta página da web onde o autor da postagem descobriu que a classe patternMatcher do Android (que é usada para a correspondência pathPattern em Intent-Filters) tem um comportamento inesperado quando seu caminho contém o primeiro caractere de seu padrão de correspondência em outro lugar no caminho (como se você estivesse tentando corresponder a "* .xyz", a classe patternMatcher para se houver um "x" no início do seu caminho). Aqui está o que ele encontrou para uma solução alternativa e funcionou para mim, embora seja um pouco um hack:
fonte
Nenhuma das opções acima funciona corretamente, para as ações VIEW ou SEND, se o sufixo não estiver registrado com um tipo MIME no banco de dados MIME system = wide do Android. As únicas configurações que descobri que disparam para o sufixo especificado incluem
android:mimeType="*/*"
, mas a ação dispara para TODOS os arquivos. Claramente NÃO é o que você quer!Não consigo encontrar nenhuma solução adequada sem adicionar o mime e o sufixo ao banco de dados mime do Android; até agora, não encontrei uma maneira de fazer isso. Se alguém souber, um ponteiro seria ótimo.
fonte
Quando um Intent atende a
intent-filter
, estes são osintent-filter
requisitos: (imagine uma lista de verificação).<action>
<category>
<data mimeType>
(solução fácil: " / ")Opcionalmente:
Qualquer correspondência
<data scheme>
(fácil correção:<data android:scheme="file" /> <data android:scheme="content" />
)Qualquer correspondência
<data host>
(solução fácil: "*")<data pathPattern/etc.>
(por exemplo.*\\.0cc
)A definição de vários
<data $type="">
elementos marca a caixa $ type se algum<data $type=>
corresponder aIntent
.A omissão de mimeType quebra o seu
intent-filter
, embora seja aparentemente redundante. A omissão<data scheme/host/pathPattern>
faz com que seu filtro corresponda a tudo.https://f-droid.org/en/packages/de.k3b.android.intentintercept/ é um aplicativo projetado para receber todos os intents e permite que você inspecione o intent. Aprendi que extensões de arquivo não reconhecidas abertas por meio do Simple File Manager são entregues com o tipo MIME
application/octet-stream
.https://stackoverflow.com/a/4621284/2683842 relata que
<data pathPattern=>
.*xyz
aborta no primeirox
que vê e falhará imediatamente se não for seguido poryz
. Portanto/sdcard/.hidden/foo.0cc
, não vai passar, a.*\\.0cc
menos que você tente.*\\..*\\.0cc
.Resultado final:
fonte
Se você deseja que os arquivos sejam abertos diretamente do Gmail, caixa de depósito ou qualquer uma das ferramentas de criação de arquivos Android, use o seguinte código (delete 'android: host = "*"' que tornou o arquivo inacessível para gmail):
O filtro de dados deve ser escrito em uma instrução conforme Android versão 4.x
fonte
Usando o filtro abaixo para abrir no navegador, gmail e navegador de arquivos (testado). NOTA: Por favor, não mescle dois filtros, isso fará com que o navegador ignore seu aplicativo (Testado).
fonte
Atualização 2020
O Android mudou para URIs de conteúdo e tipos MIME para filtros de intenção.
O problema
Um URI de conteúdo não precisa necessariamente conter a extensão ou nome do arquivo e será diferente entre os diferentes aplicativos que fornecem o conteúdo / arquivo.
Aqui estão alguns exemplos de URIs de conteúdo de diferentes aplicativos de e-mail para o mesmo anexo de 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
Aplicativo de e-mail Samsung ->
content://com.samsung.android.email.attachmentprovider/1/1/RAW
Como podemos ver, eles são todos diferentes e não há garantia de que contenham qualquer coisa relacionada ao seu arquivo real. Assim, você não pode usar o
android:pathPattern
que a maioria sugeriu.Uma solução alternativa para anexos de e-mail
Por meio de testes, encontrei os tipos MIME que o Gmail, Outlook e Samsung Email usaram e os adicionei ao meu filtro de intenção.
Advertências / pegadinhas
Descobri que, com a solução acima, se abrisse qualquer arquivo do tipo binário, meu aplicativo seria iniciado automaticamente. Eu lidei com isso em minha atividade exibindo um estado de falha se não pudéssemos analisar o arquivo. Achei que este era um evento muito raro, então seria aceitável.
Não consegui encontrar nenhuma maneira de iniciar meu aplicativo por meio do navegador de arquivos sem adicionar
<data android:mimeType="*/*"/>
ao meu filtro de intenção. Eu não poderia usar isso porque ele iniciaria meu aplicativo sempre que o usuário clicasse em qualquer arquivo em seu telefone (não apenas aqueles com extensão de arquivo personalizado). Eu não recomendaria adicionar isso ao seu filtro de intenção.Pensamentos finais
fonte