Creating app which opens a custom file extension - android

Want to create an android application, which opens a custom-build file extension (for example, I want to open .abcd files)
It is something like Adobe Reader that opens .pdf files, or Photo Viewer that opens .jpg files
Specific conditions:
1. The .abcd file should be outside / external from the application itself. (as .pdf is to Adobe Reader)
2. The .abcd file would be a zipped file, which contains few folders and .xml, .txt, and .jpg files. I think I want to extract it - maybe temporarily - to somewhere in the storage (definitely need a zipper/unzipper library), then read the individual .xml, .txt, and .jpg files.
Looking for insights and answers for this problem.
Additional information:
I am relatively new to Android programming.

I think you need to do that type of customization via intent-filter something like:
<intent-filter android:icon="your_drawable-resource"
android:label="your_string_resource"
android:priority="integer">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
<data android:host="*" />
<data android:pathPattern=".*\\.YOUR_CUSTOM_FILE_EXTENSION" />
</intent-filter>
Also you should look:
Custom Filetype in Android not working
Android intent filter for a particular file extension?
android intent filter for custom file extension

One possible answer is shown
here
. Try some customisation for intent filters.
<intent-filter android:priority="999">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.OPENABLE" />
<data android:host="*" />
<data android:mimeType="application/octet-stream" />
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.yourextension" />
<data android:pathPattern=".*\\..*\\..*\\..*\\.yourextension" />
<data android:pathPattern=".*\\..*\\..*\\.yourextension" />
<data android:pathPattern=".*\\..*\\.yourextension" />
<data android:pathPattern=".*\\.yourextension" />
<data android:scheme="content" />
</intent-filter>

Related

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

Intent filter works on emulator but not on device

I'm creating a custom intent filter which will open my app when I tap a file with a certain file extension (.myextension in this case.) The intent-filter is below. This currently works perfectly every time I open a .myextension file from my emulator. However, when I try it from my device, it no longer works.
On my device, when I tap a .myextension file in the Files browser app, I see Unable to preview file. instead of automatically opening the app. I've tried opening the file from quite a few locations (Files app, GDrive, Downloads folder, Slack/Gmail, both internal storage and SDCard.) I'm using Android 10 on both my emulator and my device.
<intent-filter android:label="My App">
<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:mimeType="*/*"
android:host="*"
android:pathPattern=".*\\.myextension" />
</intent-filter>
I've also tried replacing that data tag/adding a second tag with this block but it doesn't seem to help:
<data
android:scheme="file"
android:mimeType="*/*"
android:host="*"
android:pathPattern=".*\\.myextension" />
Am I missing something obvious? Any help would be greatly appreciated. Thanks!
This currently works perfectly every time I open a .myextension file from my emulator.
It will fail much of the time, as it is not really tied to an emulator versus a device.
However, when I try it from my device, it no longer works.
A content Uri is not required to have a file extension, just as an https URL is not required to have a file extension. Much of the time, a content Uri will not have a file extension, and such a Uri will not match your <intent-filter>.
ACTION_VIEW is mostly for files with a widely-recognized MIME type.
I've also tried replacing that data tag/adding a second tag with this block but it doesn't seem to help
file Uri values have been generally banned since Android 7.0.
<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=".*\\.myextension" />
<data android:pathPattern="/*.*\\.myextension" />
<data android:pathPattern="/*.*\\..*\\.myextension" />
<data android:pathPattern="/*.*\\..*\\..*\\.myextension" />
<data android:pathPattern="/*.*\\..*\\..*\\..*\\.myextension" />
<data android:pathPattern="/*.*\\..*\\..*\\..*\\..*\\.myextension" />
<data android:pathPattern="/*.*\\..*\\..*\\..*\\..*\\..*\\.myextension" />
<data android:pathPattern="/*.*\\..*\\..*\\..*\\..*\\..*\\..*\\.myextension" />
<data android:pathPattern="/*.*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.myextension" />
<data android:host="*" />
</intent-filter>
Though it doesnt work in some of the file managers Better first try in ESExplorer.

Is it possible to make simpler path patterns?

