I recently downloaded the ACDisplay lock screen app:
https://play.google.com/store/apps/details?id=com.achep.acdisplay
The application shows an overlay on my device while also at the same time detecting home button click on the activity so that i can't bypass the lock screen. It is also somehow able to completely hide the recent button on a non-rooted device. How is that possible?
I have went through the following links:
Detect home button press in android
How can I detect user pressing HOME key in my activity?
How can I detect user pressing HOME key in my activity?
and all of the solutions used to work for older versions of Android OR they say that the home button click cannot be detected since it can be used by malicious apps.
How is this application able to do so?
Can someone share sample code/app on how to prevent the user exiting the lock screen app until they have successfully authenticated themselves?
Thank you.
With Device admin permission
https://developer.android.com/guide/topics/admin/device-admin
you can pragmatically lock unlock device.
That app also use permission for "retrieve running apps" android.permission.GET_TASKS, so with that we can detect current foreground running app.
check answer.
https://stackoverflow.com/a/17756786/1025070
with that if user try to press home and leave we can instant check app is not in forground, and relaunch our activity again. (its workaround to detect if user leave from app with Home press).
Check my app https://play.google.com/store/apps/details?id=com.udayalakmal.applock&hl=en
that add overlay of lockscreen on any app that can not bypass. use same check foreground running app.
#user2511882
- Created sample app that simply load Activity when device locked, and another activity when device unlock
https://github.com/UdayaLakmal/LockScreenDemo
**This is only a demo, you have to use receivers with background service for continue monitor device lock state and handle memory leaks, .Tested with Android 6 API 23
no need to monitor running apps since this only use with device lock screen.
**Check how I get Home button press event in Lockscreen activity.
WindowManager windowManager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
}
layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
layoutParams.x = 0;
layoutParams.y = 0;
layoutParams.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
View window = LayoutInflater.from(this).inflate(R.layout.activity_main, null, false);
windowManager.addView(window, layoutParams);
The following piece of code blocks the home, back and recents button as per the requirement.
Also requires the following permission in the manifest:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
You cant disable recent button and home button but you can achieve this by using Window Manager link, in one line its create an overlay over your android application screen.
Related
I made an field guide app for biology. It does tons of stuff, for example, recordings of wildlife sounds, and it is made to run the whole day with a single battery charge.
Since it is intended to be run a whole day, I cannot keep the screen on all the time. So naturally the screen goes off. Then, the lock screen kicks in, blocking the app. Then you need to enter the pin/pattern/whatever and you then miss the opportunity of a precious recording. Dozens of times per day. And in general the user is using my app in the wild, where there is much less risk of theft.
So I present the user an option in the preference section of my app to turn lock screen off while using it. There is no problem with this (see below for the code I made), except that when I switch to a secondary activity the lock screen appears. It is not truly a "lock screen", in the sense that it shows the back button that when you press it the lock screen disappears. But still, a pain when you're in a hurry. I want no lock screen. At all.
Interestingly, when I switch back to the primary activity from a secondary, no lock screen is shown...
This is the way I found to (partially) disable the lock screen (executed in each activity act):
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
act.setShowWhenLocked(true);
act.setTurnScreenOn(true);
((KeyguardManager) act.getSystemService(Context.KEYGUARD_SERVICE)).requestDismissKeyguard(act, null);
//if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
// act.setInheritShowWhenLocked(true); // makes no difference?
} else {
Window window = act.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
}
Of course, I also have in the Manifest:
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
It turns out that the requestDismissKeyguard was causing the Lock Screen to be activated instead of deactivated (??!!). So I removed the line
((KeyguardManager) act.getSystemService(Context.KEYGUARD_SERVICE)).requestDismissKeyguard(act, null);
and now everything works just fine.
I am writing code in Android to display an activity on the locked screen. The activity has an activity button which launches another new activity. For the new activity, I have added FLAG_DISMISS_KEYGUARD so that the activity can be showed on the lock screen. Ideally if the keyguard is currently active and is secure (requires an unlock credential) than the user can confirm it using the lock pattern or key code or whatever the user set and then the activity window should appear. It works as expected on all phones except the Xiaomi Phone - after clicking the button there is no prompt shown to the user to unlock. How can I resolve this issue?
Here is a snippet of my code:
I have this code in the onActivityResumed(Activity activity) method of the new activity:
final Window win = activity.getWindow();
win.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
The new activity will be resumed on the button click and hence I have it in the onActivityResumed API.
I am building a VoIP app and it has an incoming call screen. Instead showing the screen, I want to just show a heads up notification, if current foreground app is in full screen mode. Is this possible? Is there a way to check if the current running activity is in full screen?
WindowManager.LayoutParams lp = getWindow().getAttributes();
if(lp.flags == WindowManager.LayoutParams.FLAG_FULLSCREEN){
//Do your stuff
}
Edit
If the running app is not your app you need to take a different approach which possible only from API 11, and use View.OnSystemUiVisibilityChangeListener:
Callback to be invoked when the status bar changes visibility. This reports global changes to the system UI state, not what the application is requesting
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I am developing custom lockscreen app.its working fine in below 4.0 but above 4.0,when we press home button the app stops.is there any solution for this no apps will stop when pressing home button untill unlocking the screen.(like go locker app)
Another way to develop a LockScreen App is by using Views, let me explain it.
First of all you can "disable" in some devices the System lock screen by disabling the KEYGUARD:
((KeyguardManager)getSystemService(Activity.KEYGUARD_SERVICE)).newKeyguardLock("IN").disableKeyguard();
You should put this line of code in your Service.
After that you can launch an activity every time the screen goes off:
public class AutoStart extends BroadcastReceiver {
public void onReceive(Context arg0, Intent arg1) {
if(arg1.getAction().equals("android.intent.action.SCREEN_OFF")) {
Intent localIntent = new Intent(arg0, LockScreen.class);
localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
localIntent.addFlags(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
arg0.startActivity(localIntent);
}
}
}
If you read the documentation for WindowManager.LayoutParams.TYPE_SYSTEM_ERROR it explains that is a type of internal system error windows, appear on top of everything they can. In multiuser systems shows only on the owning user's window.
So now you have an activity on top of everything, but a press in HOME button will exit the activity.
Here is where the Views make their appearance. You can inflate a view from a layout resource and add it to the WindowManager as a TYPE_SYSTEM_ERROR, so will be on top of everything. And since you can control when to remove this View, the best place is in onDestroy of your Activity, because pressing the HOME button will only pause your activity, and the view will still be visible.
public WindowManager winManager;
public RelativeLayout wrapperView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WindowManager.LayoutParams localLayoutParams = new WindowManager.LayoutParams( WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL|
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
this.winManager = ((WindowManager)getApplicationContext().getSystemService(WINDOW_SERVICE));
this.wrapperView = new RelativeLayout(getBaseContext());
getWindow().setAttributes(localLayoutParams);
View.inflate(this, R.layout.lock_screen, this.wrapperView);
this.winManager.addView(this.wrapperView, localLayoutParams);
}
public void onDestroy()
{
this.winManager.removeView(this.wrapperView);
this.wrapperView.removeAllViews();
super.onDestroy();
}
To avoid the notification bar of showing I added the flags FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL | FLAG_LAYOUT_IN_SCREEN to consume all pointer events.
Not forget to add these two lines to your manifest:
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
From here you just need to add the logic of your Lock Screen app to let the user use his smartphone :)
A custom launcher is basically an app (you can make it behave like a grid, list, implement your own drag and drop etc) then, you only need to add these lines to the intent filter of the main activity, with this done, after you install your app and press the home button your app will appear in the list of available homescreens.
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
What i cant find is a way to replace the lock screen, and hacks like disabling the lock screen on the phone and using an activity in a custom launcher isn't actually replacing the lockscreen ^^
You can use the below method to disable the Home key in android :
#Override
public void onAttachedToWindow() {
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
super.onAttachedToWindow();
}
I am developing on a Samsung Galaxy S4 5.0 and what worked for me was simply changing getWindow().setFlags(..) to getWindow().addFlags(..)
I think first of all you should ask yourself if you really want to hijack the home key. Sometimes you may want it. But I think placing the app on the Android lock screen, letting the home key act normally and letting the underlying Android lock screen take care of password-protecting the device is what you actually want in a lot of cases (unless you want to change the way this is done by default).
Bottom line, letting an app be displayed on the Android lock screen comes pretty close to writing your own custom lock screen. And is decidedly easier since you don't have to manage passwords yourself. Not to mention it's safer and more reliable since you don't hijack the home key.
I did it like this and it works very well. You can see the details here:
show web site on Android lock screen
The question is about displaying a website on the lock screen, since that's what I was interested in, but the answer is more general, it works with any app.
You can see here an app that's on Google Play and has been written like this:
https://play.google.com/store/apps/details?id=com.a50webs.intelnav.worldtime
I want to build a dialog which is visible on the lockscreen and can receive touch events. I built a window with WindowManager but only the TYPE_SYSTEM_OVERLAY Flag is shown over the lockscreen in GB (Android 2.3.7).
Is there a way to create a system overlay which is visible on the lockscreen and can receive touch events in Android 2.3.7?
There was a bug with FLAG_WATCH_OUTSIDE_TOUCH but I'm not sure how that affects me. Any ideas?
I do not think you can launch an activity each time when device is locked without binding your application as admin privilaged app programatically.
Once your app is admin privilaged app, you can programatically set password & lock the screen & then programatically unlock it using Device Policy Manager.
On top of that lock screen you can programatically launch your own activity & you can create your own unlocker & unlock device through that activity as you can get call backs via DeviceAdminReceiver.
Here is a good example for that & all you need is to create your own activity after you called DevicePolicyManager.lockNow(). Then it will appear on top of lock screen as normal activity plus extra control over native lockscreen.
Try this It may helps you,
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.alertdialog);
And also, Android is a little bit of a contradiction. It's very open and as a developer you have access to anything, and it's up to you to use those powers for good or evil. When I say evil I don't mean malware. I mean apps that try to get cute and use things in ways they weren't meant to be used, like putting up notifications asking you to use the app more. The contradiction is that you don't actually have access to everything, there are a few parts the developers decided were so important that app couldn't mess with them. The lock screen is one of those parts. You can replace your home app all you want, but you never have to worry about your replacement lock screen failing and preventing you from accessing your phone.
Even if this were possible you would have more problems to deal with. Every lock screen is different, manufacturers can and do customize it so you have no guarantees your activity won't get in the way of unlocking the phone.
For touching outside of your dialog,
dialog.setCanceledOnTouchOutside(your boolean);
Finally I achieved the same. Don't go for activity, because android will not show lock screen behind your activity for security reason, so for service.
Below is my code in onStartCommand of my service
WindowManager mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
View mView = mInflater.inflate(R.layout.score, null);
WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT, 0, 0,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
/* | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON */,
PixelFormat.RGBA_8888);
mWindowManager.addView(mView, mLayoutParams);