Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Filtro de intenciones de Android para una extensión de archivo en particular?

Quiero ser capaz de descargar un archivo con una extensión en particular de la red, y lo han pasado a mi aplicación para tratar con él, pero no he sido capaz de averiguar el filtro de intención. El tipo de archivo no está incluido en el mimetypes, y he intentado usar

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

Pero no pude conseguir que funcione.

  • Establecer el nombre de la aplicación en la etiqueta de la aplicación no funciona
  • Deshabilitar permisos de dependencia
  • ¿Cómo agregar atributos de varios temas a la misma actividad en el manifiesto de Android?
  • External AndroidManifest.xml no aparece en el panel de vista del proyecto
  • ¿Agregar actividad automáticamente a Manifest?
  • Pantalla de llamadas entrantes / salientes personalizadas en Android
  • ¿Qué sucede si la minSdkVersion es menor que la targetSdkVersion?
  • AdjustPan no impide que el teclado cubra EditText
  • 13 Solutions collect form web for “Filtro de intenciones de Android para una extensión de archivo en particular?”

    Aquí es cómo 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 de 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 mime.

    pathPattern es donde se especifica la extensión que desea coincidir (en este ejemplo .kdb ). El .* Al principio coincide con cualquier escaso de caracteres. Estas cadenas requieren doble escape, por lo que \\\\. Coincide con un período literal. A continuación, termina con la extensión de archivo. Una advertencia con pathPattern es que .* No es un combate codicioso como se esperaría si se tratara de una expresión regular. Este patrón no coincidirá con las rutas que contienen a . Antes de la .kdb . Para una discusión más detallada de este problema y una solución ver aquí

    Por último, de acuerdo con la documentación de Android, tanto el host como los atributos de scheme son necesarios para que el atributo pathPattern funcione, por lo que sólo tiene que establecer el comodín para que coincida con cualquier cosa.

    Ahora, si selecciona un archivo .kdb en una aplicación como Linda File Manager, mi aplicación aparece como una opción. Debo tener en cuenta que esto por sí solo no le permite descargar este tipo de archivo en un navegador, ya que sólo se registra con el esquema de archivos. Tener una aplicación como Linda File Manager en su teléfono se resiste genéricamente permitiéndole 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 stackoverflow no funcionaron correctamente para mí.

    Mis requisitos eran:

    • Tener mi aplicación manejar archivos adjuntos compartidos por mi aplicación
    • Tener mi app manejar archivos en filestorage que fueron generados por mi aplicación y tienen una extensión en particular

    Probablemente la mejor manera de realizar esta tarea es especificar un tipo MIME personalizado para sus archivos adjuntos. Y probablemente también elija tener una extensión de archivo personalizada. Así que digamos que nuestra aplicación se llama "Cool App" y generamos archivos adjuntos que tienen ". Cool" al final.

    Este es el más cercano que llegué a mi meta 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 para los archivos adjuntos (cuando se utiliza android:scheme="content" ). Si alguien obtiene el pathPattern para responder sólo a ciertos patrones, estaría encantado de ver cómo.
    • La aplicación de Gmail se negó a incluir mi aplicación en el selector si agregaba el atributo android:host="*" .
    • Es probable que todavía funciona si estos bloques de intent-filter se fusionan, pero no he verificado esto.
    • Para manejar las peticiones de un navegador al descargar un archivo, se puede usar el android:scheme="http" . Tenga en cuenta que algunos navegadores pueden estropear el android:mimeType para experimentar con android:mimeType="*/*" y comprobar en el depurador lo que realmente pasa a través y luego apriete el filtrado para no acabar siendo esa aplicación molesto que maneja todo .
    • Ciertos exploradores de archivos se ensucian los MIME-Tipos para sus archivos también. El intent-filter se probó con la aplicación "My Files" de Samsung en un Galaxy S3. El FX Explorer todavía se niega a abrir correctamente el archivo y también noté que el icono de la aplicación no se utiliza para los archivos. Una vez más, si alguien consigue que el trabajo por favor comente a continuación.

    Espero que encuentre esto útil y que no tendrá que perder días pasando por todas las combinaciones posibles. Hay margen de mejora para que los comentarios sean bienvenidos.

    La respuesta de Brian me consiguió el 90% del camino. Para terminar, para el tipo mime que usé

     android:mimeType="*/*" 

    Sospecho que los carteles anteriores han intentado publicar el mismo detalle, pero el qoting bastante la estrella del slash de la estrella como código, stackoverflow los diplays él como apenas un slash.

    Hay un montón de información errónea sobre este tema, no menos de 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 intenciones tiene 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 sensible. Los patrones de ruta se aplican, para intentos de esquema "file".

    La coincidencia de patrón de tipo mime global coincidirá con todos los tipos siempre y cuando coincida con la extensión de archivo. Esto no es perfecto, pero es la única manera de igualar el comportamiento de los gestores de archivos como ES File Explorer, y se limita a las intenciones donde coincide la extensión de URI / archivo.

    No he incluido otros esquemas como "http" aquí, pero probablemente funcionarán bien en todos estos filtros.

    El esquema impar es "content", para el cual la extensión no está disponible para el filtro. Pero mientras el proveedor indique su tipo MIME (por ejemplo, Gmail pasará el tipo MIME para el archivo adjunto sin impedimentos), el filtro coincidirá.

    Tienes que tener en cuenta:

    1. Tenga en cuenta que nada se comporta de manera consistente en los filtros, es un laberinto de casos specal, y trata la violación del principio de menor sorpresa como un objetivo de diseño. Ninguno de los algoritmos de concordancia de patrones sigue la misma sintaxis o comportamiento. La ausencia de un campo a veces es un comodín ya veces no lo es. Los atributos dentro de un elemento de datos a veces deben ir juntos ya veces ignorar el agrupamiento. Realmente podría haber sido mejor.
    2. Se debe especificar el esquema Y el host para que las reglas de ruta coincidan (en contraposición a la guía de API de Google, actualmente).
    3. Por lo menos ES File Explorer genera intenciones con un tipo MIME de "", que se filtra muy diferente a null, es imposible coincidir de forma explícita, y sólo puede ser igualado por el arriesgado "* / *" filtro.
    4. El filtro "* / *" NO coincidirá con INTENTOS 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" sólo puede coincidir con el tipo MIME, ya que el nombre del archivo original no está disponible en la intención (al menos con Gmail).
    6. El agrupamiento de atributos en elementos separados de "datos" es (casi) irrelevante para la interpretación, con la excepción específica de host y puerto – que se emparejan entre sí. Todo lo demás no tiene una asociación específica dentro de un elemento "datos" o entre elementos "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> 

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

    La respuesta de Brian es muy cercana, pero aquí hay una manera limpia y sin errores para que tu aplicación sea invocada al intentar abrir un archivo con tu propia extensión personalizada (no necesitas esquema ni 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> 

    En Android 4 las reglas se volvieron más estrictas que antes. Utilizar:

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

    Usted probablemente no puede hacerlo en todo el sistema, porque Android no es compatible con eso. Puede hacerlo para aplicaciones específicas como el cliente de correo de Google o el navegador de Google.

    Busque más información sobre alquiler: http://www.mail-archive.com/android-developers@googlegroups.com/msg47862.html

    Vi código para agregar soporte para APKs en el cliente de correo (para instalarlos en lugar de guardarlos), pero por desgracia no puedo encontrarlo ahora.

    Ninguno de los anteriores funciona correctamente, para las acciones VIEW o SEND, si el sufijo no está registrado con un tipo MIME en el sistema de Android = base de datos MIME amplia. Los únicos ajustes que he encontrado que el fuego para el sufijo especificado incluyen android:mimeType="*/*" , pero entonces la acción se dispara 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 Android, hasta ahora, no he encontrado una manera de hacerlo. Si alguien sabe, un puntero sería fenomenal.

    Si desea que los archivos se abran directamente desde Gmail, dropbox o cualquiera de las herramientas de archivo buildin android, utilice el siguiente código (elimine 'android: host = "*"' que hizo que el archivo no estuviera disponible 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 sentencia según la versión 4.x de Android

    He estado luchando con esto bastante para una extensión de archivo personalizada, yo mismo. Después de un montón de búsqueda, encontré esta página web donde el cartel descubrió que la clase patternMatcher de Android (que se usa para la coincidencia pathPattern en Intent-Filters) tiene un comportamiento inesperado cuando su ruta contiene el primer carácter de su patrón de coincidencia en otro lugar de la ruta (Como si intentas igualar "* .xyz", la clase patternMatcher se detiene si hay una "x" en tu camino). Esto es lo que encontró para una solución, y trabajó para mí, aunque es un poco de un hack:

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

    Si hay "siguiente carácter" del patrón ". *" En el centro de la cadena, PatternMatcher detiene el bucle en ese punto. (Consulte PatternMatcher.java del framework de Android.)

    Ex. String: "este es un archivo adjunto" patrón: ". Att. ". Android PatternMatcher introduce el bucle para que coincida con '. 'Hasta que encuentre el siguiente carácter de patrón (en este ejemplo,' a ') Así que,'. 'El bucle coincidente se detiene en el índice 8 -' a 'entre' is 'y' my '. Por lo tanto, el resultado de esta coincidencia devuelve 'false'.

    Muy extraño, ¿no es así? Para solucionar esto – en realidad reducir la posibilidad – desarrollador debe utilizar molesto pathPattern estúpido.

    Ex. Meta: Emparejar el camino 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 compara con la extensión de archivo personalizada.

    Utilizando el filtro como se muestra a continuación para abrir desde el navegador, Gmail y el explorador de archivos (Probado). NOTA: No combine dos filtros, que harán que el navegador no haga caso de 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> 

    He estado tratando de conseguir que esto funcione durante años y han intentado básicamente todas las soluciones sugeridas y todavía no puede conseguir Android para reconocer extensiones de archivos específicos. Tengo un filtro de intención con un " / " ("asterisco / asterisco", los asteriscos no mostrarán por alguna razón) el tipo mimetype que es lo único que parece funcionar y los navegadores de archivos ahora listan mi aplicación como una opción para abrir archivos , Sin embargo mi aplicación se muestra ahora como una opción para abrir cualquier tipo de archivo a pesar de que he especificado extensiones de archivo específico mediante la etiqueta pathPattern. Esto va tan lejos que incluso cuando intento ver / corregir un contacto en mi lista de contactos Android me pregunta si quiero utilizar mi app para ver el contacto, y ése es apenas una de muchas situaciones donde esto ocurre, MUY MUY molesto.

    Eventualmente, encontré este grupo de google post con una pregunta similar a la que un ingeniero de framework Android real respondió. Ella explica que android simplemente no sabe nada acerca de las extensiones de archivo, solo MIME-types ( https://groups.google.com/forum/#!topic/android-developers/a7qsSl3vQq0 ).

    Así que por lo que he visto, probado y leído, Android simplemente no puede distinguir entre las extensiones de archivo y la etiqueta pathPattern es básicamente una gigantesca pérdida de tiempo y energía. Si tienes la suerte de solo necesitar archivos de cierto tipo mime (diga texto, video o audio), puedes usar un filtro de intenciones con un tipo mime. Si necesitas una extensión de archivo específica o un tipo de mime desconocido por Android sin embargo, entonces no tienes suerte.

    Si estoy equivocado acerca de esto, por favor dígame, hasta ahora he leído cada post y he probado todas las soluciones propuestas que pude encontrar pero ninguna ha funcionado.

    Podría escribir otra página o dos sobre cómo común este tipo de cosas parecen estar en Android y cómo estropeó la experiencia del desarrollador es, pero te ahorraré mis enojados rantings;). Espero haber salvado a alguien algún problema.

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.