Action Intent causing a ActivityNotFoundException while starting another activity - android

My TestApp which launches the activity has the following code:
public void startOperaView() {
Intent browserIntent = new Intent("org.droidtv.nettvbrowser.VIEW");
Uri luri = Uri.parse("connectedplanet.tv/olvs/test");
//browserIntent.setClass(getApplicationContext(), Browser.class);
//browserIntent.setAction("org.droidtv.nettvbrowser.VIEW");
browserIntent.setType("application/vnd.droidtv.sta");
browserIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
browserIntent.setData(luri);
startActivity(browserIntent);
}
And the package "org.droidtv.nettvbrowser" has the following AndroidManifest.xml file:
<activity
android:name="org.droidtv.nettvbrowser.Browser"
android:configChanges="locale"
android:label="#string/app_name" >
<intent-filter>
<action android:name="org.droidtv.nettvbrowser.VIEW" />
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/vnd.droidtv.sta" />
</intent-filter>
</activity>
The weird part is that if I specify the actual package name in the intent it seems to work fine, Only the action intents are throwing these errors.Any help would be appreciated.Thank You.

Refer to http://developer.android.com/guide/topics/manifest/activity-element.html and you can try set android:exported="true"
android:exported
Whether or not the activity can be launched by components of other applications — "true" if it can be, and "false" if not. If "false", the activity can be launched only by components of the same application or applications with the same user ID.
The default value depends on whether the activity contains intent filters. The absence of any filters means that the activity can be invoked only by specifying its exact class name. This implies that the activity is intended only for application-internal use (since others would not know the class name). So in this case, the default value is "false". On the other hand, the presence of at least one filter implies that the activity is intended for external use, so the default value is "true".
This attribute is not the only way to limit an activity's exposure to other applications. You can also use a permission to limit the external entities that can invoke the activity (see the permission attribute).
Or you can refer to something like this:
<activity android:name="OutgoingCallBroadcaster"
android:theme="#android:style/Theme.NoDisplay"
android:permission="android.permission.CALL_PHONE"
android:configChanges="orientation|screenSize|keyboardHidden">
<!-- CALL action intent filters, for the various ways
of initiating an outgoing call. -->
<intent-filter>
<action android:name="android.intent.action.CALL" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="tel" />
</intent-filter>
<intent-filter android:icon="#drawable/ic_launcher_sip_call">
<action android:name="android.intent.action.CALL" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="sip" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.CALL" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="voicemail" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.CALL" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/phone" />
<data android:mimeType="vnd.android.cursor.item/phone_v2" />
<data android:mimeType="vnd.android.cursor.item/person" />
</intent-filter>
</activity>

Related

Including two intent-filters, sharing same activity, action, category and mimeType

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.

Android Intent-filter action name vs data scheme

In <intent-filter>, What is the advantage of specifying <data android:scheme=""> when one can specify a custom action name which other apps can use?
For e.g.
<activity android:name=".MyActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="foobar" />
</intent-filter>
</activity>
<activity android:name=".MyActivity">
<intent-filter>
<action android:name="com.example.myapp.FOOBAR" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
As in what advantage specifying foobar scheme gives me? Other apps can also launch my activity by specifying com.example.myapp.FOOBAR as Intent action and can send data in Intent extras.
I get that specifying scheme establishes a contract that other app has to use that scheme. But is there anything else I am missing?
If a scheme is not specified for the intent filter, all the other URI attributes are ignored. That's the basic point you are missing.

Application not appearing in activity chooser whenever outgoing call is made using dailer

What intent filter should be used so that my app is shown in activity chooser whenever outgoing call is made :like Viber and Skype are shown.
I am using this filter:
<receiver android:name="OutgoingCallReceiver" >
<intent-filter>
<action android:name="android.intent.action.ACTION_NEW_OUTGOING_CALL" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
with permission:
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
still myApp do not appear in activity chooser.
Declare your Activity as to add it in option list for calling application
<activity android:name="Makecall" >
<intent-filter>
<action android:name="android.intent.action.CALL" />
<data android:scheme="tel" />
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.CALL_PRIVILEGED" />
</intent-filter>
</activity>
and for calling to any Number use Intent.ACTION_DIAL as :
Uri numberuri = Uri.parse("tel:" + edit_text_number);
Intent intent_call = new Intent(Intent.ACTION_DIAL, numberuri);
startActivity(intent_call);
Surprisingly, I found I need to add action VIEW to my manifest for my dialer to appear in App Chooser. Still looking for an explanation for that.
So this is what worked:
<!-- language: lang-XML -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.DIAL"/>
<action android:name="android.intent.action.CALL"/>
<data android:scheme="tel"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
And when I added to the intent-filter
<!-- language: lang-XML -->
<data android:mimeType="text/plain"/>
my dialer did not appear in the App Chooser
You need a Main Activity for the Broadcast Receiver to be registered.
DO NOT use an activitythat intercepts CALL_PRIVILEGED Intent calls. Doing that will interfere with EMS calls. You were on the right track with your example.

Android - Intent Filter?

