I'm doing a project, and I'm trying to launch our application through link from a received message.
But the URIS keep getting cut... I don't know the reason why.
Here is the SMS I got - I can't upload pictures, so i'll make the link part bold.
test *com.wekimi.and*roid
I defined the URI in EmergencyActivity.java like this :
Uri uri = Uri.parse("com.wekimi.android");
And I added intent-filter in manifest file like this :
<activity android:name="EmergencyActivity" >
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="com.wekimi.android" />
</intent-filter>
What would be the problem? I don't even know if the Uri is recognizing the scheme data or not, because it's too short so it can't be directed to a right destination.
Related
I am trying to make a video player app. I can play video by opening my app manually. But I want to show my app as an option like below picture:
in short, when I click any video file in file manager, this will show my app as an option for playing that video. When user click on my app this will open a particular activity and start playing that file. How can I do this?
add intent filter to activity.
very similar to this.
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="video/*" />
</intent-filter>
also see this Forcing an app chooser
Read how to achieve this in official documentation
You need to put an intent filter in your manifest.xml. This tells the OS which types of media/ files your app is capable of handling. When you click a video file in file manager, Android issues an implicit intent . This basically puts out a wanted ad (excuse the analogy) to other apps that the file needs to be handled. When this happens, if your app has the capability to handle this file/ media type, it will respond. From here, if there is only one capable app, it will be selected for the task. If there are multiple capable apps, all of them will be added to a list, which is then displayed to the user (the list in the image you posted above.)
Add the below code to inside activity(that you want to open) inside manifest:
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="video/*"/>
<data android:scheme="content"/>
<data android:scheme="file"/>
</intent-filter>
use below code to your activity to get the uri of your file. I have tested the path in exoplayer.
Uri uri = getIntent().getData();
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.
We have developed an Android app which is used for rendering files of our custom file type (.vds). I am able to launch my app for all the files (.vds file) which are stored on local storage, but if the files is stored on Box and I try to access them using the Box Android App then I am facing issues. I have created the following intent filter:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
<data android:host="*" />
<data android:pathPattern=".*\\.vds" />
The problem is that in the corresponding activity I am able to get the intent, but if I try to read the URI (as our rendering logic is based upon file location) it gives me a path which doesn't exists on the SD card. What happens if we try to open a file using Box Android Native App? Where is the file downloaded and how should the downloaded file be accessed?
This may solve ur problem. Add the bellow intent filter.
<activity android:name=".Activity"
android:screenOrientation="portrait"
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"/>
<action android:name="android.intent.action.EDIT"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:pathPattern="*.snowdragon"/>
<data android:mimeType="text/snowdragon"/>
</intent-filter>
</activity>
As noted above I've run into the same problem. While I've not found what I would consider to be The Right Solution(TM) I do have a couple of things to add that might be useful to others:
First, I've discovered that if I download the file in Box (not the same as mark for offline) then clicking the item in either the download result dialog or in the subsequent notification that appears at the bottom of the app works. Once you've dismissed that notification however, there does not seem to be a way to get back to the downloaded file from within Box.
Second, and let me qualify this by saying that I've not looked very closely at it yet but I think one could use the filename info in the intents for non-existent files to retrieve the file via the Box API, either directly from the cloud or possibly via API call to retrieve offline items. I'm wondering if this is actually what Box is trying to get us to do with these bogus file paths, considering that they are so blatantly bogus:
12-04 10:09:29.318: INFO/ActivityManager(607): START u0
{act=android.intent.action.VIEW dat=file:///non_existent_dummy_folder/foo.abcdef typ=application/abcdef cmp=com.foo.bar/.app.FooViewer}
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
I want to open a specific type of file that my app can already send over email as an attachment. I need to be able to have the android email app choose my app to download or open that specific file type. I can't figure out how to set up an intent filter that would let me do that though. Anyone know how this is done?
Intent filters generally work based on MIME type of the file. But if you're using a custom file format that Android's not likely to recognise, then it's not as simple. You can maybe try using the android:pathPattern attribute to try and match the filename, but it's not something I've tried.
I imagine you'd use something like this in your <activity> tag:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
<data android:pathPattern=".*\\.xyz" />
</intent-filter>