I've tried opening an Activity on the lock screen in Android Pie but I could not.
I added the showWhenLocked and turnScreenOn on the Android Manifest and on the proper activity and permissions I searched for but could not make the activity open on the default lock screen on the phone. Some help?
MainActivity
if (Build.VERSION.SDK_INT >= 27) {
setShowWhenLocked(true);
setTurnScreenOn(true);
} else {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
Android Manifest
android:showWhenLocked="true"
android:turnScreenOn="true"
android:showOnLockScreen="true"
android:excludeFromRecents="true"
Here is my working method call it from onCreate() before setContentView() of activity
Also set below flag for your activity in AndroidManifest file.
android:showOnLockScreen="true"
/**
* Allow calling screen to display over lock screen
*/
private fun allowOnLockScreen() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true)
setTurnScreenOn(true)
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
keyguardManager.requestDismissKeyguard(this, null)
} else {
this.window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON)
}
}
Just override the following method in your activity which you want to open on the lock screen.
#Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
And add the following tag to your activity in Manifest.
android:excludeFromRecents="true"
Something like this should work:
PowerManager.WakeLock cpuWakelock = ((PowerManager) getSystemService(POWER_SERVICE)).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "XXX:CPU_WAKE_LOCK");
cpuWakelock.acquire();
Related
I am trying to show an activity when the screen is locked. I am running a service in the background, when an event occurs, I want to open an activity even if the app is locked(Similar to alarm app, which wakes up the screen and displays its activity). I have followed the following steps,
When OnReceive() is called, I want to open the activity on the lock screen.
public void OnReceive() {
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "myalarmapp:alarm.");
wl.acquire(5000);
Intent startAlarmActivity = new Intent(MainScreen.this, AcceptScreen.class);
startActivity(startAlarmActivity);
wl.release();
}
Added below code in the activity's onCreate method which I want to show,
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true);
setTurnScreenOn(true);
KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
keyguardManager.requestDismissKeyguard(this, null);
}
else {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON |
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
Added this in manifest for the activity which I want to show,
<activity
android:name=".v2.ui.orderaccept.AcceptScreen"
android:exported="true"
android:label="#string/title_activity_accept_screen"
android:theme="#style/AppTheme.NoActionBar"
android:showOnLockScreen="true"
android:screenOrientation="sensorPortrait"/>
It is working as expected when the phone does not have a lock screen password. But it does not work when there is a password for the lock screen.
Finally, I got the solution.
add below code in the activity's onCreate method which you want to show on the lock screen,
final Window win = getWindow();
win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON);
Manifest,
<activity
android:name=".v2.ui.orderaccept.AcceptScreen"
android:exported="true"
android:label="#string/title_activity_accept_screen"
android:theme="#style/AppTheme.NoActionBar"
android:launchMode="singleInstance"/>
Call the activity,
val intent = Intent(context, targetclass)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(intent)
I am trying to display my alarm activity over lock screen. I am using a full screen intent from my broadcast receiver. When the screen is locked, the activity is not displayed over lock screen. It is displayed when i unlock the screen. Where am i going wrong?
I have used following permissions:
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
In the activity, i am setting following flags in the activity's oncreate:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true);
setTurnScreenOn(true);
KeyguardManager keyguardManager = (KeyguardManager)
getSystemService(Context.KEYGUARD_SERVICE);
if(keyguardManager!=null)
keyguardManager.requestDismissKeyguard(this, null);
} else {
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON |
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
);
}
In my application, i need to launch an activity and turn screen on, when high-priority FCM message is received. It's an alarm activity, which is very, very important for users.
On most Android devices, the code is working fine. However, on some Huawei or LG devices, the activity is not launched when the device is in Doze mode, or in the pocket (proximity sensor). The behaviour should be similar like Alarm clocks, calls etc.
Here is my code:
FirebaseMessagingService:
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Intent dialogIntent = new Intent(getBaseContext(), AlarmActivity.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
dialogIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
getApplication().startActivity(dialogIntent);
}
Alarm Activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// set flags so an activity fire on the screen
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
);
setContentView(R.layout.activity_alarm);
.
.
}
I wanted to use SCREEN_BRIGHT_WAKE_LOCK before I launch an activity, but it's deprecated.
I am using in my activity this code:
#Override
protected void onCreate(Bundle savedInstanceState) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
setShowWhenLocked(true);
setTurnScreenOn(true);
KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
if (keyguardManager != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
keyguardManager.requestDismissKeyguard(this, null);
}
} else {
//noinspection deprecation
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
);
}
}
.....
}
To prevent different behavior on different devices I use in my activity layout this:
<android.support.design.widget.CoordinatorLayout
....
android:keepScreenOn="true"
>
I want launch my activity on push notification over lock screen without change in lock.
Any special permission for that activity?
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1)
{
setShowWhenLocked(true);
setTurnScreenOn(true);
KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
if(keyguardManager!=null)
keyguardManager.requestDismissKeyguard(this, null);
}
else
{
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
After API level 17 this would work
<activity
android:name=".yourActivityName"
android:showOnLockScreen="true"
android:screenOrientation="sensorPortrait" >
or write this in onCreate() before calling setContentView()
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
The other answers include extra functionality that you may or may not want.
The minimum code to allow your activity to display on the lock screen is this:
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= 27)
setShowWhenLocked(true);
else
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
// setContentView etc
}
If you also want your activity to turn on the screen (since it might be off) or unlock the keyguard, then see Vladimir Demirev's answer.
In the method onCreate(Bundle savedInstanceState) you should add some window flags:
Window window = this.getWindow();
window.addFlags(LayoutParams.FLAG_DISMISS_KEYGUARD);
window.addFlags(LayoutParams.FLAG_SHOW_WHEN_LOCKED);
window.addFlags(LayoutParams.FLAG_TURN_SCREEN_ON);
Hey i need to wake my sleeping android device up at a certain time.
Any suggestions?
P.S. Wake up: turn display on and maybe unlock phone
To wake up the screen:
PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
WakeLock wakeLock = pm.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "TAG");
wakeLock.acquire();
To release the screen lock:
KeyguardManager keyguardManager = (KeyguardManager) getApplicationContext().getSystemService(Context.KEYGUARD_SERVICE);
KeyguardLock keyguardLock = keyguardManager.newKeyguardLock("TAG");
keyguardLock.disableKeyguard();
And the manifest needs to contain:
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
For more details about PowerManager, refer to the API documentation: http://developer.android.com/reference/android/os/PowerManager.html
EDIT: this answer is reported as deprecated.
Best is to use some appropriate combination of these window flags:
http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_DISMISS_KEYGUARD
http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_SHOW_WHEN_LOCKED
http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_KEEP_SCREEN_ON
http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_TURN_SCREEN_ON
If you want to run on older versions of the platform that don't support the desired flag(s), you can directly use wake locks and keyguard locks... but that path is fraught with peril.
ONE IMPORTANT NOTE: Your activity must be full screen in order for the above flag combination to work. In my app I tried to use these flags with an activity which is not full screen (Dialog Theme) and it didn't work. After looking at the documentation I found that these flags require the window to be a full screen window.
I found a way and it is not that complex... works on any API version.
You need to use PowerManager.userActivity(l, false) method and register your activity as broadcast received for SCREEN_OFF intent:
In your actiivity OnCreate put something like:
mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.v(TAG, "Screen OFF onReceive()");
screenOFFHandler.sendEmptyMessageDelayed(0, 2000L);
}
};
It will kick off the handler after 2 seconds of Screen Off event.
Register receiver in your onResume() method:
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
registerReceiver(mReceiver, filter);
Log.i(TAG, "broadcast receiver registered!");
Create a handler like the one below:
private Handler screenOFFHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// do something
// wake up phone
Log.i(TAG, "ake up the phone and disable keyguard");
PowerManager powerManager = (PowerManager) YourActivityName.this
.getSystemService(Context.POWER_SERVICE);
long l = SystemClock.uptimeMillis();
powerManager.userActivity(l, false);//false will bring the screen back as bright as it was, true - will dim it
}
};
Request permission in your manifest file:
<uses-permission android:name="android.permission.WAKE_LOCK" />
Do not forget to unregister broadcast receiver when you are done. You may do that in onDestroy() for example (which is not guaranteed)
unregisterReceiver(mReceiver);
Log.i(TAG, "broadcast UNregistred!");
On newer devices you should use something like this, since the mentioned Flags are deprecated.
class AlarmActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_alarm)
// Keep screen always on, unless the user interacts (wakes the mess up...)
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
setTurnScreenOn(true)
setShowWhenLocked(true)
(getSystemService(KeyguardManager::class.java) as KeyguardManager).requestDismissKeyguard(this,
object: KeyguardManager.KeyguardDismissCallback(){
override fun onDismissCancelled() {
Log.d("Keyguard", "Cancelled")
}
override fun onDismissError() {
Log.d("Keyguard", "Error")
}
override fun onDismissSucceeded() {
Log.d("Keyguard", "Success")
}
}
)
}
}
KeyguardManager.requestDismissKeyguard only wakes up the device, if the setter setTurnScreenOn(true) was called before.
I tested this on my Android Pie device.
Try with the below code after setContentView(R.layout.YOUR_LAYOUT); in activity onCreate() method
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
Log.d(TAG, "onCreate: set window flags for API level > 27");
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
KeyguardManager keyguardManager = (KeyguardManager) getApplicationContext().getSystemService(Context.KEYGUARD_SERVICE);
keyguardManager.requestDismissKeyguard(this, null);
setShowWhenLocked(true);
setTurnScreenOn(true);
} else {
Log.d(TAG, "onCreate: onCreate:set window flags for API level < 27");
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
If you are showing a window when waking up, you can get it working easily by adding few flags to your activity, without using a wake lock.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
Settling an alarm programatically will wake up the phone(play a sound) and i guess the turn on display would be an option there.
I donot think there would be an exposed API that will unlock the phone automatically.
getWindow().addFlags(LayoutParams.FLAG_DISMISS_KEYGUARD);
will dismiss the general keyguard and cause the device to unlock.