What I want:
I am developing one app where I want to display dialog / popup on incoming call.
I have observed in log that there is slight delay between my activity start on incoming call and phone screen getting on. First activity gets fired and then phone screen gets on.
So I want to display this dialog after the phone screen gets on. In short I want to wait till phone gets on.
What I Tried:
I have used Asynctask in BroadcastReceiver
protected Boolean doInBackground(Void... params) {
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
isScreenOn = powerManager.isInteractive();
return isScreenOn;
}
and followed this answer. But it is giving me compile time exception
unhandled exception java.util.concurrent.executionexception even after searching a lot on google I was not able to solve it. So I used another approach.
I have created another* broadcast receiver for phone screen status as per this link
(*Note I already have incoming call broadcast receiver)
But I am not able to figure out how incoming call broadcast receiver will communicate to phone screen broadcast receiver and wait till phone screen gets on.
I have even tried to add intent action in existing broadcast receiver but again dont know how to wait till phone screen gets on.
Any pointers/suggestions?
After Struggling a lot on this issue, finally able to solve it. Posting the answer if anybody else struggling for similar issue.
case TelephonyManager.CALL_STATE_RINGING: //Incoming Call Ringing
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//Calling activity to show dialog / popup window.
}
}, 1000);
It was that simple. Phew!!
Related
I have an android application that needs to detect when the screen is going to lock.
is it possible to discover how long the screen will stay "UnLocked" for?
You will need to register a broadcast reciever.Your system will send a brodcast when device is going to sleep. Put the following code wherever desired:
private BroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(final Context context, final Intent intent) {
//check if the broadcast is our desired one
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF))
//here define your method to be executed when screen is going to sleep
}};
you will need to register your receiver:
IntentFilter regFilter = new IntentFilter();
// get device sleep evernt
regFilter .addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(receiver, regFilter );
ACTION_SCREEN_OFF is sent after the screen turns off and ACTION_SCREEN_ON is sent after the screen turns on.
UPDATE:
1.Method 1: As far as i know, you can not setup a listener before ur device goes to sleep.There is no such listener inside PowerManager. A solution which comes to my mind is to get the device time out from the settings and then setup a count down timer in your app. The countdown should be reset every time user touches screen. This way you may guess the time when the device goes to sleep and then setup a wakelock before the device goes to sleep and run your desired code and after that,disable the wakelock and the put the device to sleep.
2.Method 2: inPause() method of your activity is called when your device goes to sleep. You might be able to do some code there.Just a thought.
You have to use "Wakelock"..
try this code
PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "whatever");wl.acquire();
And don't forget to take permission in your menifest
"android.permission.WAKE_LOCK"
and write wl.release() in your pouse() method..
In general i have a service that sends an intent to my activity which is ALWAYS on every 6 sec and a BroadcastReceiver everytime on receive updates a timer.
I found by accident that after a while ( this is random ) that the particular receiver stops working.
OnPause i unregister it and onResume i register it again.
Also this happens randomly in any devices and android versions.
I found by researching on the web , that after onReceive the receiver is ready to killed by Android but mine keeps getting intents.
"Receiver Lifecycle
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.
"
FYI i have declare it like this inside my activity
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context arg0, Intent intent) {
Log.i("Intent received", "+_ " + intent.getAction());
if (intent.getAction().equals(TEST)) {
//do sth
} else {
//do sth else
}
}
}
Thans a lot even for taking the time to read :).
I dont declare anythin to my manifest and as for my logcat i must be over my phone the moment it happens. The service is a simple send broadcast after one async task. The last test i made was ensuring that the code from the service was running by logging the beeing sent. And the service kept on.
I am away from my code write now but i think there will be no help because is very simple. Thnaks
Well i could still figure out but I find a solution to my problem
Timer now is in the activity and receiver is sending the event but after 10000 tries i want to trigger the END EVENT. Now the receiver since he didn't work i couldn't get it but now i Start an intent with extras for the same activity always with flags new_task and clear_top.
No matter if my receiver is working or not, since the service is ok i will start the specific Activity and pseudo-show the END EVENT.
PS:: This behavior isn't always trigger but sometimes. So now i am ok.
If i am not understood please comment and ask anything. Thanks
I am developing an app that shows the location of the caller when an incoming call come on incoming call screen. I am succesfully fetching the location from my algorithm but I am not able to display it on Deafult Incoming Screen.
If i use A toast then it just appears for 1 or 2seconds, I want ihe information shoulkd appear till the call picked.
What should I use Toast, Notification or something , and how to do that.
In short how can I show something on Incoming Call Screen till the call picked up
class IncomingCallREceiver extends BroadcastReciever
{
void onRecieve()
{
// here I want to show the Information
}
}
You are not able to override Android's call screen, and with good reason, things may get spoofed!
With that said, a Dialog would most likely be the best solution to showing something before the user picks up. The easiest way to make a Dialog is with DialogFragments. However since Dialogs cannot be shown from receivers, you will need to start an Activity. So your onReceive() code should look something like this:
void onReceive(Context context, Intent intent)
{
Intent showDialogIntent = new Intent (context, DialogActivity.class);
showDialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startIntent (showDialogIntent);
}
And then when your DialogActivity is started, it's onCreate() method would make the Dialog and show it to the user.
I have a CPU intensive long-running operation (a few hours) that I am using AsyncTask to perform. As it continues, it updates a progressbar on the screen to show what percentage of the task is done.
I discovered that when my screen goes to sleep (time-out) the task seems to stop. Not sure whether this is happing because the AsyncTask stops or it gets stuck at trying to update the screen (latter I am thinking).
Other than never letting the screen sleep, how else can I prevent my AsyncTask to stop executing? And if that is the only way, then how do I make sure that the screen doesn't sleep?
EDIT: I must add that I know this sounds like a non-user-friendly app as commented by someone below. This does a very specialized task (processes thousands of image files to compare processing on different systems) and is to be used by a few users internally, not for public release.
That's expected behavior. The idea is that the phone's battery is not supposed to drain because of bad apps. If the screen is off, the user generally expects the phone to sleep.
If you need your app to run, you can use a WakeLock to keep the phone running (with the screen off): Documentation here and here.
Note that a wake lock requires the WAKE_LOCK permission, and again, you need to make it clear to the user that your app will drink the phone's milkshake while it's off.
Not sure if anyone will read this as the OP is several years old but I am in the same boat in that I need to use a wakelock for an app for internal use, and leaving the screen on was not ok (I just needed the cpu on so I could run some metrics queries) I simply used a partial wakelock; ie:
public class my_frag extends Fragment {
WakeLock wl;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setRetainInstance(true);
PowerManager pm = (PowerManager) this.getActivity().getSystemService(Context.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock");
//I happen to have it in a button click event based on an async task
//Side note: I should probably be using a Loader for my Async task but this works fine
connectButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (metrics_task != null)
{
Status s = metrics_task.getStatus();
if (s.name().equals("RUNNING")){
if (metrics_task.running){
metrics_task.cancel(true);
connectButton.setText("Start");
metrics_task.running = false;
wl.release(); <--releases it on async stop
}
else{
metrics_task = new start_metrics(ae);
metrics_task.execute();
wl.acquire(); <--starts it on async start
}
}
else{
metrics_task = new start_metrics(ae);
metrics_task.execute();
}
}
else{
metrics_task = new start_metrics(ae);
metrics_task.execute();
}
}
});
This worked great with no issues
My 2 cents on this old post, in case it might help someone. If all you want is to prevent your screen from going to sleep, there's a simple solution that does not require a permission from the user - and it's just 2 lines of code:
// prevent the screen from sleeping
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// do your stuff
// don't forget to re-enable the screen time-out so it won't stay awake from now on
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
An important note: it can only be called within an Activity - not from other app components. more details can be found here.
Today I noticed something rather interesting. The activity lifecycle seems to have a slight discrepancy when the phone display times out. Let me explain with an example.
I have an activity that uses the accelerometer to vibrate the phone. In the onPause event I unregister the SensorManager listener so that I don't vibrate the phone when my activity is no longer the main focus.
However, I've noticed if the display shuts off and then comes back on my activity has the SensorManager listener registered even before I unlock the screen, enter my password, and my activity is shown.
Now I realize this is my own interpretation of how I would expect it to work, but to me this seems rather strange, since my activity isn't yet the main focus. I expected the SensorManager listener wasn't registered because onResume hasn't yet been called. This clearly isn't the case when I can make my phone vibrate from both the lock screen and the password screen.
So, can anyone explain why this behavior? Secondly what can I do to get around it?
Thank you.
EDIT for clarity
I use the accelerometer to trigger a vibrate by moving the phone. This is accomplished through the SensorManager listener.
Scenario:
My activity is in the foreground (main focus). I trigger the vibrate by moving the phone. The display times out. At this point I can not trigger the vibrate. I press home/power to show the screen. I can now vibrate my phone even though either the lock screen or password screen is shown and my activity is not in the foreground.
I can not verify if the reason I can not vibrate the phone when the display turns off is because onPause was called or there is something inherent to the OS that prevents it. Or to put it another way, I also can't verify if onResume was called when the display turned on.
The key to all this is understanding the activity life cycle when the phones display is shut off. Unfortunately, my expectation was that it would follow the same life cycle diagram that we have all learned. My opinion was that it is different.
You said it.
"expected the SensorManager listener wasn't registered because onResume hasn't yet been called. This clearly isn't the case when I can make my phone vibrate from both the lock screen and the password screen."
onResume is called before you unlock the phone
The following code will handle Screen Off and Screen On intents. Perhaps you can call onPause() in the onResume() called only after the screen turns on, and call and onResume() when your activity has focus again.
public class ExampleActivity extends Activity {
#Override
protected void onCreate() {
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new ScreenReceiver();
registerReceiver(mReceiver, filter);
}
#Override
protected void onPause() {
if (ScreenReceiver.wasScreenOn) {
System.out.println("onPause() called because screen turned off.");
} else {
System.out.println("normal onPause() call");
}
super.onPause();
}
#Override
protected void onResume() {
if (!ScreenReceiver.wasScreenOn) {
System.out.println("onResume() called when screen turns on");
} else {
System.out.println("normal onResume() call");
}
super.onResume();
}
}
Ah. Your edit tells us why this is happening.
The problem is that when your "screen times out" and the phone goes black, what is happening is the phone is actually going to sleep. The OS is probably going into a low power state and turning of listeners for various things and possibly turning off the accelerometer and/or vibrator.
If you really want the activity to be able to vibrate, try holding a wake lock.
http://developer.android.com/reference/android/os/PowerManager.WakeLock.html