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 )
Related
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. :)
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.
Have an app that carries out a number of tasks when the phone receives on sms message, and they all work fine. However, if I exit/ kill the app, I get a force close error when I receive an sms message.
It's almost like the app is still somehow running/ some methods like "onReceive" are still cached in memory. I need to ensure when the application is exited, that it is properly exited and the phone doesn't give the force close error.
Can anyone advise?
Here is the code for exiting the app which seems to work fine. (When I press back on the phone when inside the app and am back at android home screen, when I check advanced task killer; it is not listed)
#Override
public void onDestroy() {
super.onDestroy();
System.runFinalizersOnExit(true);
System.exit(0);
}//end onDestroy method
You should read some about how Android works:
Activity especially Activity Lifecycle part
Application Fundamentals
Tasks and Back Stack
Try to look at the system logs (adb logcat) there may be some messages about not unregistered/leaked recievers or something else similar.
Looks like you have some reciever that rely on some data, what was destroyed/nulled after your app shutdown.
Why are you doing System.exit(0)? Also runFinalizersOnExit is marked deprecated and unsafe in documentation.
Seems like you need to do unregisterReceiver(BroadcastReceiver) in onStop or onDestroy method depending on your needs.
It seems quite obvious that it is FYPSpeakerActivity has a null value in there. But based on your description, that probably should not ever be called.
How are you registering for text messages?
If you are using manifest.xml to define the broadcast receivers for text messages, then "Exiting" your app does nothing to prevent those.
If you are registering the broadcast receiver programatically, then you will need to unregister at some point. "Exiting" the app does not automatically unregister.
Furthermore, as in other posts you should read up on the application lifecycle. System.exit() is frowned upon, runFinalizerOnExit is deprecated, and onDestroy is not guaranteed to run.
I have a net service in my app, for now it doesn't matter if it's a thread in the Application context or a service, what does matter is i have some trouble getting response properly.
The service is working, and i do get responses, right now i work with the observer design patter which is a bitch in android :-( i have to remove the listener in on destroy and then check the network if it is all ready finished and handle different scenarios.
I want to change my approach, but i'm not sure what's the right android way, it seems like activities are made for polling which is bad for my architecture and error prone :-(.
I thought of the folowing two methods but non seem to give me a real solution:
create a braodcast receiver that
will send a broadcase with a flag if
response or error arrived from the
net, it's apt to the activity to
poll the right data and handle. i do
wonder about this since if i
register for broacast i basically
have to remove the listener in on
pause, so i CAN miss a broadcast,
then it's back to check the net
state in onCreate, same like what
i'm doing now - sucks...
register the activity that whats an event and sent it an intent using startActivity but here if the activity is in on pause or stop i'll bring it to the front, i don't want this kind of behavior, i only want that the activity will get the event no matter what, and starting to wonder if there's a way to do that.
The landscape\portrait event are killing me, any way out of it ?
i discovered the following:
i can decide to handle the
landscape\portrait events myself and
then i eliminate 90% of the problem
i can use Broadcast Receivers but with sticky flag on that will cause the intent to wait for me, i just have to check first if i got the intent once i'll gt it once more if it's sticky (meaning in landscape \ portrait i may get it twice on screen rotation)
if i get new intent that doesn't kill my app (depends on the intent) i get it in onNewIntent() method. i can put some init functions that are dependant on those values in a seperate init function that gathers them all to share them between onCreate and onNewIntnet.
I've got an Android app which has a periodic background Service. I want this Service to react differently depending on whether any Activities in my application are open. The issue is that the Service just keeps itself running via the AlarmManager making it on kind of on a separate "track" from the Activities, so I don't know whether the application is open when it runs.
The best solution I can think of is to flip a boolean on/off whenever onResume() or onPause() is called in all my Activities, but this seems like a lot of footwork. Is there a simpler, more elegant solution?
Is there a simpler, more elegant
solution?
Well, it depends a bit on what "react differently" means.
Let's suppose you want to raise a Notification if your activities are not in the foreground, but you want to pop a dialog if an activity is in the foreground.
In that case, you need some communication path from the service to the activity anyway. So, register a callback (supplied by the activity) with the service in onResume() and unregister it in onPause(). Your service uses the callback if one exists; if there is no callback, it raises the Notification.
You could accomplish the same thing with a broadcast Intent (register/unregister the receiver in the activity in onResume()/onPause()) if you wanted.