I have deployed an Android app that is designed to view files, some users reporting that my app isn't appearing when they try to open a file but does appear when selecting Open with....
For example, when I try to open a file in some apps I am presented with a dialog like this:
When I press Open with... I am presented with a dialog like this:
I think what is happening here is the Open with... is starting an ACTION_CHOOSER intent whereas pressing the file starts an ACTION_VIEW intent.
My questions are:
Is my assumption surrounding the ACTION_CHOOSER reasonable?
Why do some apps appear in ACTION_CHOOSER that don't appear in ACTION_VIEW?
Is the ACTION_VIEW list somehow dependent on a device?
If so, what would cause my app to not appear in this list?
For reference, my activity's intent filter looks like this:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.EDIT" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="*"
android:mimeType="*/*"
android:scheme="content" />
<data
android:pathPattern=".*\\.xml"
android:scheme="file" />
<!-- about a hundred other file types -->
<intent-filter>
Related
What I want to achieve is that if user tap on the link e.g. on Whatsapp:
HTTP://dev.mycompany.com/qr/asd89f7as98df78
This link will open my app supplied with the deep link.
But the issue is this link actually open my app inside the Whatsapp. So when I open the app switcher, it looks like there are two instances of my app opened. How can I fix this?
I suspect this has something to do with the way I configure my intent filter on Android Manifest. But I'm inexperienced with intent-filter. This is the current configuration for my intent filter(s):
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter android:autoVerify="true">
<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="dev.mycompany.com" />
<data android:scheme="https" />
</intent-filter>
Is there anything I can do to fix the problem? The first intent filter is the default when I create the app. The second one is from copy pasting from solutions I find on stack overflow. But I don't think this is the fully correct solution. I don't want the app to can be opened as popup.
I am developing an app that can extract information from certain web pages. The idea is that when the user is within a specific url path in the browser and press the share button, my app will show up in the list of receiver apps.
I can do that easily by adding this to the manifest:
<intent-filter android:label="#string/app_name" >
<action android:name="android.intent.action.SEND" />
<data android:mimeType="text/plain" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
However, this will make my app appear on the list on all urls, also all those where it will have nothing to do. Instead I would like the app appear in the chooser only from these urls:
www.example.com/foo/bla.html
www.example.com/foo/bar/blabla.html
But not from these:
www.example.com
www.foobar.com
etc. Ie. only from within a certain path on a certain host. Also note that I do not want my app to be launched when the user clicks on links matching the criteria. It should only be invoked from the share menu.
So my question is: How can I limit my app to show up in the intent choose only for certain urls?
Add the following filter to the destination Activity ..
1. host your site name.
2. scheme scheme of your site http or https.
3. path for the file path your app should display.
<intent-filter>
<data
android:host="www.example.com"
android:scheme="http"
android:path="/foo/bla.html"
/>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" >
</category>
<category android:name="android.intent.category.BROWSABLE" >
</category>
</intent-filter>
How can I limit my app to show up in the intent choose only for certain urls?
You can't. ACTION_SEND has no notion of "only from certain URLs", or "only from certain WhatsApp users", or "only from left-handed Alaskan pipe-welders".
This is not significantly different than any other activity. An <intent-filter> only controls what the Intent is being delivered to. Nothing controls what the Intent is delivered from, with the exception of security-related items (permissions, whether or not the component is exported, etc.).
So, with ACTION_VIEW, the URL is something being delivered to another activity ("I wish to view this URL"). This works because the URL is turned into the Uri of the Intent, and that can be filtered upon via <data> elements in the <intent-filter>.
But ACTION_SEND doesn't have to have a URL, and even if there is one, it is merely payload in the form of an extra. It is not something that can be filtered upon.
Hence, what you want is not supported.
Use pathPrefix
<intent-filter>
<data
android:host="www.example.com"
android:scheme="http"
android:pathPrefix="/foo/"
/>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" >
</category>
<category android:name="android.intent.category.BROWSABLE" >
</category>
</intent-filter>
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>
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.
I'm trying to catch an Android Market search intent.
That's the way you launch Android Market and search for an app by package name:
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=pname:com.google.somepackage")));
Now, here's the intent filter for one of my activities:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="market" android:host="search" />
</intent-filter>
I'd expect Android to ask me which app should handle the intent which doesn't happen.
Yet, if I replace market with market1 or search with search1, in both places, my activity gets launched.
Is there a notion of "untouchable" intents or something?
TIA.
That is odd indeed, and kinda goes against the whole open intent system. I know there are broadcasts that only the system can create, but I hadn't heard of such a thing for intent resolution.
Anyway, I just dumped the Market APK on my HTC Hero and checked the manifest. They're being slightly more specific in their URI-matching by adding the path:
<intent-filter android:priority="100">
<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="market.android.com" android:path="/search" />
<data android:scheme="market"
android:host="search" android:path="" />
</intent-filter>
However, I tried adding this to my app, except I increased the priority value (not that I've seen that have any effect before), yet still I couldn't capture the Intent.
Hopefully someone (or the AOSP) can shed some light on the situation...