wma tipo reproductor reproducir programa para opus incompatible extensiones este archivos archivo admite abrir android android-intent android-manifest

tipo - Filtro de intención de Android para una extensión de archivo en particular?



reproducir wma en android (12)

Quiero poder descargar un archivo con una extensión particular de la red y hacer que pase a mi aplicación para tratarlo, pero no he podido descifrar el filtro de intención. El tipo de archivo no está incluido en los tipos mimet, y traté de usar

<data android:path="*.ext" />

pero no pude hacer que eso funcione.


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 del file indica que esto debería suceder cuando se abre un archivo local (en lugar de un protocolo como HTTP).

mimeType se puede establecer en /*//* para que coincida con cualquier tipo de mimo.

pathPattern es donde especificas qué extensión deseas .kdb (en este ejemplo, .kdb ). El .* Al principio coincide con cualquier secuencia de caracteres. Estas cadenas requieren un doble escape, entonces ////. coincide con un período literal. Entonces, terminas con tu extensión de archivo. Una advertencia con pathPattern es que .* No es una coincidencia ambiciosa como se esperaría si esta fuera una expresión regular. Este patrón no coincidirá con las rutas que contienen a . antes del .kdb . Para una discusión más detallada de este problema y una solución, vea here

Finalmente, de acuerdo con la documentación de Android, se requieren atributos tanto del host como del scheme para que pathPattern atributo pathPattern , así que simplemente pathPattern para que coincida con cualquier cosa.

Ahora, si selecciona un archivo .kdb en una aplicación como Linda File Manager, mi aplicación aparecerá como una opción. Debo señalar que esto solo no le permite descargar este tipo de archivo en un navegador, ya que esto solo se registra con el esquema de archivo. Tener una aplicación como Linda File Manager en su teléfono se resiste genéricamente, lo que le permite descargar cualquier tipo de archivo.


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 de la historia. Es fácil manejar demasiados archivos o muy pocos. Pero hacerlo bien es difícil. La mayoría de las soluciones publicadas en no funcionaron correctamente para mí.

Mis requisitos fueron:

  • hacer que mi aplicación maneje los archivos adjuntos compartidos por mi aplicación
  • hacer que mi aplicación maneje los archivos almacenados en los archivos generados por mi aplicación y tener una extensión particular

Probablemente la mejor manera de llevar a cabo esta tarea es especificar un tipo MIME personalizado para sus archivos adjuntos. Y probablemente también elija 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 llegué a mi objetivo y funciona ... satisfactorio.

<!-- 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>

Notas:

  • El pathPattern parece ser más o menos ignorado por los archivos adjuntos (cuando se usa android:scheme="content" ). Si alguien consigue que pathPattern responda solo a ciertos patrones, me encantaría ver cómo.
  • La aplicación Gmail se negó a mostrar mi aplicación en el selector si agregué el atributo android:host="*" .
  • Probablemente todavía funcione si estos bloques de intent-filter se combinan pero no he verificado esto.
  • Para manejar las solicitudes de un navegador al descargar un archivo, se puede usar el android:scheme="http" . Tenga en cuenta que ciertos navegadores pueden estropear el android:mimeType así que experimente con android:mimeType="*/*" y verifique en el depurador lo que realmente pasa y luego ajuste el filtro para no terminar siendo esa aplicación molesta que maneja todo .
  • Ciertos Exploradores de archivos también estropearán los tipos MIME para sus archivos. El intent-filter anterior se probó con la aplicación "Mis archivos" de Samsung en un Galaxy S3. FX Explorer todavía se niega a abrir el archivo correctamente y también noté que el ícono de la aplicación no se usa para los archivos. Nuevamente, si alguien consigue que trabaje, por favor comente a continuación.

Espero que esto te resulte útil y que no tendrás que perder días examinando todas las combinaciones posibles. Hay margen de mejora, por lo que los comentarios son bienvenidos.


