I want to detect calls and delete certain numbers from call log from background. Below are the options I have considered. Please advise if any of these or another is a better/workable solution.
Register phone state broadcast receiver. Delete number from call log in onReceive. The problem is that the call log may not have been updated at this point and thus the delete will have no effect.
Register phone state broadcast receiver. In onReceive somehow add a delay and try to delete the call log after some time. The delay would give the system enough time to add a call log entry. This approach seems a bit hacky to me, not keen on this.
Register phone state broadcast receiver. In onReceive register content observer for call logs. My understanding is that after on receive the process may get killed at any time so content observers onChange will not get called if the process has been killed.
Register phone state broadcast receiver. In onReceive start my service (if not already running) which then has a content observer registered. Delete call log entries matching certain numbers in content observer onChange.
Thanks,
Option 4 is a perfect way to do it.
I would suggest that you stop your service after finishing the work and let the broadcast receiver restart it whenever required.
Edit : You may also note that BroadcastReceiver is only for performing some small or light work so delaying is not an option here. :)
Related
I have a call recording app that reacts to call state changes from a dedicated BroadcastReceiver.
BroadcastReceiver is registered correctly in my manifest, along with the PROCESS_OUTGOING_CALLS and READ_PHONE_STATE permissions.
My issue is that for some reason, in some of the calls I get the CALL_STATE_OFFHOOK state broadcast several minutes after call has already ended.
It seems that the broadcasts are somehow stuck, and then triggered after a while. The 'CALL_STATE_IDLE' subsequent broadcast is received approximately after X time since CALL_STATE_OFFHOOK broadcast, where X is the time the actual call took.
My logs verify that previous onReceive calls are not hanging the process or the BroadcastReceiver.
What can be the cause for such behavior?
UPDATE:
I found that this occurs after I turn my Wi-Fi on or off and start a call relatively close to Wi-Fi change.
Is this the cause for the issue or a symptom of the actual issue?
In Android System, broadcast are processed internally.
Sometimes, due to system loading/ restart/ high runtime, the broadcast receiver gets time to receive some intent
Workaround is, to add Flag FLAG_RECEIVER_FOREGROUND to intent sending broadcast
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
This will speed up the broadcast delivery much than before in problem scenario
It turned out to be a bug in the Broadcast sending by android (or alternatively some malfunctional receiver). Investigating log cat showed that some system receivers did get broadcasts on time while others (prior to mine) received it after a long time.
This happens frequently whenever Wi-Fi state changes during call start.
What I did was creating an ITelephony proxy (credit to End call in android programmatically) and monitor its state.
Thanks for the helpers :)
I need my app to monitor (and parse) outgoing calls (among other things).
There is a broadcast for that "NEW_OUTGOING_CALL" but it is fired when starting the call and I need to know when is it actually finished.
For that I could create a PhoneStateListener and listen to "LISTEN_CALL_STATE" but it gets fired too soon again as the call is not yet inside the call log database. (I could launch a timer but.. beurk..)
On last resort, I can put a ContentObserver on the CallLog URI (and get rid of the multiple calls) and detect the new entries.
That's actually how I'm trying to do (the third option), but for that I of course need to register my ContentObserver, hence the question : where and when should I register it ?
Apparently, the answer seems to be : within a Service..
But then when to start the service ?
I need it on start of my application to catch up with missing entries, so I would need to start the service from all the "callable" activities... Here the app needs to be manually opened, could be a problem after a reboot.
I need it whenever a new call is made : can be achieved with the BroadcastListener on "NEW_OUTGOING_CALL", starting the service if it's not already on. Get rid of the reboot problem here (as long as the app has been launched once and not user-killed since then)
But what would be wrong by registering them within the Application.OnCreate() ?
I already need to subclass the Application (or at least that's how I handled other things)
from my understanding, the Application.OnCreate() is going to be called anyway either when one of my Activity is created (first time), or my BroadcastReceiver (after a reboot) starts the service, anything that needs my process to start...
Service lives also as long as my process lives.
I don't need an extra Service for that, don't have to bind, start etc...
So is there anything wrong registering ContentObserver in Application.OnCreate() or what would be the advantage of using a Service for that ?
UPDATE :
On the pro-service I'll just discovered that :
If I want my application to start at boot_time, I listen to "BOOT_COMPLETED" with my BroadcastReceiver right ? So my process will be created, and I can register my ContentObservers... but then it will be quickly destroyed :
07-24 15:44:50.260: I/ActivityManager(531): No longer want com.test.test (pid 1829): empty #17
That's because Android flagged it as a "Level 5 : Empty process". Why ? Because registering ContentObservers don't make my Process "not empty".
Starting a service on the other hand makes my process a "Level3 : Service process" and it won't get cleaned anymore (at least not right away..) so if later on I launch the app, the process is already here, quietly listening...
I'm reading the documentation now, and I have 1 thing to be fixed - please, tell me, what is difference between broadcast receiver and activity (without the fact that activity can show UI)? Broadcast receiver gets announcements using intent-filter, but Activity can do it too! Please, make me clear. Thank you.
Activity is something which work on your input or require an user intruption for launching any task but with the help of broadcast reciever you can listen the system services as once a broadcast receiver is started for listening incoming calls then each time when a incoming call it will launch your method what you have written for that for more explanation check these
http://developer.android.com/reference/android/content/BroadcastReceiver.html
http://www.vogella.de/articles/AndroidServices/article.html
You basically have it. An Activity is intended to be associated with a UI. By contrast a Broadcast receiver only 'catches' intents broadcast through the app / system. However, there are also implications for how the object is loaded into the system, and how long it sticks around. From the BroadcastReciever documentation:
A BroadcastReceiver object is only valid for the duration of the call to onReceive(Context, Intent). Once your code returns from this function, the system considers the object to be finished and no longer active.
This has important repercussions to what you can do in an onReceive(Context, Intent) implementation: anything that requires asynchronous operation is not available, because you will need to return from the function to handle the asynchronous operation, but at that point the BroadcastReceiver is no longer active and thus the system is free to kill its process before the asynchronous operation completes.
Keeping these differences in mind, the system may be able to more efficiently execute pieces of your app...
Activity is only active when you open it. When it is moved to the background, it is either paused or shut down.
A listener is always active on the background. The only thing that can "activate" a listener, is the thing it is listening for. Ex.: a broadcastlistener will detect (and react) when you receive a phonecall/sms, but will ignore the fact that you set your alarm (since it only pays attention to incoming/outgoing broadcasts)
the intent filter does pretty much the same thing for both, the difference is just how it is called. With activities, it requires the user to do something; with listeners, it requires the listener to be triggered.
At first, it sound like a simple thing to do but I found it no so simple.
What I'm trying to achieve is to have my android app return to a certain state after an it went to the background upon an incoming call.
The question is, what is the best way to know whether my app went to foreground after the user rejected or ended an incoming call (that occurred while my app was in the foreground)?
I know I can use broadcast receivers to identify incoming calls.
Thanks.
You should look at Activity Lifecycle
Once you app is resumed/restarted onResume/onRestart would be called, you do not need to listen for broadcast unless you are doing something with audio that will hamper the ongoing call.
Basically you can trust Android to reactivate your activity from background and call onResume() method. When your activity is about to be put to background, onPause() will be called ( and this is only reliable callback )
Things are simple, with a Broadcast receiver I intercept the phone call. Because calling broadcast can't be aborted, the InCallScreen appears and the call get's stored in Call Log. I manged somehow to block the InCallScreen from appearing now I need to do something about the call log. So, I've got the phone number and the date of the call. How do I delete it from the Call log ? If I get the list of items from the Call Log uri, my call will always be the first in that list ?
The simplest solution was to start a service in the broadcast receiver, after the call state becomes ide. This service will have a sleep time of 5 seconds, time needed to make sure Android inserted the call into call log, and just then query the call log to get info about all calls.