I have used this example so that other applications can call my activity to receive data from them.
Specifically, I want when uploading an image from a browser my application can supply that image.
In the following image can see that case. A list of applications that provide images when the user clicks upload file:
I used this code that is copied from the link I added to the start.
<activity
android:name=".LoginActivity"
android:label="#string/title_activity_login">
<!-- filter for sending text or images; accepts SEND action and text or image data -->
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
I can not get my app to appear in the apps list shown in the photo.
Also I test this, as #Avi suggests:
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.APP_BROWSER" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:mimeType="image/*" />
<data android:mimeType="text/plain" />
</intent-filter>
Getting the same results
Note: I am using the chrome browser in Android
Change below line
<action android:name="android.intent.action.SEND" />
to
<action android:name="android.intent.action.VIEW" />
I got my app to appear in the browser when uploading an image with the following code.
<intent-filter>
<action android:name="android.media.action.IMAGE_CAPTURE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.media.action.STILL_IMAGE_CAMERA" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
Try this-
Manifest file:
<activity
android:name=".activities.HomeActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
<data android:mimeType="image/*" />
</intent-filter>
</activity>
Your MainActivity file:
val data: Uri? = intent?.data
// Figure out what to do based on the intent type
if (intent?.type?.startsWith("image/") == true) {
// This handles the intents with image data or of any other type based on your specified condition.
} else if (intent?.type == "text/plain") {
// This handle the intents with text or based on your conditions
//Use any popup like toast, snackbar, dialog, etc of your preference.
}
And also please do check whether you have mentioned your action as VIEW or SEND.
If its a VIEW it wont reflect in your result but if its SEND then it will work.
Check for this if in any of the file you have mentioned this-
val sendIntent = Intent(Intent.ACTION_SEND) //Replace to SEND if you have used ACTION_VIEW
sendIntent.type = "image/*"
val title = context?.resources?.getString(R.string.chooser_text)
if (context?.packageManager != null) {
context?.startActivity(Intent.createChooser(sendIntent, title))
}
And if you want to fetch the result of your action the insert this too...
Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri")).also { result ->
setResult(Activity.RESULT_OK, result)
}
finish()
For better understanding of this flow, refer this -> https://developer.android.com/training/basics/intents/filters
Related
I'd like to add a share functionality to share photos with my app,
the app has two main functionalities, each uses photos as the main input data from the user.
So I need to have two share buttons for the two functionalities. I added this in the application tag in the AndroidManifest.xml:
<activity android:name="MainActivity">
<intent-filter android:label="#string/ENCODE">
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
<intent-filter android:label="#string/DECODE">
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
</activity >
but only the first intent filter is applied.
but when I specified another activity for the second filter, it worked:
<activity android:name="MainActivity" android:label="#string/ENCODE">
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
</activity >
<activity android:name="com.company.myapp.DecodeActivity" android:label="#string/DECODE">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
</activity >
but I had to create DecodeActivity and copy the setup code from the MainActivity, this for example caused problems like they share some resources (photo picker) that gets ambiguous between activities and navigate from the DecodeActivity to the MainActivity, because it initially uses the MainActivity.
Here I'm resolving the incoming intent:
if (Intent.ActionSend.Equals(Intent.Action) && Intent.Type != null && Intent.Type.StartsWith("image/"))
{
await ImageDispatcher.HandleSendImage(ContentResolver, Intent, "Encode");
}
The two intent filters differ only by the label, which does not affect the function of the filter in any way.
I think you should have two activities (one for each operation), and both should have the same base class. Put the operation-specific code in the operation-specific activities.
Alternatively, you may ask the user what to do with the image.
I have integrate deep linking in android app .I get result like below image and already app install in my phone but When i click on link from message Application after app icon not show in launcher list. I don't know what is wrong in my code implementation .Thanks in advance.
Here is my menifests file code
<activity
android:name=".activity.SplashActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#style/AppTheme.Splash"
android:windowSoftInputMode="stateHidden"
android:launchMode="singleTask">
<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" />
<!-- handle website links -->
<data
android:host="www.abc.in"
android:pathPattern="/event"
android:scheme="https" />
<data
android:host="abc.in"
android:pathPattern="/event"
android:scheme="https" />
</intent-filter>
</activity>
Here is my activity code
private void handleIntent() {
// ATTENTION: This was auto-generated to handle app links.
Intent appLinkIntent = getIntent();
String appLinkAction = appLinkIntent.getAction();
Uri appLinkData = appLinkIntent.getData();
if (Intent.ACTION_VIEW.equals(appLinkAction) && appLinkData != null){
String recipeId = appLinkData.getLastPathSegment();
Log.e(TAG,"recipeId ="+ recipeId);
}
}
The host you clicked does not match to your deeplink.
If you clicked: https://abc.in/event. it will work.
If you want to support deeplink from like the sample above, you should this on your current intent-filter
<data
android:host="maps.google.com"
android:pathPrefix="/maps"
android:scheme="http" />
Edit:
To support this link: https://abc.in/event/-chakravyuh-featuring-nitish-bharadwaj/1073. You need to add the following.
<data
android:host="abc.in"
android:pathPrefix="/event"
android:scheme="https" />
I am trying to enable deeplinking in my app. Here is the code I am running in AndroidManifest to achieve it:
<activity
android:name=".ui.WalletActivity"
android:label="#string/title_activity_wallet">
<intent-filter android:label="#string/title_activity_link_wallet" >
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="myapp"
android:host="wallet"
/>
</intent-filter>
</activity>
Is there anything else I need to do in order to make tapping on myapp://wallet to open WalletActivity of my app?
In my app, this works fine:
<activity
android:name=".ui.WalletActivity"
android:label="#string/title_activity_wallet">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<intent-filter>
<data android:scheme="myapp" android:host="wallet" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
I also have extra parameters (myapp://wallet?id=42), which I parse like this:
Intent intent = getIntent();
String providerUrl = intent.getData().toString();
UrlQuerySanitizer sanitizer = new UrlQuerySanitizer();
sanitizer.setAllowUnregisteredParamaters(true);
sanitizer.parseUrl(providerUrl);
String id = sanitizer.getValue("id");
(You can read about UrlQuerySanitizer here)
To test, I'd suggest to send the myapp://wallet link to yourself via email, for example :-) (or adb, as mentioned in the comments)
To test and make sure that your intent is working, you can use adb command as suggested in the deep linking docs
To pass parameters in your uri, simply add them as a normal query parameter (i.e. example://gizmos/path?key=value, then retrieve them by parsing the intent data like this:
Uri uri = getIntent().getData();
String value = uri.getQueryParameter("key");
Make sure you check for nulls etc.
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
this is in my manifest file
this will make my app appear on the share list of all apps
but I want my app to appear in the share list of another specific app
and I don't own the other app
Add this code in the activity you want opened first when sharing a content from outside the app, call this method in onCreate()
private void onSharedIntent() {
Intent receiverdIntent = getIntent();
String receivedAction = receiverdIntent.getAction();
String receivedType = receiverdIntent.getType();
if (receivedAction.equals(Intent.ACTION_SEND)) {
// check mime type
if (receivedType.startsWith("text/")) {
String receivedText = receiverdIntent
.getStringExtra(Intent.EXTRA_TEXT);
if (receivedText != null) {
//do your stuff
}
}
else if (receivedType.startsWith("image/")) {
Uri receiveUri = (Uri) receiverdIntent
.getParcelableExtra(Intent.EXTRA_STREAM);
if (receiveUri != null) {
//do your stuff
fileUri = receiveUri;// save to your own Uri object
Log.e(TAG,receiveUri.toString());
}
}
} else if (receivedAction.equals(Intent.ACTION_MAIN)) {
Log.e(TAG, "onSharedIntent: nothing shared" );
}
}
Add this in Manifest,
<activity
android:name="your-package-name.YourActivity">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
<data android:mimeType="text/*" />
</intent-filter>
</activity>
In order to do this, you need to know the Intent that the application is creating and create an IntentFilter that will add your application to the specific list.
Receiving an Implicit Intent on Intents and Filters (Android Developers)
The application probably uses a specific action name that you could hook to.
<intent-filter . . . >
<action android:name="com.example.project.SHOW_CURRENT" />
<action android:name="com.example.project.SHOW_RECENT" />
<action android:name="com.example.project.SHOW_PENDING" />
. . .
</intent-filter>
Or it could be looking for applications accepting a certain type of file.
<intent-filter . . . >
<data android:mimeType="video/mpeg" android:scheme="http" . . . />
<data android:mimeType="audio/mpeg" android:scheme="http" . . . />
. . .
</intent-filter>
The name of the application and what it is sharing would help me give a more specific response.
- Add below code into your Project AndroidManifest.xml file in Specific Activity.
<activity
android:name=".MainActivity"
android:theme="#style/Theme.AppCompat.Light.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
- Add the following line of code into your project specific Activity.
Intent intent = getIntent();
String action = intent.getAction();
String type = intent.getType();
if ("android.intent.action.SEND".equals(action) && type != null && "text/plain".equals(type)) {
Log.println(Log.ASSERT,"shareablTextExtra",intent.getStringExtra("android.intent.extra.TEXT"));
}
add this to your mainefist file
<activity android:name=".ShareActivity">
<intent-filter
android:label="Share with my app">
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
this link may help you
this worked well for me for getting all web pages, for my app that scans for mp3 files on a web page, and sets alarms from them. It opens up my new url activity, when you share a web page:
Here is what this code results in:
<activity
android:name=".NewUrl"
android:label="#string/title_activity_new_url"
android:windowSoftInputMode="stateUnchanged">
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/*"/>
</intent-filter>
</activity>
Then to receive the link in the app, I got awsome info from this tutorial:
http://code.tutsplus.com/tutorials/android-sdk-receiving-data-from-the-send-intent--mobile-14878
I want to add something to the above answers. Keep in mind that you should put another intent filter to prevent overriding in case you are using multiple categories in an activity.
For example, the following will prevent your application to be shown on the application list in your device because it doesn't detect it as launcher activity.
Don't do this
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<!-- DO NOT DO THIS-->
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
</activity>
</application>
Instead do following
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- USE SEPERATE INTENT FILTER -->
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
</activity>
</application>
Note: Change mimeType according to your use.
Verdict: If you are using more than one category in intent filter use them separately.
I would check to see if there is any API for this app you want to work with.
If so, you can benefit by knowing
a more specific implicit action for your filter
or perhaps add a category other than DEFAULT
If you can find something like these, it would be unlikely to be seen by other apps.
Also make sure to have you Activity NOT labeled with android:exported="false", otherwise it won't show up in other applications' intent choosers (only your own)
E.g. AndroidManifest.xml
<activity
android:name=".ReceiveImageActivity"
android:exported="true"> <!-- here -->
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
Im trying to create my own url scheme so my android app can get called via an URL but for now I dont have a success.
Im trying to have this url to work : cedemo://com.cedemo.scan?X=toto
Here is part of my manifest file :
<activity android:name=".Gallery1" android:label="#string/app_name" android:launchMode="singleTask" android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.GALLERY" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="cedemo" android:host="com.cedemo.scan" />
</intent-filter>
</activity>
Does anyone can help telling me what is wrong ?
Also, if someone find what is wrong, can someone tell me how I read the "X" variable from inside the android code from my app ?
Update:
Update: I did the modification of the action (as advised in one of the answers) and it's worked fine. The thing is that I still cannot get the url variable value. Here is the code I tried.
final Intent intent = getIntent();
final String myScheme=intent.getScheme();
final Bundle myBundle=intent.getExtras();
final boolean inContestKey;
if (myBundle != null) {
inContestKey=myBundle.containsKey("inContest");
}
final Uri myURI=intent.getData();
final String value;
if (myURI != null) {
value = myURI.getQueryParameter("inContest");
}
But I receiving null from all the functions… what else can i do?
May be I should explain better the context of my software:
My software is started
My software launch then the browser
the user click a link in the browser and the browser go to the url scheme, back to the software with a variable "X" (for example)
the software should read the variable "X"
But in my case : myScheme, myBundle, myURI are set to null.
Any ideas ?
Update:
I found the answer is that you have to be in the main activity to do that.
I think the problem is with the Action you defined.
There is a "android.intent.action.VIEW" which is what I think you want.
<activity android:name=".Gallery1" android:label="#string/app_name" android:launchMode="singleTask" android:screenOrientation="portrait">
<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="cedemo" android:host="com.cedemo.scan" />
</intent-filter>
</activity>
Try that and I bet will resolve correctly. I only made this assumption because you included the browsable category which is usually used by the Browser, which does not know of any of your custom actions. If you do want the GALLERY action as you have implied then just create 2 filters
<activity android:name=".Gallery1" android:label="#string/app_name" android:launchMode="singleTask" android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.GALLERY" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="cedemo" android:host="com.cedemo.scan" />
</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="cedemo" android:host="com.cedemo.scan" />
</intent-filter>
</activity>
So within the contents of your activity you can do something like:
// Value should be "toto" as in your example
String value = getData().getQueryParameter("X");
What finally fixed things for me was changing the order of the XML elements. Specifically, swapping the data and action rows so data is before action made it start working.
<intent-filter>
<data android:scheme="myappname" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
And for completeness, my link in the html is "myappname://noop".
One more thing, i would like to throw light. Initially it was not working for me because i was using Main/Launcher tags before View/Default/Browsable/data.
Once i changed the order it started working fine.
i.e Initially not working code
<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="myapp" />
</intent-filter>
correct code order
<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="myapp" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
and way to test for android is very simple.
Make any html file insert
test to launch myapp <br /><br />
just open this html file and click on test to .... :-)