Así es como definí mi actividad en mi AndroidManifest.xml para que esto funcione.
<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>
El scheme
defile
indica que esto debería suceder cuando se abre un archivo local (en lugar de un protocolo como HTTP).
mimeType
se puede configurar para \*/\*
que coincida con cualquier tipo de mimo.
pathPattern
es donde especifica qué extensión desea hacer coincidir (en este ejemplo .kdb
). El .*
al principio coincide con cualquier secuencia de caracteres. Estas cadenas requieren un doble escape, por lo que \\\\.
coincide con un período literal. Luego, terminas con tu extensión de archivo. Una advertencia con pathPattern es que .*
no es una coincidencia codiciosa como cabría esperar si fuera una expresión regular. Este patrón no coincidirá con las rutas que contienen un .
antes de .kdb
. Para una discusión más detallada de este problema y una solución, consulte aquí
Finalmente, de acuerdo con la documentación de Android, se requieren ambos atributos host
y scheme
para elpathPattern
atributo funcione, así que configúrelo en el comodín para que coincida con cualquier cosa.
Ahora, si selecciona un .kdb
archivo en una aplicación como Linda File Manager, mi aplicación aparece como una opción. Debo señalar que esto por sí solo no le permite descargar este tipo de archivo en un navegador, ya que solo se registra con el esquema de archivo. Tener una aplicación como Linda File Manager en su teléfono se resiste genéricamente permitiéndole descargar cualquier tipo de archivo.
.kdbx
extensión para permitir que el explorador de archivos ES abra archivos kdbx cuando me señalaron esta publicación. Aparentemente, si la intención tiene un tipo MIME vacío, ¡este filtro de intención no funcionará! Además, es posible tener una intención con una cadena VACÍA como acción y solo un URI. Google Docs respondió a esa intención, por lo que debe ser válida.<data>
etiqueta con cuatro atributos. Tener 4 etiquetas es lógico O, que funcionó con Android 2, pero Android 4 es más estricto. Ver stackoverflow.com/questions/20650378/…\\\\.
coincide con un período literal, ¿por qué no lo usa para formar una.kdb
extensión como esta\\\\.kdb
:?Hay mucha desinformación sobre este tema, sobre todo de la propia documentación de Google. Lo mejor, y dada la extraña lógica, posiblemente la única documentación real sea el código fuente.
La implementación del filtro de intención tiene una lógica que casi desafía la descripción. El código del analizador es la otra pieza relevante del rompecabezas.
Los siguientes filtros se acercan bastante al comportamiento sensato. Los patrones de ruta se aplican para las intenciones de esquema de "archivo".
La coincidencia de patrón de tipo de mimo global coincidirá con todos los tipos siempre que la extensión del archivo coincida. Esto no es perfecto, pero es la única forma de coincidir con el comportamiento de administradores de archivos como ES File Explorer, y se limita a las intenciones en las que coincide la extensión de archivo / URI.
No he incluido otros esquemas como "http" aquí, pero probablemente funcionarán bien en todos estos filtros.
El esquema extraño es "contenido", para el cual la extensión no está disponible para el filtro. Pero siempre que el proveedor indique su tipo de MIME (por ejemplo, Gmail transmitirá el tipo de MIME para el archivo adjunto sin obstáculos), el filtro coincidirá.
Puntos a tener en cuenta:
Con todo esto en mente, aquí hay un ejemplo con comentarios:
fuente
<data android:mimeType="*/*" />
en las tres opciones y funcionó a la perfección para todas las aplicaciones, incluidas Google Drive y Gmail.Debo admitir que la simple tarea de abrir archivos adjuntos de correos electrónicos y archivos del sistema de archivos en Android ha sido una de las experiencias más enloquecedoras. Es fácil manejar demasiados archivos o muy pocos. Pero hacerlo bien es difícil. La mayoría de las soluciones publicadas en stackoverflow no funcionaron correctamente para mí.
Mis requisitos eran:
Probablemente la mejor manera de realizar esta tarea es especificar un tipo MIME personalizado para sus archivos adjuntos. Y probablemente también optará por tener una extensión de archivo personalizada. Entonces, digamos que nuestra aplicación se llama "Cool App" y generamos archivos adjuntos que tienen ".cool" al final.
Esto es lo más cerca que estuve de mi objetivo y funciona ... satisfactorio.
Notas:
pathPattern
parece ser más o menos ignorado para los archivos adjuntos (cuando se utilizaandroid:scheme="content"
). Si alguien consigue que pathPattern responda solo a ciertos patrones, me encantaría ver cómo.android:host="*"
atributo.intent-filter
bloques se combinan, pero no lo he verificado.android:scheme="http"
se puede utilizar. Tenga en cuenta que ciertos navegadores pueden estropear el proceso,android:mimeType
así que experimenteandroid:mimeType="*/*"
y verifique en el depurador lo que realmente se transmite y luego ajuste el filtrado para no terminar siendo esa aplicación molesta que maneja todo .intent-filter
se probó con la aplicación "Mis archivos" de Samsung en un Galaxy S3. El FX Explorer todavía se niega a abrir correctamente el archivo y también noté que el ícono de la aplicación no se usa para los archivos. Nuevamente, si alguien logra que eso funcione, comente a continuación.Espero que esto le resulte útil y que no tenga que perder días revisando todas las combinaciones posibles. Hay margen de mejora, por lo que los comentarios son bienvenidos.
fuente
android:label
filtro de intención es la cadena que el usuario verá en el menú del selector. Por defecto, se utiliza el nombre de la aplicación.La respuesta de Brian arriba me llevó al 90% del camino. Para terminar, para el tipo de mimo usé
Sospecho que los carteles anteriores han intentado publicar el mismo detalle, pero sin citar la estrella de barra inclinada como código, stackoverflow lo muestra como una barra inclinada.
fuente
En lugar de
android:path
intentarloandroid:mimeType
, con un valor del tipo MIME de este contenido en particular. Además,android:path
no acepta comodines; utilíceloandroid:pathPattern
para eso.fuente
He intentado que esto funcione durante años y he probado básicamente todas las soluciones sugeridas y todavía no puedo hacer que Android reconozca extensiones de archivo específicas. Tengo un filtro de intención con un tipo
"*/*"
MIME que es lo único que parece funcionar y los navegadores de archivos ahora enumeran mi aplicación como una opción para abrir archivos, sin embargo, mi aplicación ahora se muestra como una opción para abrir CUALQUIER TIPO de archivo aunque He especificado extensiones de archivo específicas usando la etiqueta pathPattern. Esto va tan lejos que incluso cuando intento ver / editar un contacto en mi lista de contactos, Android me pregunta si quiero usar mi aplicación para ver el contacto, y esa es solo una de las muchas situaciones en las que esto ocurre, MUY MUY molesto.Finalmente encontré esta publicación de grupos de Google con una pregunta similar a la que respondió un ingeniero de marco de Android real. Ella explica que Android simplemente no sabe nada sobre extensiones de archivo, solo tipos MIME ( https://groups.google.com/forum/#!topic/android-developers/a7qsSl3vQq0 ).
Entonces, por lo que he visto, probado y leído, Android simplemente no puede distinguir entre extensiones de archivo y la etiqueta pathPattern es básicamente una pérdida gigantesca de tiempo y energía. Si tiene la suerte de que solo necesite archivos de cierto tipo de mímica (por ejemplo, texto, video o audio), puede utilizar un filtro de intención con un tipo de mímica. Sin embargo, si necesita una extensión de archivo específica o un tipo de mímica que Android no conoce, no tiene suerte.
Si me equivoco en algo de esto, por favor dígame, hasta ahora he leído todas las publicaciones y he probado todas las soluciones propuestas que pude encontrar, pero ninguna ha funcionado.
Podría escribir una o dos páginas más sobre lo común que parecen ser este tipo de cosas en Android y lo jodida que es la experiencia del desarrollador, pero te ahorraré mis desvaríos;). Espero haberle ahorrado algunos problemas a alguien.
fuente
La respuesta de Brian es muy cercana, pero aquí hay una forma limpia y sin errores de invocar su aplicación al intentar abrir un archivo con su propia extensión personalizada (sin necesidad de esquema o host):
fuente
<data>
etiqueta con cuatro atributos. Su solución puede funcionar con Android 2, pero las reglas se han vuelto más estrictas: stackoverflow.com/questions/20650378/…host
yscheme
son obligatorios!En Android 4, las reglas se volvieron más estrictas de lo que solían ser. Utilizar:
fuente
Yo mismo he estado luchando bastante con esto para obtener una extensión de archivo personalizada. Después de mucha búsqueda, encontré esta página web donde el cartel descubrió que la clase patternMatcher de Android (que se usa para la coincidencia de pathPattern en Intent-Filters) tiene un comportamiento inesperado cuando su ruta contiene el primer carácter de su patrón de coincidencia en otra parte de la ruta (como si estuviera intentando hacer coincidir "* .xyz", la clase patternMatcher se detiene si hay una "x" antes en su ruta). Esto es lo que encontró como solución alternativa y funcionó para mí, aunque es un truco:
fuente
Ninguno de los anteriores funciona correctamente, para las acciones VER o ENVIAR, si el sufijo no está registrado con un tipo MIME en el sistema de Android = base de datos MIME amplia. La única configuración que he encontrado que se activa para el sufijo especificado incluye
android:mimeType="*/*"
, pero luego la acción se activa para TODOS los archivos. ¡Claramente NO es lo que quieres!No puedo encontrar ninguna solución adecuada sin agregar el mime y el sufijo a la base de datos de mime de Android, hasta ahora, no he encontrado una manera de hacerlo. Si alguien lo sabe, un puntero sería fantástico.
fuente
Cuando un Intent cumple con un
intent-filter
, estos son losintent-filter
requisitos: (imagine una lista de verificación).<action>
<category>
<data mimeType>
(solución fácil: " / ")Opcionalmente:
Cualquier coincidencia
<data scheme>
(solución fácil:<data android:scheme="file" /> <data android:scheme="content" />
)Cualquier coincidencia
<data host>
(solución fácil: "*")<data pathPattern/etc.>
(por ejemplo.*\\.0cc
)La definición de varios
<data $type="">
elementos marca la casilla $ type si alguna<data $type=>
coincide conIntent
.Omitir mimeType rompe tu
intent-filter
, aunque aparentemente es redundante. Omitir<data scheme/host/pathPattern>
hace que su filtro coincida con todo.https://f-droid.org/en/packages/de.k3b.android.intentintercept/ es una aplicación diseñada para recibir todas las intenciones y le permite inspeccionar la intención. Aprendí que las extensiones de archivo no reconocidas que se abren a través de Simple File Manager se entregan con el tipo MIME
application/octet-stream
.https://stackoverflow.com/a/4621284/2683842 informa que se
<data pathPattern=>
.*xyz
cancela a la primerax
que ve, y fallará inmediatamente si no lo sigueyz
. Así/sdcard/.hidden/foo.0cc
que no pasará a.*\\.0cc
menos que lo intentes.*\\..*\\.0cc
.Resultado final:
fuente
Si desea que los archivos se abran directamente desde Gmail, Dropbox o cualquiera de las herramientas de archivo de Android integradas, utilice el siguiente código (elimine 'android: host = "*"' que hizo que el archivo no fuera accesible para Gmail):
El filtro de datos debe estar escrito en una declaración según la versión 4.x de Android
fuente
Usando el filtro como se muestra a continuación para abrir desde el navegador, gmail y el navegador de archivos (probado). NOTA: No combine dos filtros, eso hará que el navegador ignore su aplicación (probado).
fuente
Actualización 2020
Android se ha movido hacia URI de contenido y tipos MIME para filtros de intención.
El problema
Un URI de contenido no necesariamente tiene que contener la extensión o el nombre del archivo y será diferente entre las diferentes aplicaciones que proporcionan el contenido / archivo.
A continuación, se muestran algunos ejemplos de URI de contenido de diferentes aplicaciones de correo electrónico para el mismo archivo adjunto de correo electrónico:
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
Aplicación de correo electrónico de Samsung ->
content://com.samsung.android.email.attachmentprovider/1/1/RAW
Como puede ver, todos son diferentes y no se garantiza que contengan nada relacionado con su archivo real. Por lo tanto, no puede usar lo que la
android:pathPattern
mayoría ha sugerido.Una solución alternativa para archivos adjuntos de correo electrónico
A través de las pruebas, encontré los tipos MIME que usaban Gmail, Outlook y Samsung Email y los agregué a mi filtro de intención.
Advertencias / errores
Descubrí que con mi solución anterior, si abría cualquier archivo que fuera de tipo binario, automáticamente iniciaría mi aplicación. Manejé esto en mi actividad mostrando un estado fallido si no podíamos analizar el archivo. Pensé que este era un evento bastante raro, por lo que sería aceptable.
No pude encontrar ninguna forma de iniciar mi aplicación a través del navegador de archivos sin agregar
<data android:mimeType="*/*"/>
a mi filtro de intención. No pude usar esto porque luego iniciaría mi aplicación cada vez que el usuario hiciera clic en cualquier archivo en su teléfono (no solo en los de extensión de archivo personalizado). No recomendaría agregar esto a su filtro de intención.Pensamientos finales
fuente