I am trying to register my Activity so that it can be used by the Activity chooser/picker allowing a user to choose whether or not to select my application/Activity to complete what they are trying to do.
I want to provide the option for the user to be able to select my application when they want to send an SMS message and when they want to place an outgoing call, to try to achieve this I added the following pieces of code within my Activity tags in my manifest:
<intent-filter>
<action android:name="android.intent.action.SENDTO" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
However the Activity chooser never appears and the native apps are used without providing a choice to the user. Can anyone see where I am going wrong?
EDIT:
I have figured out I need to add
<data android:scheme="sms" />
<data android:scheme="smsto" />
for the SMS message but what do I use for the outgoing call?
EDIT 2:
I have tried the following for the outgoing call:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.DIAL" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="tel" />
</intent-filter>
But again with no luck, has this been blocked from 1.6 on?
Edit 3:
This is what happens when I click Text Mobile:
So i want the same thing when I click Call mobile
I think it should help you
<intent-filter >
<action android:name="android.intent.action.CALL_PRIVILEGED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="tel" />
</intent-filter>
Tested on Android 2.1
This is because activities and services can not pickup outside intents on their own. You need to use a BroadcastReceiver. To implement this, do the following:
Extend Android's BroadcastReceiver class like so:
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Context context = getApplicationContext();
Intent sendIntent = new Intent();
if ( intent.getAction().equals(Intent.NEW_OUTGOING_CALL) ) {
sendIntent.setClass(context, MyActivity.class);
context.startActivity(sendIntent);
}
else if ( intent.getAction().equals(Intent.SOME_OTHER_INTENT) {
sendIntent.setClass(context, MyService.class);
context.startService(sendIntent);
}
// More else ifs for more intents you want to catch.
}
}
Then you need to declare the receiver in your manifest like this:
<receiver android:name="MyReceiver">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
// more intents you want to catch here
</intent-filter>
</receiver>
Only intents declared in the manifest will be caught by your Receiver, so if you want to catch several intents thrown by the system or other programs and want to do the exact same thing when their intents are caught then specify those intents here in the manifest and skip the if/else blocks in the onReceive method.
this worked for me
<activity
android:label="#string/app_name"
android:name=".TestIntentActivity" >
<intent-filter>
<action android:name="android.intent.action.CALL" />
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.CALL_PRIVILEGED" />
<data android:scheme="tel" />
</intent-filter>
</activity>
You need to add a priority to the intent filter so that Android takes it into account. For example:
<activity android:name="YourActivity">
<intent-filter android:priority="100">
<action android:name="android.intent.action.CALL_PRIVILEGED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>

Intent filter with vendor specific MIME type

The app AndroidVNC defines the following activity filter in its manifest:
<activity android:screenOrientation="landscape" android:configChanges="orientation|keyboardHidden" android:name="VncCanvasActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/vnd.vnc.config" />
</intent-filter>
</activity>
If it is possible to invoke this activity, you need a URI for the vendor specific MIME type vnd.vnc.config. Something to replace FOO in the following code is needed:
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("FOO"));
startActivity(intent);
So what string is needed for Uri.parse() to match a vendor specific MIME type like vnd.vnc.config? Given a vendor specific MIME type like vnd.vnc.config, in general how do you determine what string to pass into Uri.parse() to match such a MIME type?
===========================================
I've appended AndroidVNC's entire AndroidManifest.xml file at the bottom of this question.
Can a completely separate Android app invoke any or all of the activities specified
in this AndroidManifest.xml file? If so, what specific version of the following code would that separate app use to match and invoke each activity in the AndroidManifest.xml file?
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("FOO"));
startActivity(intent);
<provider android:name="Provider"
android:authorities="android.androidVNC.Provider" />
<activity android:screenOrientation="landscape" android:configChanges="orientation|keyboardHidden" android:name="VncCanvasActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/vnd.vnc.config" />
</intent-filter>
</activity>
<activity android:name=".gui.ListVncSettingsActivity" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".gui.InsertVncSettingsActivity">
<intent-filter>
<action android:name="android.intent.action.INSERT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.dir/vnd.vnc.config" />
</intent-filter>
</activity>
<activity android:name=".gui.EditVncSettingsActivity">
<intent-filter>
<action android:name="android.intent.action.EDIT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/vnd.vnc.config" />
</intent-filter>
</activity>
<activity android:name=".gui.DeleteVncSettingsActivity">
<intent-filter>
<action android:name="android.intent.action.DELETE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/vnd.vnc.config" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
Something to replace FOO in the
following code is needed:
Not necessarily. Call setType() on the Intent. Depending on how they implemented the activities, they may not even need FOO.
Given a vendor specific MIME type like
vnd.vnc.config, in general how do you
determine what string to pass into
Uri.parse() to match such a MIME type?
You ask the authors of the activity. Perhaps they are expecting to be processing links where a Web server serves up that MIME type. Perhaps they have an associated ContentProvider that serves up content with that MIME type. Perhaps they have other approaches in mind. In this case, they have a <provider> element, which is a clue.
Can a completely separate Android app
invoke any or all of the activities
specified in this AndroidManifest.xml
file?
It can certainly try. To determine what the activities expect, ask the authors of the activities, or read their source code. Particularly with respect to any Uri that the activities expect, you will not necessarily get enough information just by looking at the manifest. This is no different than a book: reading the table of contents is not the same as reading the book.

Categories

Resources