Creating an intent - android

I'm trying to send an intent to Photoshop Express which now accepts raw images. In this example I'm sending a Canon CR2 file. Regardless of how I specify the action, data, or type I can't seem to get PSE to pop up as an option.
PSE manifest:
<activity android:configChanges="orientation|screenSize" android:launchMode="singleTask" android:name="com.adobe.psmobile.PSXEditActivity">
<meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.adobe.psmobile.MainActivity"/>
<intent-filter>
<action android:name="android.intent.action.EDIT"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="image/jpeg"/>
<data android:mimeType="image/png"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.EDIT"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="file"/>
<data android:mimeType="*/*"/>
<data android:host="*"/>
<data android:pathPattern=".*\\.cr2"/>
<data android:pathPattern=".*\\.CR2"/>
...
One of hundreds of attempted combinations:
// Intent action = new Intent();
Intent action = new Intent(Intent.ACTION_EDIT);
// action.setType("*/*");
action.setData(media.getUri());
action.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
action.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Intent chooser = Intent.createChooser(action, getResources().getString(R.string.edit));
startActivityForResult(chooser, REQUEST_CODE_EDIT);
Ex uri:
file:///storage/sdcard1/_test/canon_1d_miv_03.CR2
ES File explorer will send a CR2 file to PSE, but I can't under any circumstances get it to appear as an option for anything but jpeg. Does anyone know how to format the intent that PSE would consume?

You say that you are opening files in ES file explorer, well maybe it has set defaults for some file extensions?
Try re-setting them by:
Long click on an item
More
Open As
Clear defaults
You may need to do this multiple times for separate extensions.

Believe it or not this was the answer:
Intent action = new Intent(Intent.ACTION_VIEW);
action.setDataAndType(media.getUri(), "");
Note the empty string as type. The only other thing that produced options was "*/*", but that showed dozens of apps.
I still don't understand why the empty string worked, so if anyone has an explanation please let me know.

Related

Open Files, Mime Type, File Extensions Problems

i have many problems with my app.
1. I want to make a memo app which open only files with .mem file extension. Everything i tried doesn't work or it worked for all file extensions. What should i use/write in my manifest?
When i try to open a file in my app it is only possible when its not direct in the device storage, how can i open it from everywhere?
When i try to open a shared .mem file from whatsapp i get no url to the file. What i have to do there?
My current manifest intent filter:
<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:scheme="file" android:mimeType="*/*" android:pathPattern="*.*\\.mem" />
<data android:scheme="content" android:mimeType="*/*" android:pathPattern="*.*\\.mem" />
</intent-filter>
and so i load a file:
if (Intent.ACTION_VIEW.equals(appLinkAction)) {
String appLinkData = intent.getData().getPath();
File lo = new File(appLinkData);
}
thats the way i share it if its necessary:
Intent intentShareFile = new Intent(Intent.ACTION_SEND);
intentShareFile.setType("text/plain");
intentShareFile.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(memo));
context.startActivity(Intent.createChooser(intentShareFile, "Memo teilen über..."));
I searched a lot online but nothing helped me. Hope you know what to do.
Thx for every help :D

Android: Associate app with custom file type