I noticed one of the big video apps on Android has all sorts of path patterns, I'm assuming to catch subdirectories or weird names? they basically end up having a bunch of pattersn that look like this: <data android:pathPattern=".*..*..*..*..*..*..*..*..*..*..*..*..*..*..*.3gp" />
Is there no easier way to simplify that path?
Here is a longer example:
</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="*" />
<data android:pathPattern=".*.3gp" />
<data android:pathPattern=".*..*.3gp" />
<data android:pathPattern=".*..*..*.3gp" />
<data android:pathPattern=".*..*..*..*.3gp" />
<data android:pathPattern=".*..*..*..*..*.3gp" />
<data android:pathPattern=".*..*..*..*..*..*.3gp" />
<data android:pathPattern=".*..*..*..*..*..*..*.3gp" />
<data android:pathPattern=".*..*..*..*..*..*..*..*.3gp" />
<data android:pathPattern=".*..*..*..*..*..*..*..*..*.3gp" />
<data android:pathPattern=".*..*..*..*..*..*..*..*..*..*.3gp" />
<data android:pathPattern=".*..*..*..*..*..*..*..*..*..*..*.3gp" />
<data android:pathPattern=".*..*..*..*..*..*..*..*..*..*..*..*.3gp" />
<data android:pathPattern=".*..*..*..*..*..*..*..*..*..*..*..*..*.3gp" />
<data android:pathPattern=".*..*..*..*..*..*..*..*..*..*..*..*..*..*.3gp" />
<data android:pathPattern=".*..*..*..*..*..*..*..*..*..*..*..*..*..*..*.3gp" />
Reference
<activity 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=".*\\.3gp" />
<data android:host="*" />
</intent-filter>
</activity>
The scheme of file indicates that this should happen when a local file is opened (rather than protocol like HTTP).
mimeType can be set to */* to match any mime type.
pathPattern is where you specify what extension you want to match (in this example .3gp). The .* at the beginning matches any squence of characters. These strings require double escaping, so \\. matches a literal period. Then, you end with your file extension. One caveat with pathPattern is that .* is not a greedy match like you would expect if this was a regular expression. This pattern will fail to match paths that contain a . before the .3gp. For a more detailed discussion of this issue and a workaround see here
Finally, according to the Android documentation, both host and scheme attributes are required for the pathPattern attribute to work, so just set that to the wildcard to match anything.
Now, if you select a .3gp file in an app like Linda File Manager, my app shows up as an option. I should note that this alone does not allow you to download this filetype in a browser, since this only registers with the file scheme. Having an app like Linda File Manager on your phone resisters itself generically allowing you to download any file type.

Saving File and Opening with Android App

I am saving a binary to a file with a custom extension for instance .custom. How do I save it to a specific mime type? I want my app to be called to open that custom file. In the manifest I used / as mimeType but the app gets called even when tapping an image. I used octet-stream but the file doesn't get recognized and the app does not get opened. I just want to save a binary with custom extension and the OS would call my app when it encounters this 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="file" />
<data android:mimeType="application/octet-stream" />
<data android:pathPattern=".*\\.test" />
<data android:host="*" />
</intent-filter>
Finally, after several views only without answers I figured it out. The post on this link helped me resolve my issue.
https://publish.illinois.edu/weiyang-david/2013/04/11/how-to-write-intent-filter-dealing-with-mime-type-problem/
This example was it
<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="http" />
<data android:host="*" />
<data android:pathPattern=".*\.pdf" />
</intent-filter>
I replaced the scheme to "file" and replaced with my pathPattern. Removing the mimeType was key to solving my issue. File browsers now suggests to open the custom file with my app.

Android: Issue opening custom file attachment in native email

I have a file with extension .abc and I trying to read this file in my personal app. I have the following intent filter in my manifest xml.
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
<data android:scheme="content" />
<data android:mimeType="*" />
<data android:pathPattern=".*\\.abc" />
<data android:host="*" />
</intent-filter>
This filter catches all the intents sent from a file browser, 3rd party email clients etc. except for the native email client. the only difference between a file browser application and native email client is that, the scheme for the file browser is "file" and the scheme for native email client is "content". When I click a file with extension .abc in attachments in the native email client, it doesnt even download the file and no intent is fired. Any suggestions on where the issue could be?
If I am missing any information, I will be happy to add to the question.
This was solution to the problem. The mime type for the files with custom extension was application/. Adding the below filter to the manifest file solved the issue.
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
<data android:mimeType="application/abc" />
<data android:host="*" />
</intent-filter>

Categories

Resources