Android intent filter - android

I have written the below intent filter to open a text file using my app. It seems to work but only sometimes. For example, if I email a text file, if I choose open from mail, my app is not shown. If I choose save first, then open, my app will be shown. Similar experience with drop box, if I try to open from drop box, my app won't be listed as being able to open but if I export from drop box to sd and use a file manager to open it, my app is listed and works.
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</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=".*\\.txt" />
<data android:scheme="https" android:host="*" android:pathPattern=".*\\.txt" />
<!-- <data android:scheme="content" android:host="*" android:pathPattern=".*\\.txt" /> -->
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.txt" />
</intent-filter>

Dropbox and the Email app probably use content providers and don't match the pathPattern. Typically content providers don't include a file extension, but would use the mime type to indicate what type of file is being opened. If you are intending to open any text/plain file, and not necessarily only those which have the .txt extension, then you'd be better off leaving the pathPattern off altogether.
<intent-filter>
<data android:mimeType="text/plain" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>

Probably beacuse the email app and dropbox uses a different scheme instead of file, http, or https. Try using the mime type attribute only.
EDIT: Acording to the dropbox forums:
FYI, the easiest way to do this now is to open up your app from Dropbox by registering for VIEW with the correct mime-type. Then everything is handed off properly, and saving & watching file changes to re-upload is handled well.
You only have to specify the mime type, and nothing else. I haven't tried this though, but probably this works for the email app as well, as long as the mime types match.
Here is the link if you are interested:
https://forums.dropbox.com/topic.php?id=26035#post-162963

Related

How to add application to the "open from" menu

I'm making a custom application and I need to enable it to use it as a file picker (like Drive, and Fotografias, Solid Explorer in the attached screenshot)
I want to open one of my app activities in order to use it as a custom signature pad
My plan is to allow the user to sign and that whould be returned to the file input of the caller application
Currently I have a deeplink that allows me to open the signature activity, the signature is saved in the filesystem of the phone, and after that the user has to use the file explorer to select the signature
Use Intent-filter for this purpose:
Read here: https://developer.android.com/guide/components/intents-filters
<activity android:name="com.yourapp.MainActivity">
<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=".*\\.your_file_extension" />
<data android:host="*" />
</intent-filter>
</activity>

Kotlin: Associate specific file extension to open 'content' files which have no explicit extension

In my project I want to my app to open custom file extension like '.bla'
I used the following IntentFilter to do this:
<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:scheme="content" />
<data android:mimeType="application/*" />
<data android:host="*" />
<data android:pathPattern=".*" />
</intent-filter>
This works great but the problem is my app appears in the 'open with' list for any file type -as expected, but I want it to open just my extension.
I can't use explicit extension '.bla' because it wont work if I open a bla file from WhatsApp, because the file wont have its ordinary path with the extension at the end, instead, it will be some kind like 'content://com.whatsapp.provider.media/item/03fda30df57e-c5e3a-46ea-6df67-fd23e4a3cb4fe'
so, I used the pathPattern as .* instead of something like .*\\.bla to make it work
What shall I do to solve this problem and to make my app opens only the .bla extension only

Can't get Android Firefox to open files with a mime-type specified

