I have created an application that successively adds appointments to a calendar. However i wish now to be able to click the "New Event" button in a calendar program eg. aCalendar and have my program popup. and i think i am a little lost.
in my AndroidManifest.xml
<receiver
android:name="com.johnny.CalendarAdd"
android:enabled="true"
>
<intent-filter>
<data android:pathPrefix="vnd.android.cursor.item/event" />
<action android:name="android.intent.action.EDIT" />
</intent-filter>
</receiver>
tryed to change it to.
<activity android:name="CalendarAdd">
<intent-filter>
<data android:pathPrefix="vnd.android.cursor.item/event" />
<action android:name="android.intent.action.EDIT" />
</intent-filter>
</activity>
In class file
package com.johnny;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class CalendarTest extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("CalendarAdd", "CalendarAdd.onReceive called!");
}
}
when i click the "New Event" button i don't get my app in the list.
I have had a look-around and think i have missed something simple or i am Totally on the wrong path.
Thanks for any Help in advance.
You can't achieve it using Broadcast Receiver, Broadcast intent-filter will work only when some app broadcast that particular intent, e.g connectivity state got changed, screen got turned off, battery low etc are correct example of system broadcasts. While create calendar event can't be a broadcast & thats why you can't receive it.
From android documentation regarding Broadcast Receivers:
A broadcast receiver is a component that responds to system-wide
broadcast announcements. Many broadcasts originate from the system—for
example, a broadcast announcing that the screen has turned off, the
battery is low, or a picture was captured. Applications can also
initiate broadcasts—for example, to let other applications know that
some data has been downloaded to the device and is available for them
to use. Although broadcast receivers don't display a user interface,
they may create a status bar notification to alert the user when a
broadcast event occurs. More commonly, though, a broadcast receiver is
just a "gateway" to other components and is intended to do a very
minimal amount of work. For instance, it might initiate a service to
perform some work based on the event.
For achieving desired functionality, you need to register intent-filter for your activity.
Also your manifest should contain read/write calendar permission and event edit/insert intent-filter, e.g.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.CalanderTest"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8"/>
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<application android:label="#string/app_name" android:icon="#drawable/ic_launcher">
<activity android:name="MyActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.INSERT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/event" />
</intent-filter>
</activity>
</application>
</manifest>
for testing it out do below in onclick of some test button:-
#Override
public void onClick(View view) {
super.onClick(view);
if (view.getId()==R.id.create_event)
{
Intent i = new Intent(Intent.ACTION_INSERT);
i.setType("vnd.android.cursor.item/event");
startActivity(i);
}
}
On clicking of my test button i got menu like in below image, so above code works fine to show your app in App chooser dialog for adding/editing calendar events.
Now in your activity you can handle this intent using getIntent() and perform action accordingly.
You can have a look here for extras supported by Calendar event.
Like Events.TITLE,Events.EVENT_LOCATION etc. If you are going to create your own calendar event creator, then you need to handle all such extras Gracefully, for awesome user experience.
Place the <intent-filter> you defined inside your <activity> instead. The user should be given a list of apps (including yours) that can handle that action, so they can select yours if they want to.
<receiver>s are for receiving BroadcastIntents, which are a bit different.
Use <receiver> as you originally did, and android:name should be com.johnny.CalendarTest if you wish to register your receiver, since your receiver class name is CalendarTest.
See here
android:name
Required name of the class implementing the receiver, deriving from BroadcastReceiver.
However i wish now to be able to click the "New Event" button in a
calendar program eg. aCalendar and have my program popup.
Have you tried the various action and category filter declarations in your <intent-filter>.
For instance:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.PICK" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.OPENABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/myapp" />
</intent-filter>
See if any of those help you.
See also: http://developer.android.com/reference/android/content/Intent.html
From CalendarController, I can almost be sure that these intent are explicit intent with specific component set. For example, in launchEditEvent method.
private void launchEditEvent(long eventId, long startMillis, long endMillis, boolean edit) {
Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventId);
Intent intent = new Intent(Intent.ACTION_EDIT, uri);
intent.putExtra(EXTRA_EVENT_BEGIN_TIME, startMillis);
intent.putExtra(EXTRA_EVENT_END_TIME, endMillis);
intent.setClass(mContext, EditEventActivity.class);
intent.putExtra(EVENT_EDIT_ON_LAUNCH, edit);
mEventId = eventId;
mContext.startActivity(intent);
}
The intent is set to be handled by EditEventActivity. So it is impossible to receive such intents in your application. I think the Calendar App make it as an explicit intent because it regard this as an in-app event. If this is not an explicit intent, your code should work, because the component in Calendar App is almost same with what you did.
<intent-filter>
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.INSERT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/event" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.INSERT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.dir/event" />
</intent-filter>
The aCalendar New Event Intent is as this.
{act=android.intent.action.EDIT typ=vnd.android.cursor.item/event flg=0x20000000 cmp=org.withouthat.acalendar/.edit.EditActivity (has extras)}
And Google Calendar App New Event Intent is as this.
{act=android.intent.action.VIEW cmp=com.android.calendar/.event.EditEventActivity
They are explicit intent.
Your can not receive this intent in your app.
More about intent click here
<activity android:name="com.johny.CalendarTest"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.EDIT" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.ALTERNATIVE" />
<data android:host="com.android.calendar" />
<data android:host="calendar" />
<data android:scheme="content" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.EDIT" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.ALTERNATIVE" />
<data android:mimeType="vnd.android.cursor.item/event" />
</intent-filter>
</activity>
This was the exact code i used and got to work.
Most of The Answers helped in getting the response.
The reward went to the person who put most effort into it and achieved what was a result.
The old answers show me the direction, but I had to do a small modification to make it work:
<activity
android:name=".YourActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.INSERT" />
<action android:name="android.intent.action.EDIT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.dir/event" />
</intent-filter>
</activity>
Related
I found several answers on this issue, but it's not working for me. If you click a phone number in an email or on a website, a default dialer popup comes up to select the dialer/skype etc.
I'm trying to get my app in that list - so I don't want to handle the actual call, but open the activity and show the number the user clicked on.
I've tried this:
<receiver android:name=".MyOutgoingCallHandler">
<intent-filter>
<action android:name="android.intent.action.ACTION_DIAL" />
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
But it's not showing in the list. What intent should I filter for?
If you want to add an Activity to the list of Activitys that will be shown to the user as possible phone dialers, you need to have an Activity and the <activity> definition must contain this intent-filter> in the manifest:
<activity ...>
<intent-filter>
<action android:name="android.intent.action.DIAL" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
What you've got is a BroadcastReceiver that will receive the outgoing call Intent. That's something different.
The official Android Developers blog has covered this process. You can read all about it there.
Your intent filter looks like it has the correct action, so it may be that you have not requested the correct Android permission.
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
Here is how the Android Developers blog suggest you declare the broadcast receiver.
<manifest>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<application>
...
<receiver android:name=MyOutgoingCallHandler">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
...
</application>
</manifest>
I am trying to detect the uninstall action of my application. Till now, I have got a specific code that catch the uninstall action and inflate an Activity. Here is the code:
Manifest:
<activity
android:name=".UninstallActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.DELETE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="package" />
</intent-filter>
</activity>
I have created a simple Activity called UninstallActivity and It works fine. When the user try to uninstall the app this Activity has been inflated.
I am trying to listen on those intents with a Receiver instead of Activity but I have failed to get this action. My code is:
Manifest:
<receiver android:name=".PackageUninstallReceiver" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.DELETE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="package" />
</intent-filter>
</receiver>
PackageUninstallReceiver:
public class PackageUninstallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("uTag", "In the PackageUninstallReceiver onReceive()");
if (intent.getAction().equals(Intent.ACTION_DELETE) && intent.getDataString().contains(context.getPackageName())) {
Log.d("uTag", "Uninstallation is being happened....");
}
}
}
First, is it possible to listen to this Intent with the receiver?
If yes, what is wrong with my code?
The Intent used to start an Activity (in this case, an Intent to VIEW or DELETE a PACKAGE) is a completely different thing from a braodcast Intent. They share some of the same properties, but are still completely different things. a broadcast Intent will never start an Activity and an Intent used to start an Activity will never be seen by a BroadcastReceiver.
Therefore, the answer to your question
First, is it possible to listen to this Intent with the receiver?
is "no".
The actions you are listening are generic and could be applied in any context with a different schema. What you should be listening to is the package changing.
<receiver android:name="PackageChangeReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_REPLACED"/>
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
<data android:scheme="package"/>
</intent-filter>
</receiver>
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.
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
}
}
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>