En Android 4 las reglas se volvieron más estrictas de lo que solían ser. Utilizar:

<data android:host="" android:mimeType="*/*" android:pathPattern=".*//.ext" android:scheme="file" ></data>


En lugar de android:path , prueba android:mimeType , con un valor del tipo MIME de esta pieza de contenido en particular. Además, android:path no acepta comodines - use android:pathPattern para eso.


Hay mucha desinformación sobre este tema, especialmente desde la propia documentación de Google. Lo mejor, y dada la extraña lógica, posiblemente la única documentación real es 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 intentos de esquema de "archivo".

La coincidencia de patrón de tipo MIME global coincidirá con todos los tipos siempre que la extensión de archivo coincida. Esto no es perfecto, pero es la única forma de hacer coincidir el comportamiento de los administradores de archivos, como ES File Explorer, y está limitado a los intentos en los que coincida la extensión de URI / archivo.

No he incluido otros esquemas como "http" aquí, pero probablemente funcionen 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 MIME (por ejemplo, Gmail transmitirá el tipo MIME para el archivo adjunto sin impedimentos), el filtro coincidirá.

Cosas que debes tener en cuenta:

  1. Tenga en cuenta que nada se comporta de manera consistente en los filtros, es un laberinto de casos especiales y trata la violación del principio de menor sorpresa como un objetivo de diseño. Ninguno de los algoritmos de coincidencia de patrones sigue la misma sintaxis o comportamiento. La ausencia de un campo a veces es un comodín y otras no. Los atributos dentro de un elemento de datos a veces deben ir juntos y, a veces, ignorar la agrupación. Realmente podría haberse hecho mejor.
  2. El esquema Y el host se deben especificar para que coincidan las reglas de ruta (contrariamente a la guía API de Google, actualmente).
  3. Al menos, ES File Explorer genera intentos con un tipo MIME de "", que se filtra de manera muy diferente a nulo, es imposible hacer coincidir de forma explícita y solo puede coincidir con el arriesgado filtro "* / *".
  4. El filtro "* / *" NO coincidirá con Intents con un tipo MIME nulo, que requiere un filtro separado para este caso específico sin ningún tipo de MIME.
  5. El esquema de "contenido" solo puede coincidir con el tipo MIME, porque el nombre del archivo original no está disponible en el intento (al menos con Gmail).
  6. La agrupación de atributos en elementos de "datos" separados es (casi) irrelevante para la interpretación, con la excepción específica de host y puerto, que se emparejan. Todo lo demás no tiene una asociación específica dentro de un elemento de "datos" o entre elementos de "datos".

Con todo esto en mente, he aquí un ejemplo con comentarios:

<!-- 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>


He estado luchando con esto bastante para una extensión de archivo personalizado, yo mismo. Después de buscar mucho, encontré esta página web donde el póster descubrió que la clase patternMatcher de Android (que se utiliza para la coincidencia PathPattern en Intent-Filters) tiene un comportamiento inesperado cuando tu ruta contiene el primer carácter de tu patrón de coincidencia en otra parte de la ruta (Por ejemplo, si intenta hacer coincidir "* .xyz", la clase patternMatcher se detiene si hay una "x" anteriormente en su ruta). Esto es lo que encontró para una solución alternativa, y funcionó para mí, aunque es un poco complicado:

PatternMatcher se usa para pathPattern en IntentFilter Pero, el algoritmo de PatternMatcher es bastante extraño para mí. Aquí está el algoritmo de Android PatternMatcher.

Si hay un ''siguiente carácter'' del patrón ''. *'' En el medio de la cadena, PatternMatcher detiene el ciclo en ese punto. (Ver PatternMatcher.java de Android framework.)

Ex. cadena: patrón "este es un archivo adjunto": ". att ". Android PatternMatcher ingresa el bucle para que coincida ''. ''patrón hasta cumplir con el siguiente carácter de patrón (en este ejemplo,'' a '') Entonces,''. ''el lazo correspondiente se detiene en el índice 8 -'' a ''entre'' es ''y'' mi ''. Por lo tanto, el resultado de este partido devuelve ''falso''.

