Custom file extension in Android - android

I have a custom file extension like .foo that I want to associate my app with. I created this 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="file" android:pathPattern=".*\\.foo"/-->
<data android:scheme="file" android:mimeType="*/*" android:pathPattern=".*\\.foo" android:host="*"/>
</intent-filter>
The problem is that this doesn’t work on some devices. For example, only the following works with the Samsung Galaxy S3 (Android version: 4.4.2):
<data android:scheme="file" android:mimeType="*/*" android:pathPattern=".*\\.foo" android:host="*"/>
However, with a LG G2 (Android version: 4.4.2), only this line works:
<data android:scheme="file" android:pathPattern=".*\\.foo"/>
To make it even worse, the Nexus 7 (Android-Version: 5.0) doesn’t seem to recognize custom file endings at all.
Has anyone ever had a similar problem and knows a solution?

Patterns for files are screwy... seems to be on purpose done by the developers.
It seems that the file pattern will work differently on different devices but it only depends on de depth of the file structure. See this link: pathPattern to match file extension does not work if a period exists elsewhere in the file name?

I think this way works for me (change "custom" with the extension you want to use) :
<activity android:name=".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=".*\\.custom"/>
<!-- These additional pathPattern blocks are to allow for paths with
additional periods in them. See:
http://stackoverflow.com/questions/3400072/pathpattern-to-match-file-extension-does-not-work-if-a-period-exists-elsewhere-i/8599921 -->
<data android:pathPattern=".*\\..*\\.custom"/>
<data android:pathPattern=".*\\..*\\..*\\.custom"/>
<data android:pathPattern=".*\\..*\\..*\\..*\\.custom"/>
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.custom"/>
<data android:host="*"/>
</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="file"/>
<data android:pathPattern=".*\\.custom"/>
<data android:pathPattern=".*\\..*\\.custom"/>
<data android:pathPattern=".*\\..*\\..*\\.custom"/>
<data android:pathPattern=".*\\..*\\..*\\..*\\.custom"/>
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.custom"/>
<data android:host="*"/>
</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:mimeType="application/vnd.ni.custom" android:scheme="file"/>
</intent-filter>
</activity>

Related

Issue in android:pathPrefix on AndroidManifest.xml with special character #

I have the following link:
https://thus.customapp.it/#/app/customapp/itemDetail/45289348293423
I want that this link is captured and opened with my app. So, I added these lines on AndroidManifest file:
<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="https" android:host="thus.customapp.it" android:pathPrefix="/#/app/customapp/itemDetail"/>
</intent-filter>
I also tried with:
<data android:scheme="https" android:host="thus.customapp.it" android:pathPrefix="/#/app/customapp/itemDetail/.*"/>
and this:
<data android:scheme="https" android:host="thus.customapp.it" android:pathPattern="/.*/.*/.*/.*/..*"/>
and this:
<data android:scheme="https" android:host="thus.customapp.it" android:android:pathPrefix="/#"/>
and this:
<data android:scheme="https" android:host="thus.customapp.it" android:pathPattern="/#/.*" />
but it doesn't work.
P.S. with the following code:
<data android:scheme="https" android:host="thus.customapp.it" android:pathPattern="/.*"/>
it works, but I need to intercept just a url which contains "itemDetail", and not, for example, https://thus.customapp.it/#/app/customapp/editItem/45289348293423
Use
android:path="/%23/app/customapp/itemDetail/.*
instead of
android:pathPrefix="/#/app/customapp/itemDetail/.*"
Edit: As suggested by #panagulis72 we should use %23 instead of #

Android Intent filter for url with redirect

