I am trying to read (first time - new to me) a gmail attachment (.gcsb extension) in my app. The intent filter looks like this:
<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:pathPattern="*.gcsb"></data>
<data android:mimeType="application/*"></data>
</intent-filter>
and that appears to get the 'download' and 'preview' buttons to appear next to the attachment in gmail (without that filter, the buttons do not appear).
In the activity (onCreate() / onRestart()) I do:
....
Intent intent = getIntent();
if (!Intent.ACTION_VIEW.equals(intent.getAction())) {
// Deal with the file from gmail here
}
....
to check if it is gmail that has caused this to start the activity or not.
However intent.getAction() always resolves to android.intent.action.MAIN, so it never does anything. There is another intent filter in the activity:
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
being for the app launch, but I don't understand why I never see the android.intent.action.VIEW from gmail?
The answer appears to be that the activity was set to be 'single instance' for various reasons. This means that whilst it is brought to the foreground again, it comes back with the intent it was originally started with, not the one created by gmail.
Removing the 'single instance' attribute allowed the correct intent to be used.
Related
I have noticed that when someone shares a location in WhatsApp using WhatsApp location share feature, tapping on the location opens up application chooser which included both GMAP and Uber. Initially, it looked like it was something like the "ACTION_VIEW" intent with a "geo:" scheme. I am trying to make my Android app handle the "ACTION_VIEW" intent with a "geo:" scheme, but tapping on the location in WhatsApp is not working as expected. Here is my code in the AndroidManifest.xml file:
<activity
android:name=".MapActivity">
<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="geo"
android:host="*"/>
</intent-filter>
</activity>
When I tap on a location shared from WhatsApp, the Android system is not showing my app as an option in the app chooser. I have checked that my app is installed and that the activity is declared in the manifest file.
What could be the reason for the intent filter not working as expected, and how can I fix it? Does WhatsApp use any other type of DeepLink for this? When hovering or clicking the location from a PC, it redirects to https://maps.google.com/maps?q=23.7797847%2C90.4065005&z=17&hl=en
I was using similar intent filters. The main difference is that host is not specified. As I remember * in host should be used to match subdomains.
<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="geo"/>
</intent-filter>
I am attempting to get one activity to launh another via an intent and intent filter. Here is what I have.
In the launching activity:
Intent i = new Intent();
i.setAction("com.test.apps.CATAPP");
i.addCategory("com.test.apps");
this.startActivityForResult(i,APP_REQUEST_CODE);
The intent filter in the receiving app:
<intent-filter>
<action android:name="com.test.apps.CATAPP" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.test.apps" />
<data android:mimeType="text/plain"/>
</intent-filter>
This fails to work. However, if I take the example from Wei Meng Lee's Android 4 Development, it works and then only if the URI and the Intent.ACTION_VIEW are present.
Code in the launching app:
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("http://google.com"));
i.setAction("com.test.apps.CATAPP");
i.addCategory("com.test.apps");
this.startActivityForResult(i,APP_REQUEST_CODE);
Intend in the receiving app:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="com.test.apps.CATAPP" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.test.apps" />
<data android:scheme="http"/>
</intent-filter>
Where am I going wrong? Have I made a simple mistake?
I have spend the last couple of hours trawling stack overflow, for anwer to this but only found similar questions, with answers that did not solve my problem or were not applicable.
In your first example, your Intent is not going to match the IntentFilter of the Activity. You've specified a data element in the IntentFilter, but you've not set one on the Intent. You can either set the MIME type on the Intent:
i.setType("text/plain");
Or remove the <data> element from the <intent-filter> in the manifest, depending on your requirements.
If you just want to pass some simple text, set the Intent's type as shown above, and attach a String extra to it.
i.putExtra(Intent.EXTRA_TEXT, "Plain text.");
Then, to retrieve the text in the next Activity:
String plainText = getIntent().getStringExtra(Intent.EXTRA_TEXT);
if(plainText != null)
...
Note that the Intent.EXTRA_TEXT constant is merely a convenience. The extra key can be anything you want, as long as it's the same in both places.
I would like to be able to display my own calendar events, given an Android intent and a date to display. I believe that the intent to do so looks like this:
Intent { act=android.intent.action.VIEW act=content://com.android.calendar/time/1409565898789 }
And I have set up the Activity to handle this intent with an intent filter specified thus in my AndroidManifest.xml:
<activity
android:name=".MyActivity"
android:label="#string/title_activity_custom"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<!-- etc. -->
</activity>
In order to test this code, I load my application onto my test device and issue an intent using this command:
adb shell am start -a android.intent.action.VIEW -d content://com.android.calendar/time/1410665898789
But when I do so, the stock Android calendar is launched. I am never given an opportunity to view this time in another application. I think perhaps the Android system doesn't even recognize my Activity as a candidate for receiving this Intent.
I am not sure what I'm doing wrong and none of my searches have turned up the answer I'm seeking. Does anyone know what I'm missing?
You need to add the scheme, MIME type, and perhaps the host to your <intent-filter>. Now, I do not know what the MIME type is precisely, so I am guessing that the following <intent-filter> from the AOSP Calendar app is what you are seeking:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="time/epoch" />
<data android:host="com.android.calendar" />
<data android:scheme="content"/>
</intent-filter>
Your current <intent-filter> will match nothing, unless some app has a bug and tries starting an ACTION_VIEW activity with no Uri.
I want to share url's from other apps to mine.
I am using this Phonegap Plugin to implement the intents:
https://github.com/chrisekelley/olutindo-app/tree/master/plugins/com.borismus.webintent
Intents are working, but everytime i share an intent from another app, a new instance of my app is launched, but i want to use one instance. If the app is already opened, it should be reinitialized and brought to front or restarted with the shared intent initialization.
I tryed android:launchMode="singleTop", but the same behavior occurs, app would be opened multiple times.
My manifest entry:
<activity android:configChanges="orientation|keyboardHidden|screenSize"
android:name=".StartActivity"
android:label="#string/app_name"
android:launchMode="singleTop" >
<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>
<category android:name="android.intent.category.DEFAULT"></category>
<category android:name="android.intent.category.BROWSABLE"></category>
<data android:mimeType="text/plain" />
</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>
These is no initialization in my MainActivity because the intents would be initialized from javascript with a own function (See PG plugin above).
Edit: I tryed to use android:launchMode="singleInstance". Now on every share request my app would be brought to top, but the intent is not initialized. How can i initialize the incoming intent request again with cordova, if the app is already started?
Thank you!
I'm not sure how to workaround this. But i'm pretty sure that even if your code is launchMode="singleInstance" or singleTask, the OS will open an different Instance for each intent.action.
The only way to workaround i did find is creating a empty activity that calls your activity with a unique intent.action.
final Intent myIntent = new Intent(this,
MainActivity.class);
myIntent.setAction("android.intent.action.MAIN"); //myIntent.setAction(Intent.ACTION_MAIN);
startActivity(myIntent);
You can do a listening service. When you try to share the service get launched and it opens your activity if one intent.action aways.
I have an activity that works as a hook for various intents. Specifically, the VOICE_COMMAND and CALL_PRIVILEGED. (It is a requirement to use these.)
<activity android:name=".MyActivity"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.VOICE_COMMAND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.CALL_PRIVILEGED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="tel" />
</intent-filter>
</activity>
I ask the user to set my app as the default action for these intents so they don't have to select it every time. This is also a requirement.
The problem is that in certain cases I want my activity to work transparently and pass the intent to the dialer or other app. This should be selectable by the user. I achieved this by using getPackageManager().setComponentEnabledSetting(myCompName, isEnabled, PackageManager.DONT_KILL_APP) on my activity in certain places of the code.
Is there a more elegant way to do this? I tried startNextMatchingActivity(getIntent()) but that does not start anything (returns false). Does this mean that if there is a default action, then everything else is ignored from the intent resolution?
Currently (on Android 2.3) there seems to be no other way of forwarding the intent than doing it manually. Additionally, to send CALL_PRIVILEGED intent the app must have special permissions that only system apps have. (The app will receive not allowed exceptions otherwise.)
All in all, the intent must be converted to some other intent that my app can send and start the next activity manually by retrieving the list of applicable activities from the PackageManager.queryIntentActivities() API.