Android: Issue opening custom file attachment in native email - android

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>

Related

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.

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 app has been assigned to any possible file - should be assigned to my custom file only

I'm trying to assign my Android app to custom file (json content) with extension "kka".
I'd like to be able to open my app and read *.kka file in following cases:
1. *.kka as email attachment (gmail client)
2. *.kka as file stored in filesystem e.g. Downloads/ folder
My AndroidManifest.xml file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.mydomain.kka" >
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.mydomain.kka.MainActivity"
android:label="#string/app_name" >
<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.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" android:pathPattern=".*\\.kka" android:mimeType="*/*"/>
<data android:scheme="content" android:pathPattern=".*\\.kka" android:mimeType="application/stream-octet"/>
</intent-filter>
</activity>
</application>
</manifest>
That's the only configuration I found to be able to start my app tapping *.kka as attachment in gmail client and as file in filesystem.
The problem is that my app appears in every possible place where I want to open email attachment or file on filesystem, no matter what kind of file it is, so my KKATest app is on the list of assigned apps for e.g. XMLs, PDFs, even APKs, etc.
It seems to ignore file extension I clearly mentioned in AndroidManifest file.
This situation takes place on Galaxy Nexus with Android 4.4, Galaxy S4 with Android 4.3 and few more.
I've read many suggestions on StackOverflow but no one solves my problem. What's wrong with my manifest file?
I was struggling with the same issue. I need to open my file from both SD card as well as from email attachment. For me it was also trail and error, but this is my solution:
<intent-filter> <!-- Intent filter for opening files from system -->
<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:host="*" />
<data android:mimeType="*/*" />
<data android:pathPattern=".*\\.locx" />
</intent-filter>
<intent-filter> <!-- Intent filter for open files from email -->
<data android:scheme="content" />
<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/octet-stream" />
<data android:pathPattern=".*\\.locx" />
</intent-filter>
locx is my file type obviously.
BTW: I only tested with Gmail app, from other forum posts I understand that other email apps might work different.
Indeed, as you pointed out, some email clients replace the mime type with application/octet-stream. So I ended up using an intent filter like this:
<!-- Filters for handling local files -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.EDIT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" android:scheme="file" android:pathPattern=".*\\.mtype" android:host="*"/>
</intent-filter>
<!-- Filter for email apps -->
<intent-filter>
<action android:name="android.intent.action.VIEW"></action>
<category android:name="android.intent.category.DEFAULT"></category>
<category android:name="android.intent.category.BROWSABLE"></category>
<data android:scheme="content"/>
<data android:mimeType="application/octet-stream"/>
<data android:mimeType="application/mtype"/>
</intent-filter>
This will have your app handle both mtype, and octet-stream. But in the octet-stream case, it may not be actually your file, so you need to do some checking in the app. This means getting the file name, and checking the extension. For this, you can query the content provider, using the uri handled to you in the app, via the intent:
Cursor cursor = mContext.getContentResolver().query(data, null, null, null, null);
int fileNameColumnIndex = cursor.getColumnIndex("_display_name");
if (fileNameColumnIndex != -1) {
String fileName = cursor.getString(fileNameColumnIndex);
}
Now, there are a couple of scenarios:
If you used the gmail client, ther "_display_name" is present;
If you clicked the file, in the Downloader native app, the "_display_name" is present;
If you used the native email client, it is not present; And in this case, i prompt the user to first download the file. If he does so, and then opens the file in the email client again, it will actually open the file, and it will be handled by the first intent-filter.
I've found a solution (almost) and the solution looks like this:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.mydomain.kka" >
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.mydomain.kka.MainActivity"
android:label="#string/app_name" >
<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:host="*" android:mimeType="*/*" android:pathPattern=".*\.kka" android:scheme="file" />
</intent-filter>
<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:mimeType="application/custom-kka" android:scheme="content" />
</intent-filter>
</activity>
</application>
</manifest>
I don't know why entry <data android:host="*" android:mimeType="*/*" android:pathPattern=".*\.kka" android:scheme="file" /> with one backslash ("\") instead of two ("\\") solves the issue with opening all possible files from filesystem - now my app opens only for *.kka files ...
Opening files attached to mails needs to be handled by assigning to mime-type, not file extension. I created custom mime-type "application/custom-kka" and ensured that during sending mail with the file there needs to be set my custom mime-type for attachment.
To do so, I put a piece of code in email composer code:
...
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("application/custom-kka");
...
which should guarantee me proper mime-type for my attachment. Unfortunately, android mail clients (gmail, generic mail client) on few devices send mails with different then mine mime-type, e.g. "application/octet-stream;", "<nothing here>;" but not desired "application/custom-kka;" and my app can't identify such attachment as assigned to it.
That's the PhoneGap application, so I have also iOS version, where sending this mail with custom mime-type works perfectly and android app can recognise the attachment.
Maybe someone had such issue and could help?

Creating app which opens a custom file extension

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>

Android intent filter

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

Categories

Resources