I've got a file type, the extension is '.rfts' (really it's just storing a JSON string that represents user configurations for an audio amplifier). I'd like to be able to open this file when it's an attachment from an e-mail (Gmail for example) so I can import user settings from another tablet.
Here's what my manifest looks like (note that I didn't include the other activities in this, but there's 4 others that don't have intent filters).
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/RFtheme" >
<activity
android:name=".activity.MainActivity"
android:screenOrientation="landscape"
android:windowSoftInputMode="adjustPan" >
<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"/>
<category android:name="android.intent.category.OPENABLE"/>
<data android:scheme="file"/>
<data android:mimeType="*/*"/>
<data android:pathPattern="\\.rfts$"/>
<data android:host="*"/>
</intent-filter>
</activity>
<provider
android:name=".model.FileProvider"
android:authorities="com.rockfordcorp.app3sixty.provider"
android:enabled="true"
android:exported="true" >
</provider>
</application>
I've been trying several other suggested fixes from other questions, but they were for things like opening a pdf from a browser.
When I try to open a .rfts attachment in Gmail, it tells me "You don't have an app that can open this file (.rfts). Try searching google play for one that can"
I'm at a loss as to what I need to be doing here. I don't have any idea what mime Gmail would be using to open a .rfts, nor what scheme it would be using. I've tried a few different combinations but nothings really worked. I just haven't put in the magic combination of category, mimetype, pattern and scheme that Android is looking for to associate this file to my app.
EDIT some success, but not quite there yet.
The questions suggested as fixes are off the mark, and the reason is because the scheme required is actually 'content', not 'file'
The intent filter that works is
<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:mimeType="*/*" android:pathPattern=".*\\.rfts"/>
<data android:scheme="content" android:pathPattern=".*\\.rfts" android:mimeType="application/octet-stream" />
<!-- <data android:host="*"/> -->
</intent-filter>
Without the android:sceheme="content" it does not work.
However, a new problem arises. Gmail now opens all file types that are not previously associated with another app. For example, if I were to try to open a .rfff file, it uses my app. If you try to open a .txt it opens a chooser for Chrome or HTML viewer.
This is close, but it opening other file types is problematic. Android:pathPattern evidently has no effect on what filetype my app is associated with.
As this question was marked as a possible duplicate I want to point out the solution suggested is not working for opening a file from g-mail not web, nor does it cover opening a custom filetype. Using that 'solution' with the file type swapped out causes g-mail to continue to insist there is no app on the device capable of opening the file type.
A different solution likely needs to be provided to associate opening this custom filetype via the intent from Gmail.
Update 2020
Android has moved towards content URIs and MIME-Types for intent filters.
The Problem
A content URI does not necessarily have to contain the file's extension or name and it will be different between different applications that are providing the content/file.
Here are some example content URIs from different email applications for the same email attachment:
Gmail -> content://com.google.android.gm.sapi/some_email#gmail.com/message_attachment_external/%23thread-a%3Ar332738858767305663/%23msg-a%3Ar-5439466788231005876/0.1?account_type=com.google&mimeType=application%2Foctet-stream&rendition=1
Outlook -> content://com.microsoft.office.outlook.fileprovider/outlookfile/data/data/com.microsoft.office.outlook/cache/file-download/file--2146063402/filename.customextention
Samsung Email App -> content://com.samsung.android.email.attachmentprovider/1/1/RAW
As can see they are all different and are not guaranteed to contain anything related to your actual file. Thus, you cannot use the android:pathPattern like most have suggested.
A work around solution for email attachments
<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="content"/>
<data android:host="*"/>
<!-- Required for Gmail and Samsung Email App -->
<data android:mimeType="application/octet-stream"/>
<!-- Required for Outlook -->
<data android:mimeType="application/my-custom-extension"/>
</intent-filter>
Through testing I found the MIME-Types that Gmail, Outlook, and Samsung Email used and added those to my intent-filter.
Caveats/Gotchas
I found that with my above solution, if I opened any file that was a binary type, it would automatically launch my app. I handled this in my activity by displaying a failed state if we could not parse the file. I figured this was a pretty rare event so it would acceptable.
I could not find any way to launch my app via the file browser without adding <data android:mimeType="*/*"/> to my intent-filter. I couldn't use this because it would then launch my app whenever the user clicked any file on their phone (not just the custom-file-extension ones). I would not recommend adding this to your intent-filter.
I had no luck using android:scheme="file" at all.
I tested this on a Samsung Galaxy S10 on Android 10
Final Thoughts
There is currently no elegant solution for associating your app with a specific extension type in Android. This was the best that I could do in my situation.

Intent filter for common file explorers