Muy extraño, ¿verdad? Para solucionar esto, reduzca la posibilidad de que el desarrollador use un pathPattern estúpido y molesto.

Ex. Objetivo: hacer coincidir la ruta uri que incluye ''mensaje''.

<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>

Esto se emite especialmente cuando se combina con la extensión de archivo personalizado.


He intentado hacer que esto funcione durante años y he intentado básicamente todas las soluciones sugeridas y todavía no logro que Android reconozca las extensiones de archivos específicas. Tengo un filtro de intención con un tipo de letra "*/*" que es lo único que parece funcionar y los navegadores de archivos ahora muestran mi aplicación como una opción para abrir archivos. Sin embargo, ahora mi aplicación se muestra como una opción para abrir CUALQUIER Tipo de archivo aunque he especificado extensiones de archivo específicas utilizando la etiqueta pathPattern. Esto va tan lejos que, incluso cuando trato de 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 muchas situaciones donde ocurre esto, MUY MUY molesto.

Eventualmente encontré esta publicación de Google Groups con una pregunta similar a la que respondió un ingeniero de framework de Android. Ella explica que Android simplemente no sabe nada sobre las extensiones de archivos, solo los tipos MIME ( https://groups.google.com/forum/#!topic/android-developers/a7qsSl3vQq0 ).

Por lo que he visto, probado y leído, Android simplemente no puede distinguir entre las extensiones de archivos y la etiqueta pathPattern es básicamente una gran pérdida de tiempo y energía. Si tiene la suerte de que solo necesita archivos de un cierto tipo de mime (por ejemplo, texto, video o audio), puede usar un filtro de intención con un tipo mime. Si necesita una extensión de archivo específica o un tipo de mimo desconocido para Android, entonces no tiene suerte.

Si me equivoco sobre algo de esto, por favor díganme, hasta ahora he leído todas las publicaciones e intenté todas las soluciones propuestas que pude encontrar, pero ninguna ha funcionado.

Podría escribir una o dos páginas más acerca de cuán común es este tipo de cosas en Android y qué tan jodida es la experiencia del desarrollador, pero te ahorraré mis enojos y desvaríos;). Espero haber salvado a alguien algunos problemas.


La respuesta de Brian anterior me dio el 90% del camino allí. Para terminar, para el tipo de mimo que utilicé

android:mimeType="*/*"

Sospecho que los carteles anteriores han intentado publicar el mismo detalle, pero el hecho de citar a la estrella estrella como código, lo muestra como una barra.


La respuesta de Brian es muy cercana, pero aquí hay una manera limpia y libre de errores de invocar su aplicación cuando intenta abrir un archivo con su propia extensión personalizada (sin necesidad de esquema o host):

<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>


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 = amplia base de datos MIME. Las únicas configuraciones que encontré que disparan para el sufijo especificado incluyen android:mimeType="*/*" , pero luego la acción se dispara para TODOS los archivos. Claramente NO lo que quieres!

No puedo encontrar ninguna solución adecuada sin agregar el mimo y el sufijo a la base de datos mime de Android, hasta ahora, no he encontrado una manera de hacerlo. Si alguien sabe, un puntero sería genial.


Si desea que los archivos se abran directamente desde Gmail, Dropbox o cualquiera de las herramientas de creación de archivos de Android, utilice el siguiente código (delete ''android: host = "*"'' que hace que el archivo no sea accesible para gmail):

<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>

El filtro de datos debe escribirse en una declaración según la versión de Android 4.x


Usando el filtro de la siguiente manera para abrir desde el navegador, gmail y el buscador de archivos (Probado). NOTA: no combine dos filtros, que harán que el navegador ignore su aplicación (Probado).

<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>