I want my app to handle files called *.mcmidi from browser, email or storage.
I have found that the following intent-filter data element works for android native browser and for android chrome:
<data android:scheme="content" android:mimeType="*/*" android:pathPattern=".*\\.mcmidi" />
and this works for android firefox:
<data android:scheme="file" android:pathPattern=".*\\.mcmidi" />
but if I try to use both then firefox stops being able to open the downloaded files. It seems like firefox doesn't work if any intent-filter specifies a mimeType.
(I've been testing so many combinations of these intent-filters trying to find one that works everywhere)
Does anyone know why firefox is doing this, or any way to work around it?
Ok I worked it out. Chrome and Android browsers use the scheme="content" entry. Firefox uses the scheme="file" entry. If you use the mimeType="*/*" entry then all new email alerts will open the app chooser with my app, which is also no good. Opening file attachments from gmail use scheme="content" but with a different mimeType. File explorer apps generally use scheme="file" with the path extension.
Because they all need different intent-filters, I have used activity-alias to alias my activity three different ways for the different apps, so that they all pass the file content to my app and don't interfere with each other or add themselves as generic file handlers (which is always very irritating). So I have this:
<activity
android:name="my.Activity"
android:label="#string/label1"
android:exported="true" >
<!-- the main intent filter allows chrome and native browsers to open .mcmidi files with my app -->
<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="content" android:mimeType="application/x-mcmidi" android:pathPattern=".*\\.mcmidi" />
</intent-filter>
</activity>
<!-- This alias will cause file explorer apps to open *.mcmidi files with my app -->
<activity-alias
android:name="my.ActivityFileAlias"
android:targetActivity="my.Activity"
android:label="#string/label1"
android:exported="true" >
<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=".*\\.mcmidi" />
</intent-filter>
</activity-alias>
<!-- This alias will cause gmail and the native mail apps to open *.mcmidi files with my app -->
<activity-alias
android:name="my.ActivityEmailAlias"
android:targetActivity="my.Activity"
android:label="#string/label1"
android:exported="true" >
<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="content" android:mimeType="application/octet-stream" android:pathPattern=".*\\.mcmidi" />
</intent-filter>
</activity-alias>
Which I worked out with a few clues and loads of trial and error. Hope it helps someone.

Intent filter to download attachment from gmail apps on Android

I have android application with intent filter (ACTION_VIEW) to open file and import it into my application. I wish to download file attachment from gmail app into my application. Some of file type (i.e. jpg, png, txt) are saved correctly, but some are not (i.e doc, xls, ppt). I believe I have the correct intent filter for my activity since it works from other app (i.e. dropbox), but not gmail app. Is there any solution for this ?
I was able to make the download and preview buttons pop up on Android in GMail by removing the scheme data filter in my intent (delete the scheme line and give it a try):
<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=".*\\.ext" />
<data android:host="*" />
</intent-filter>
However, as per the Android documentation, "If a scheme is not specified for the intent filter, all the other URI attributes are ignored." With the scheme and URI attributes removed, the only other way to filter the intents is using Mime type, and we all know that custom file extensions do not have registered mime types.
For reference, URI are of the form:
scheme://host:port/path
pathPrefix
pathPattern
So without a scheme, all of that drops. After discovering the above, I tried the obvious -- use a " * " for the scheme, and even tried " .* ". Neither of those worked. I hope someone else can build off my trials. But I believe it has to do with selecting the correct scheme. Unfortunately, the only schemes I know of are http https content and file, and none of the above are the magic bullet.
EDIT::::::::
I solved this yesterday. Please see my solution:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/*" host="*" android:pathPattern=".*.ext" android:scheme="content" />
</intent-filter>
This intent will cause gmail to display the Download / Preview buttons. In fact, this will also cause your app to open when .ext files are sent as attachments to the regular email client as well.
Since this is one of top question at google related to "gmail attachment intent filter" and I found above answer not working in my case I post the result of my research.
In order to register on intents from gmail, we need to support content scheme:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="content" android:mimeType="*" android:host="*" />
</intent-filter>
In case of attachments that I tested, URI did not contained file extension, even if it was displayed in gmail, so usage of android:pathPattern blocked receiving gmail intents.
Due to the fact, that registering to all mimeTypes is an overkill, I debugged contents of Intent object (on Java side) and found that in my application text/plain is enough (so your homework is to find proper mimeTypes for your application). My final intent-filter looks like that:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="content" android:mimeType="text/plain" android:host="*" />
</intent-filter>

Gmail attachment and custom extension

I work currently on an Android application that read file with a custom extension.
One of the mandatory features, is that the app must be proposed by gmail when the user receive a mail with the attachment .ourextension.
I did some research, and found that gmail client on Android doesn't rely on the extension, because in the data of the launched intent the file proposed has no extension. It only rely on the mime-type given by the mail client.
The problem is that our custom file are not detected the same way between mail clients. For example, if I send to myself with the gmail webpage our custom file, the mime-type is detect as application/octet-stream. If a friend of mine send with apple mail desktop software, it is detected as a text/xml (which would be nice). And on another mail client, Evolution, the mime-type is text/plain...
Our application can't handle all those types ! Otherwise, it would be proposed for every type of attachment...
Is there any solution for this ?
Solution to open file with custom extension tested with gmail < 4.2, gmail 4.2, Google Drive and file browser
Code to send file :
sendIntent.setType("application/calc1");
Intent-filter :
<!-- Filter to open file with gmail version < 4.2 -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/calc1" />
<data android:pathPattern=".*\\.calc1" />
<data android:host="*" />
</intent-filter>
<!-- Filter to open with file browser or google drive -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
<data android:mimeType="*/*" />
<data android:pathPattern=".*\\.calc1" />
<data android:host="*" />
</intent-filter>
<!-- Filter to open file with gmail version 4.2 -->
<!-- Save file first with "save" button otherwise gmail crashes -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/octet-stream" />
<data android:pathPattern=".*\\.calc1" />
<data android:host="*" />
</intent-filter>
It is possible to get this to work from gmail although it's taking me days of effort to figure out all the issues.
The Important Intent Data
act=android.intent.action.VIEW
dat=file:///mnt/sdcard/Download/Availability Focus.inform
typ=application/octet-stream
flg=0x80001 cmp=air.com.extension/.AppEntry
The Intent Filter that was able to capture it (some notes below)
<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="file" android:pathPattern=".*\\.inform" android:mimeType="application/octet-stream"/>
<data android:scheme="content" android:pathPattern=".*\\.inform" android:mimeType="application/octet-stream"/>
</intent-filter>
BOTH the content and file scheme's are required. Without the CONTENT scheme gmail will ignore your filter all together. This seems like a bug. Without the FILE scheme gmail will throw an error saying it doesn't know which application to launch from the intent.
07-19 15:38:19.160: ERROR/Gmail(2220): Coun't find Activity for intent
With both scheme's in place the application receives the intent for both Downloaded and Previewed files. They have to be handled differently.
You can still match extension for gmail
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/*" host="*" android:pathPattern=".*\\.mht" android:scheme="content" />
</intent-filter>
Make the change for mime type to be / and itll only match on extension
Edit: This answer is 3 years old. I didn't have the time to test the other's answers but mine is clearly outdated so please looks for the others answers of this topic !
I didn't found any solutions, the only way to work is with mime-type, so you must pray for your attachment to be recognize with a known mime-type, and handle this. It means that you will interfer with other application, if your file is recognize as html for example.
You need to handle the case that a file is not readable by your application and show a popup for notifying the user that you can't read the file.
Maybe in a year or two, Gmail will provide a good api...
By the way, the last gmail version add a download button that you must handle to avoid crashes, it works by creating a new file with the uri.

Categories

Resources