I'm trying to associate my app with extension. I have read documentation and some questions about the problem. But major file explorers (like es file explorer, astro, file manager by Rhythm software) can't open my files.
My manifest file:
<activity android:name="com.comapping.android.map.MapActivity" android:configChanges="orientation|keyboardHidden">
<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:host="*" android:pathPattern=".*\\.comap" android:mimeType="*/*" />
</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="content" android:host="*" android:pathPattern=".*\\.comap" android:mimeType="*/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
And If I try to open file from my application using next code everything works fine (chooser not shown):
String extension = "";
int dotIndex = downloadedFile.lastIndexOf('.');
if (dotIndex != -1) {
extension = downloadedFile.substring(dotIndex + 1, downloadedFile.length());
}
// create an intent
Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
Uri data = Uri.fromFile(new File(downloadedFile));
String type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
if (type == null || type.length() == 0) {
// if there is no acceptable mime type
type = "application/octet-stream";
}
intent.setDataAndType(data, type);
// get the list of the activities which can open the file
List resolvers = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if (resolvers.isEmpty()) {
(new AlertDialog.Builder(context)
.setMessage(R.string.AttachmentUnknownFileType)
.setNeutralButton(R.string.NeutralButtonText, null)
.create()).show();
} else {
context.startActivity(intent);
}
If i try to open it using OpenIntents file manager everything is normal - showed long chooser with lots of apps and my app in the list.
But if I try to open it with es file explorer or Rhythm file explorer - showed their custom chooser (open as text/image/video/audio). It's bad.
And if I try to open it with Astro - it opens OpenIntent's file manager. It's also bad.
Is there any solution of the problem? Who is wrong in such behavior?
Thank you for any help.
Part of the problem here is all the different ways people wrap a shared intent for, say, a file that resolves to text/plain in Android mime identifier.
My approach has been to find out what mime types the files I want are. Then I set my manifest filters to those types. I use two filters. The first just filters the mimes I want. The second is a copy of the first plus schemes.
Then I test by sending shares from apps like you have done. When one does not work, I use a toast to see what I am getting for a STREAM and then alter it to fit. For example, if I get an OpenIntent STREAM, I have to remove
content://org.openintents.filemanager
which leaves me with the path. Mostly, I just have to remove:
file://
But it's always something because the whole content/Uri/Intent scheme is a free-for-all cluster whatsit.
LATER. I just stumbled on this:
Intent intent = getIntent();
String name = intent.getData().getPath();
Maybe that will do for you. I'm going to try it soon myself.

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>

How to add custom mime type?

What I want: To be able to send my custom file by mail and import it with my application from the preview button in GMail or when opening it in a file browser.
What I know: I've read a lot of custom mime type handlers, that android doesn't care about file extension etc., but how to create the mime type for my custom file?
The question: Do I need to be a content provider? I just want to import files (from backup) not provide anything. I've seen people having handlers for "application/abc" saying it's working fine, but how to add that connection for my file "myFile.abc" and the mime type?
Some direction how to register/map custom mime types would be appreciated! :)
As far as I can tell, mime types are pretty flexible (I created mine as application/whatever) and they're accepted immediately by Android, as far back as Dalvik version 2.1. To handle them properly, I added this intent-filter:
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="application/whatever" />
</intent-filter>
There is a caveat though. Even though I always set the type of the send Intent with intent.setType("application/whatever");, on some phones I've seen the actual data on arrival as application/octet (to see the value, I assigned the incoming Intent and inspected its value directly Intent currentIntent = getIntent();). The receiving Android device didn't know what to do with the incoming data and told me so. So I added
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="application/octet-stream" />
</intent-filter>
This approach could be troublesome of course, but the problem with Gmail at least is that it doesn't necessarily write the file with the name as it comes in, which renders any Path I choose to define useless. And at least with an incoming octet-stream you know it's not any app's specific data you're stealing away... Still, you should validate the data afterwards and not just assume it's valid for your app.
I have added custom mime type in android contacts list. After a long research i decided to share this with you guys, i have tested this on all Android cell phone including android 9.0.
here is my Github link
Untested, but something like this should work. Put it in your AndroidManifest.xml with the activity you want to open the file:
<activity name=".ActivityHere">
<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="mimeTypeHere" />
</intent-filter>
</activity>
<activity
android:name="MainActivity"
android:label="#string/app_name"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen" >
<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="{your mime}.com"
android:scheme="http" >
</data>
</intent-filter>
</activity>
<!--
android:scheme="http" will make android "think" thats this is a link
-->
Now, when you receiving a sms with the text "http://{your mime}.com" or clicking link on the web with this text, your activity (MainActivity) will run.
You also can add parameters:
text = "http://{your mime}.com/?number=111";
Then in onCreate() or onResume() methods you'll add:
Intent intentURI = getIntent();
Uri uri = null;
String receivedNum = "";
Log.d("TAG", "intent= "+intentURI);
if (Intent.ACTION_VIEW.equals(intentURI.getAction())) {
if (intentURI!=null){
uri = intentURI.getData();
Log.d("TAG", "uri= "+uri);
}
if (uri!=null)
receivedNum = uri.getQueryParameter("number");
}
Register a custom mime type using android.webkit.MimeTypeMap

Categories

Resources