Cannot receive Uninstall broadcast - android

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>

Related

How to create a Receiver for creating a new Event

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>

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
}
}

Android Notification App

I'm currently working on an android application. I have to log any new installed app name whenever the user is installing/downloading a new third party app. How can I get the notification if the user is installing a new app. Thanks in advance.
Java File
public class ApplicationBroadcastService extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
System.out.print("-------");
}
}
Manifest
<receiver android:name=".applicationlog.ApplicationBroadcastService">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_CHANGED" />
<action android:name="android.intent.action.PACKAGE_INSTALL" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<action android:name="android.intent.action.PACKAGE_REPLACED" />
</intent-filter>
</receiver>
But still I do not enter the onReceive method, when I am installing/uninstalling any app.
Here is the solution:
I did a small change in my Manifest file.
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_CHANGED" />
<action android:name="android.intent.action.PACKAGE_INSTALL" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<data android:scheme="package" />
</intent-filter>
Now it's working fine.. :)
Thanks again #willytate
Ajay,
You will need to setup a BroadcastReceiver with an intent filter to receive the following Action: ACTION_PACKAGE_ADDED then from the onReceive() method of the BroadcastReceiver you can launch a Notification.
Take a look at the intent documentation. You are looking for ACTION_PACKAGE_INSTALL (which seems to be never used, see comments) and ACTION_PACKAGE_REMOVED.
You can listen for the android.intent.action.PACKAGE_ADDED intent.

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>

Can't receive broadcasts for PACKAGE intents

I am trying to register a Broadcast Receiver to receive broadcast events for the package events. Following is the code and my receiver in the manifest file. The log statment never happens, but I can clearly see the same broadcast firing for "HomeLoaders" (the Launcher) debug statements. What am I missing?
public class IntentListener extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.i("INTENT LISTNER:", intent.getAction());
}
}
<receiver android:name="IntentListener" android:enabled="true" android:exported="true">
<intent-filter>
<data android:scheme="package"></data>
<action android:name="android.intent.action.PACKAGE_ADDED"></action>
<action android:name="android.intent.action.PACKAGE_ADDED"></action>
<action android:name="android.intent.action.PACKAGE_CHANGED"></action>
</intent-filter>
</receiver>
It is possible that these Intents cannot be received by components registered in the manifest, but only by receivers registered in Java via registerReceiver().
These three intents namely,
Intent.ACTION_PACKAGE_ADDED
Intent.ACTION_PACKAGE_REMOVED
Intent.ACTION_PACKAGE_CHANGED
when broadcasted by the system, have
Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
flag added so that only the registered receivers will receive the broadcasts and no broadcast receiver components will be launched. Refer Intent and PackageManagerService class of source for further details.
This is my manifest, without
<category android:name="android.intent.category.DEFAULT" />
My app detects only the Android Market app install, but does not remove. Now it receives also the non-Android Market app broadcasts.
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:label="#string/app_name"
android:name=".SomeActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="com.som.pakage.PackageInstallReceiver" >
<intent-filter >
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="package" />
</intent-filter>
</receiver>
</application>

Categories

Resources