Android - Intent Filter? - android

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>

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.

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.

Action Intent causing a ActivityNotFoundException while starting another activity

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>

Making my Service accessible using intent-filter

I want my service to be accessible as one of the default options of the Share page when the user long-touches the web-link (standard android feature). This is what I wrote in the manifest file :
<service android:name=".ShareLink"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</service>
But it is still not being displayed. What am I doing wrong? P.S. When I do the same thing with the Activity - it works fine.
This is not possible, You will have to write a Dummy Activity to do this.
This is because, ResolverActivity that shows the names or selects the appropriate component to launch gets the list by querying Only Activities that match intent with API PackageManager.queryIntentActivities
This should do it:
<intent-filter
android:label="Open Using My Service">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
</intent-filter>

Intent filter is not working for calling screen

I am designing a custom calling screen to show information, such as the caller's address book info, on screen during the phone conversation.
My app will begin when the user presses the call button by use of an Intent Filter, after which I will fetch other information from the address book and add it to the screen.
My problem is that when the call button is pressed, my activity is not launching. Is my intent filter right? Is it even possible to intercept the phone call Intent? Please share your knowledge on handling call event.
My Intent Filter is shown below.
<activity android:name=".MyCallingScreen">
<intent-filter android:priority="100">
<action android:name="android.intent.action.CALL_BUTTON" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="tel" />
</intent-filter>
</activity>
In your case try to change your code following way:
<intent-filter android:priority="100">
<action android:name="android.intent.action.CALL_BUTTON" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
It's work for me if press on a call button.
Try to use following code to intercept the call:
<activity>
<intent-filter>
<action android:name="android.intent.action.CALL_PRIVILEGED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
For HTC some changes there:
<activity>
<intent-filter>
<action android:name="android.intent.action.CALL_PRIVILEGED" />
<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>
Intent with action android.intent.action.CALL_PRIVILEGED is called when you making a call from phonebook by following way: Phone Book->Contact->Phone number Long Click -> Choose make call from dropdown menu.
I'm not sure if it's possible to replace the call screen but it is relatively simple to intercept any outgoing call. You declare in your manifest a receiver:
<receiver android:name="com.mystuff.CallInterceptor" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
and you make a Java class for this interceptor:
public class CallInterceptor extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (!intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL"))
{
return;
}
String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
//do stuff using the number
//assuming you do nothing too bad the call will happen and the regular
//call screen comes up - but you can bring up another activity on top of it
//for example shwing address info
}
}

Categories

Resources