I have an app which when the device locks it starts an activity instead. By doing this the device doesn't lock but it shows an activity. This is OK. My problem is that if I am already in the activity and when I press the power button the device locks.
In the BroadcastReceiver I can see the screen is off:
if (action.equals(Intent.ACTION_SCREEN_OFF)) {
isScreenOff = true;
final Intent serviceIntent = new Intent(context, Screensaver.class);
serviceIntent.putExtra("screen_state", isScreenOff);
context.startService(serviceIntent);
Log.i(TAG, "SCREEN OFF.");
}
Then the onStartCommand() in my service is called. In it I start the activity. In the activity I see that the onResume() is called and then onPause() and that's it. The device is locked and the screen is off. If I unlock it manually, the activity is there, but it shouldn't be necessary to unlock it manually. Do you have any idea how I can fix that? (Do not hesitate to ask me if I need to post more code).
EDIT
Here is a video to get it more clear. In the end of it I am in my screensaver activity and when I press the power button the device locks and does not starts the screen again.
I figured it out! Since the activity started when I lock the device, calling Activity.recreate() in onStop() fixed my problem.
Related
I have a basic Activity which mainly allows the user to change settings and save them. I also have a BroadcastReceiver which is launched on SMS_RECEIVED.
The main point of the app is to vibrate whenever a certain message is received until the user taps a button to make it stop. The activity is only there to allow the user to change settings and press the "Stop" button.
In my onReceive method (BroadcastReceiver), I get the content of the last message received and make the phone vibrate if the message is equal to a certain string. All of that is working perfectly, the problem is when I want to make it stop. Right now, I'm trying to make a "Stop" button appear in the Activity when the phone starts vibrating.
I understand that UI elements should remain in the Activity and so what I'm trying to do is communicate between the Activity and my BroadcastReceiver. I've found here how to do that with an Observer. The problem though is that I want the app to function at any time, even at boot time. It's very easy with a BroadcastReceiver but since it requires the Activity to be shown to allow the user to stop the vibration, I have to start the activity if it isn't started already.
So what I do is this:
Intent i = new Intent(context, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("SMSReceived", true);
context.startActivity(i);
ObservableObject.getInstance().updateValue(true);
The problem is, when there is no instance launched, it creates a new one and sends the extra boolean correctly but the updateValue method doesn't seem to get called at all (due to the previous instance I suppose?) and inversely, when there is an instance launched (in the background) the extra boolean doesn't get passed and the updateValue method gets called correctly.
I suppose I could just launch the Activity on boot and immediately put it in the background but it could cause problems if the user closes the application, at which point it would simply stop working until the user started it again since the Observer would have no instance to send data to.
Do you guys have any idea of what I could do to solve my problem?
If it's not clear I can try to explain further.
I am trying to display my application over the lock screen on android.
I have it working some of the time. But certain scenarios will not work.
I am starting my activity which extends a React Native Activity from a service like so:
Intent callIntent = new Intent(context, MainActivity.class);
callIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(callIntent);
And I am setting the flags on the window like this in the onCreate method:
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
When it works:
If the activity has been started when the device is unlocked and the app is still in recents. The device will wake and the activity will be displayed over the lock screen.
Activity state changes witnessed:
onRestarted
onStarted
onResumed
onPaused
onResumed
When it doesn't work:
If the app hasn't been run since boot or the app has been removed from the recents. The device will sometimes wake and sometimes the app will flash for a second before returning to the lock screen. When the device is unlocked the app is running.
Activity state changes witnessed:
onCreated
onStarted
onResumed
onPaused
onStopped
I'm not sure if this is specific to React Native or not.
Summary
Can I start a new activity from a background service when its application is in the background, without bringing the application to the front?
Background
Suppose I'm developing MyApp for Android. This app handles very sensitive information, so we need to lock the app when the user has been inactive for a little while.
MyApp has a service, MyService. Different user interactions with the app resets an inactivity timer in MyService. When the inactivity timer expires, the service starts a new activity, LockActivity, which acts as a screen lock for MyApp. The user has to reauthenticate herself to get past the LockActivity and resume working with the app.
This all works, with one problem: when the LockActivity is started, it brings the app to the front. Since the user may be doing something else (browsing Facebook or whatever), she will be annoyed, and rightly so.
The code I'm using for starting the activity from the background is:
Activity topActivity = magicallyFindMyTopActivity(); // This part is not important; it works though
Intent intent = new Intent(this, LockActivity.class);
topActivity.startActivity(intent);
Do you know any way to avoid this?
An Activity is almost every time something that shows up to the user, so the user can interact with it.
I think what best fits what you are trying to archive is to use OnResume event and check for a field which tells if the app is secured.
Something like this:
onResume(..){
if(isSecured){
_secureMyApp();
}
}
Have a look at this:
Check the security thing in background service at some interval, now have a flag
boolean secure = true;
When the time expires update the flag secure = false;
In your main activity check the flag every time if its false ask the user to authenticate. (Don't create any new activity)
Don't blindly start lock activity when inactivity timer expires, just set some variable and when your app resumes or starts check variable state and show lock screen first.
I know that this question has been asked a lot of times but it has never been answered satisfactorily.
My problem is the following:
I have an activity which prevents the screen from turning off for a predefined amount of time.
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
When the predefined time is over I show a dialog with a countdown to inform the user that the display will turn off in 10 seconds if he doesnt press "cancel".
I managed to turn off the display but the phone always switches into StandBy-Mode.
For switching off I used:
Window mywindow = getWindow();
WindowManager.LayoutParams lp = mywindow.getAttributes();
lp.screenBrightness = 0.0f;
mywindow.setAttributes(lp);
Is there any possibility to completely darken the display without going to StandBy-Mode (which pauses the activity).
My goal is that the user should be able to just tap the display to brighten up the screen again. So the activity has to remain in an active state.
A similar question has been asked here.
Since this question is almost a year old I am hoping that maybe somebody managed to this in the mean time.
Lots of greetings
Siggy
Seems like it isn't possible to turn off the screen AND reactivate just by touching the display.
My new approach now:
private WakeLock screenWakeLock;
PowerManager pm = PowerManager.getSystemService(Context.POWER_SERVICE);
screenWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"screenWakeLock");
screenWakeLock.acquire();
The PARTIAL_WAKE_LOCK keeps the CPU running but allows the display to shut down.
When power or home button is pressed the display turns on again and the activity becomes visible again (without having to "slide-to-unlock" or sth. else).
Don't forget to release the screenWakeLock.
In my case I did it in the onResume() of the activity:
if (screenWakeLock != null) {
if(screenWakeLock.isHeld())
screenWakeLock.release();
screenWakeLock = null;
}
Maybe this helps someone with a similar problem in the future.
Note : i wasn't able to work with WAKELOCK
I have figured a workaround which involves changing SCREEN_OFF_TIMEOUT. Use the below
code to achieve it.
Settings.System.putInt(getContentResolver(),
Settings.System.SCREEN_OFF_TIMEOUT, 10);
this sets 10 milliseconds as timeout for screen_timeout SYSTEM-WIDE .
Now you might be troubled by SYSTEM-WIDE changes brought upon by this. To work around that you can get the default screen_timeout_time and save it to a variable then set back the System's SCREEN_OFF_TIMEOUT at finish() of your activity.
Before setting 10ms as our screen_timeout get SCREEN_OFF_TIMEOUT,
int defaultScreenTimeout= android.provider.Settings.
System.getInt(getContentResolver(),Settings.System.SCREEN_OFF_TIMEOUT,-1);
Now when you have finished with your changes or when your activity ends you may set the SCREEN_OFF_TIMEOUT back .
#Override
public void finish(){
Settings.System.putInt(getContentResolver(),
Settings.System.SCREEN_OFF_TIMEOUT, defaultScreenTimeout);
super.finish();
}
I am facing issue in Activity which is calling from Broadcast receiver.
My application contains alarm system, so when time of alarm match, at that time, broadcast receiver calls one activity to get in front. This activity is not in full screen, it is one type of alert box using RegionSearchDialog as theme. (Don't be confuse, I am using activity only, my class extends activity, but the theme in xml set as RegionSearchDialog)
My platform of development is: 4.0.4
Now my issue is: if my device is on (unlock keygurad) either application is in front or in back, it works fine. But if power is off (sleep mode / device is lock), it will call same activity, onCreate() calls first then onResume() and then it will call onPause() as my device is in sleep mode.
I want to keep that activity running, don't want to get it sleep.
So, when alarm time match, it will buzz alarm and if its in sleep mode then user can unlock device and see popup of that alarm.
Thanks in advance to help me in that.
This is the way Activities in Android are supposed to work. You would be better using a Service or using the Alarm manager to launch an Activity at a certain time as these are more suited to what you are trying to do =).
Here is my code,i think it can help you:
In your activity on create():
super.onCreate(savedInstanceState);
final Window win = getWindow();
win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
setContentView(R.layout.main);
and main xml is:
<activity
android:name=".main"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#android:style/Theme.Wallpaper.NoTitleBar"
android:launchMode="singleInstance"
android:excludeFromRecents="true"
android:taskAffinity=""
android:configChanges="orientation|keyboardHidden|keyboard|navigation" />
pls test these code in your project. :)
In addition to the response by 'enjoy-writing':
It sufficed in my android app to set the flags as described in the onCreate code.
The effect was that the app would pause when going into sleep mode (e.g. through pressing the On/off button on the phone), and resume when returning from sleep mode.
By removing the FLAG_KEEP_SCREEN_ON flag you can still have the phone fall asleep if the view isn't used for a while.