How to setup intent filter for url with redirection?
https://mail.mailserverXXX.com/m/redirect?url=http://foosubdomain.foodomain.com/#object?id=e1162d22-222b-4522-2210-c222102d6022
This filter does not work for URL above.
<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"/>
<data android:scheme="https"/>
<data android:host="foosubdomain.foodomain.com"/>
</intent-filter>
This filter works for URL above. But this is not what needed. I need to filter by host in redirect part foosubdomain.foodomain.com
<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"/>
<data android:scheme="https"/>
<data android:host="mail.mailserverXXX.com"/>
</intent-filter>
Well bad news. After a long check I found that intent-filter doesnt even parse everything after question mark
In other words from link
https://mail.mailserverXXX.com/m/redirect?url=http://foosubdomain.foodomain.com/#object?id=e1162d22-222b-4522-2210-c222102d6022
Intent-filter works only with that part
https://mail.mailserverXXX.com/m/redirect
So there is impossible to write universal solution for your problem.

Associating App with Epub format

I'm at a loss for getting my application to register with epub files on a mobile device. I have a set of intent filters in my android manifest, but it still will not open with epub files on the sd card. When I go through the File Explorer app, it shows the file, but when I click on it, it says "The system does not support this type of file:". When I download a file from the internet, and then navigate to the download folder using the downloads application, the file does not show up at all (even though it's in the download folder in the file browser). I've also tried to get epub files to show up with the file chooser intent (Intent.ACTION_OPEN_DOCUMENT), but no luck. I'm guessing the last two do not show up because the intent loads with Intent.CATEGORY_OPENABLE
I've tried multiple epub files and all without success.
Can someone help figure out what I'm missing?
Using KitKat and higher phones.
Note: this does work with downloading from the internet. If I go to an epub link, this works, but not from the filesystem.
<!-- Open File Types -->
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:host="*" android:scheme="file"/>
<data android:pathPattern=".*\\.epub"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:host="*" android:scheme="file" android:mimeType="text/plain"/>
<data android:pathPattern=".*\\.epub"/>
</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:host="*" android:scheme="file"/>
<data android:mimeType="application/epub+zip"/>
</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:host="*" android:scheme="http"/>
<data android:pathPattern=".*\\.epub"/>
</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:host="*" android:scheme="http" android:mimeType="text/plain"/>
<data android:pathPattern=".*\\.epub"/>
</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:host="*" android:scheme="http"/>
<data android:mimeType="application/epub+zip"/>
</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:host="*" android:scheme="https"/>
<data android:pathPattern=".*\\.epub"/>
</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:host="*" android:scheme="https" android:mimeType="text/plain"/>
<data android:pathPattern=".*\\.epub"/>
</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:host="*" android:scheme="https"/>
<data android:mimeType="application/epub+zip"/>
</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:host="*" android:scheme="content"/>
<data android:pathPattern=".*\\.epub"/>
</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:host="*" android:scheme="content" android:mimeType="text/plain"/>
<data android:pathPattern=".*\\.epub"/>
</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:host="*" android:scheme="content"/>
<data android:mimeType="application/epub+zip"/>
</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:host="*" android:scheme="book"/>
</intent-filter>
<intent-filter
android:icon="#raw/icon"
android:label="ePub File"
android:priority="1" >
<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" />
<data android:scheme="https" />
<data android:scheme="ftp" />
<data android:scheme="file" />
<data android:host="*" />
<data android:mimeType="*/*" />
<data android:pathPattern=".*\\.epub" />
</intent-filter>
Update:
Looking for answers to the following questions for the bounty:
How do I get android system to recognize that epub files on internal or external storage can be opened with my app?
How do I get the default file browser (Storage Access Framework) to show epub files?
How do I get android system to recognize that epub files on internal or external storage can be opened with my app?
The "android system" does not have much to do with it, particularly today.
Support in MimeTypeMap (or, more accurately, libcore.net.MimeUtils from the framework classes) for .epub/application/epub+zip was added ~35 hours ago. Presumably, it will show up in a future edition of Android. Prior to that, the only file managers that will use that MIME type are ones that added it in themselves.
At a high level, when confronted with a problem like this, the solution is fairly simple:
Find another app that does what you want (in this case, another EPUB reader)
Use the App Browser app to see what that app's manifest looks like and what it chose for <intent-filter> stanzas
In general, I usually see an <intent-filter> with a scheme and a MIME type or a scheme, host, and path stuff. Having the MIME type and the path stuff is unlikely to help, as if the Intent does not explicitly have the MIME type in it, and Android doesn't know about mapping that specific extension to your MIME type, your <intent-filter> may not match.
Also, you will need to test with multiple "File Manager" apps, as Android does not have a file manager, and therefore you may be experiencing bugs/limitations in the one that you are testing.
How do I get the default file browser (Storage Access Framework) to show epub files?
Specify the proper MIME type and pray for a miracle.
Again, until Android itself offers a bit more built-in support for mapping .epub to the MIME type, you are reliant upon storage providers themselves happening to know that .epub maps to the application/epub+zip MIME type. Some providers will, because they are getting that information from some back-end server that may know more MIME types than does Android itself. Some providers may not, such as Android's MediaStore-backed provider of what's on external storage, as I doubt that MediaStore has its own local support for EPUB files.

How do I find out if My activity was started by an Activity of my own app?

I have a library project that displays pdfs. My main project has a few PDFs that I want to display. So I use it. Also, I have added intent filters for the activity that displays the pdf(so that other apps can also use it to display pdfs).
I want to detect if my PDFVIEWER was started by my own activity or not(I want to display the Title Bar if its started externally) how do I do that?
Here is my activity declaration:
<activity
android:name="com.artifex.mupdfdemo.MuPDFActivity"
android:theme="#android:style/Theme.Holo.Light"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="application/vnd.ms-xpsdocument"/>
<data android:mimeType="application/xps"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="application/pdf"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="application/x-cbz"/>
</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="file"/>
<data android:mimeType="*/*"/>
<data android:pathPattern=".*\\.xps"/>
<data android:host="*"/>
</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="file"/>
<data android:mimeType="*/*"/>
<data android:pathPattern=".*\\.pdf"/>
<data android:host="*"/>
</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="file"/>
<data android:mimeType="*/*"/>
<data android:pathPattern=".*\\.cbz"/>
<data android:host="*"/>
</intent-filter>
</activity>
I can't tell you, if it's possible to get the activity which started the intent, but as a workaround you can put a Boolean value in your Intent to make sure your PDFViewer was started by your app.
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(fileUri);
intent.putExtra("myAppStarted", true);
And in your started activity:
boolean displayTitleBar = getIntent().getBooleanExtra("myAppStarted", false);
Please note it is recommended to use static final String variable with "myAppStarted" instead of hardcoding the String in different places.
You can use getCallingActivity, provided your activity was started using startActivityForResult. A better solution would be to add extra information into your intent that tells you if the calling activity is yours.
AppCompat.getReferrer() should return the package name of the Activity that started yours.

Handling share and other actions from Chrome

I have an app which can play some videos, think MXPlayer plus a light browser. So I would like to get the opportunity to handle certain video files when someone clicks on a link in chrome of one those files, and also I would like to appear on the share popup of chrome when someone wants to share the link (so that my app may open the page). I have so far gotten my app to show up on the share popups of other apps but I just can not get it to show up on the share popup of Chrome. Here are my intent filters:
<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"/>
<data android:scheme="https"/>
<data android:mimeType="video/*"/>
<data android:mimeType="*/avi"/>
<data android:mimeType="*/mkv"/>
<data android:mimeType="application/mp4"/>
</intent-filter>
<intent-filter android:icon="#drawable/ic_launcher">
<action android:name="android.intent.action.SEND"/>
<data android:mimeType="*/*"/>
<data android:scheme="http"/>
<data android:scheme="https"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
Can someone tell me what I am doing wrong? Also I should mention I only want http/https streams, I do not want local files.
Thanks.
I managed to get it working by using this for the share menu option:
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:mimeType="text/plain"></data>
</intent-filter>
and this for when someone clicks on a link and chrome pops a dialog of where to open it:
<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"/>
<data android:scheme="https"/>
</intent-filter>

Categories

Resources