Show dialog with touch events over lockscreen in Android 2.3 - android

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);

Related

Lock Screen detect home button

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.

Creating custom LockScreen in android [closed]

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

Android Galaxy S4 -- Activity that is visible over lock screen

A few years ago, I wrote an alarm app that worked on Android 2, and I'm now trying to upgrade it to work on Android 4. Specifically, on the Samsung Galaxy S4.
On Android 2, if the phone was sleeping, it would wake the phone up and display a "Snooze or Dismiss" screen over the lock screen.
On Android 4, it wakes the phone up, but you have to unlock it, then open the notifications area, then click the alarm's notification, before you can hit "Dismiss."
I have always been using this code to do the waking:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
I have read 8 different stackoverflow questions on this matter. Most of them give the code above, which worked for me years ago in Android 2 but doesn't work in Android 4. But none of them have helped me solve this problem. Here are the questions that I read and tried:
Android: remove or disable programmatically the Lock Screen on Samsung Galaxy S2 device
How to display a fullscreen TYPE_SYSTEM_ALERT window?
How do I create an Activity that is visible on top of the lock screen
How to start a dialog (like alarm dimiss /snooze) that can be clicked without unlocking the screen
Android activity over default lock screen
android device locked, yet want alarm to sound and dialog to appear
Android dialog over lock screen
Show dialog with touch events over lockscreen in Android 2.3
Does anyone have any ideas about what's changed in Android 4 that may have caused this?
EDIT: Here is one of the simplest examples I've seen of an alarm dialog that doesn't come up "minimized." It does not, as written, appear over the lockscreen, but you can fix that with WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
http://wptrafficanalyzer.in/blog/setting-up-alarm-using-alarmmanager-and-waking-up-screen-and-unlocking-keypad-on-alarm-goes-off-in-android/
It's written with a FragmentActivity and a DialogFragment, but it still works as an Activity. It uses an AlertDialog.Builder to make the dialog, and if you try to do it with an XML layout, it won't work. Why?
I figured it out, and the answer was very different from what I expected.
This piece of code was included in the alarm clock sample from Android 2, in the AlarmAlert.java Activity:
#Override
protected void onStop() {
super.onStop();
// Don't hang around.
finish();
}
For reference, you can see the file from the example code in Git's past right here, containing the above onStop function. It never caused a problem in Android 2.
But in Android 4, if the phone was off, this onStop would fire right before the phone woke up, effectively "minimizing" the Activity. Once I removed this function, it immediately worked again.
But I wonder, is this the problem that other people like #radley and #Guardanis are getting? It seems unlikely, but please let me know if this fixes your problems too.
If you're visiting this answer in the future, and you're getting this problem, what I would try is:
Take out any onStop functions.
Add this code to the Activity:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
Make sure you're using a full screen theme, and not a dialog theme.
This didn't make a difference for me, but you could try setting showOnLockScreen explicitly in the manifest: <activity android:name="com.example.MyActivity" android:showOnLockScreen="true"/>
A second thing that didn't make a difference for me but you might try is adding the flag WindowManager.LayoutParams.FLAG_FULLSCREEN
I hope this helps other people!
In Kotlin,
For Api level 28 or less, you can simply add below method in your activity that needs to be opened:
override fun onAttachedToWindow() {
super.onAttachedToWindow()
toBeShownOnLockScreen()
}
private fun toBeShownOnLockScreen() {
window.addFlags(
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
or WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setTurnScreenOn(true)
setShowWhenLocked(true)
} else {
window.addFlags(
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
or WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
)
}
}
And to make it work on Android Pie and above, in additional to above step, we need to set in AndroidManifest as well:
<activity
android:name=".view.activity.LockScreenActivity"
android:showOnLockScreen="true"
android:showWhenLocked="true"
android:turnScreenOn="true" />
I have tested this code from Api level 21 to 29, and works like charm!
Not sure if this is the problem in all cases, but the documentation on ShowWhenLocked says it applies only to the top-most full-screen window. I had a window themed as a dialog which was not working, but it worked fine once I changed it to a regular full-screen window.
One of the questions you linked to has an answer that appeared to solve this issue for me.
This is the code I am using which appears to be working:
#Override
public void onAttachedToWindow() {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onAttachedToWindow();
}
I'm also explicitly declaring this in the activity definition in the manifest:
<activity
android:name="com.example.MyActivity"
android:label="#string/app_name"
android:showOnLockScreen="true"
>
Android activity over default lock screen
Right - So I have been struggling with this one recently but with a 5.0.2 Galaxy Tab A. Unsurprisingly what works on every other device does not work on Samsung (this has been the case since the first Samsung Galaxy device, they break something new each release!)
The general solution for showing an Activity over the lock screen for most devices is
//wake up device and show even when on lock screen
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 |
WindowManager.LayoutParams.FLAG_FULLSCREEN);
However this does not work for samsung devices. Removing FLAG_DISMISS_KEYGUARD however does this trick.
Looking at the docs for this flag we have
Window flag: when set the window will cause the keyguard to be dismissed, only if it is not a secure lock keyguard. Because such a keyguard is not needed for security, it will never re-appear if the user navigates to another window (in contrast to FLAG_SHOW_WHEN_LOCKED, which will only temporarily hide both secure and non-secure keyguards but ensure they reappear when the user moves to another UI that doesn't hide them). If the keyguard is currently active and is secure (requires an unlock pattern) than the user will still need to confirm it before seeing this window, unless FLAG_SHOW_WHEN_LOCKED has also been set.
and for FLAG_SHOW_WHEN_LOCKED we have
Window flag: special flag to let windows be shown when the screen is
locked. This will let application windows take precedence over key
guard or any other lock screens. Can be used with FLAG_KEEP_SCREEN_ON
to turn screen on and display windows directly before showing the key
guard window. Can be used with FLAG_DISMISS_KEYGUARD to automatically
fully dismisss non-secure keyguards. This flag only applies to the
top-most full-screen window.
You can see they can be used together but it seems samsung will not bother with FLAG_SHOW_WHEN_LOCKED if the device is locked and FLAG_DISMISS_KEYGUARD is present. My app requires a lock screen to be setup so removing the dismiss keyguard flag actually allows me to show full screen Activities over the lock screen. Yay for me, nay for samsung.

Android Create GestureOverlay as a System Alert View (on top of all apps)

I want to create a gestureoverlay for an app. I want the gesutureoverlay to be ontop of all other views. I have done this with a textbox and a button so far. I have the below code which creates the overlay on top of all apps but I can not use anything else in any others app or home screen. The app takes away from being able to focus in on the background view. I do however get my gesture overlay to work.
How do I at the very least get the phone to work normally but get to see the swipes the user makes (create a gesture overlay) on top of all apps?
This is what I have so far
#Override
public void onCreate() {
super.onCreate();
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
GestureOverlayView g = new GestureOverlayView(getBaseContext());
g.setGestureVisible(true);
g.setEventsInterceptionEnabled(true);
wm.addView(g, params);
}
First of all, thanks because your code helped me to get my GestureOverlayView working on top.
I am working on something similar also and as far as I know you cant do this, at least just like that. To do that you need to have INJECT_PERSMISSION and this permission is grant only to system signed app, therefore you canĀ“t do it using Android APIs if you dont have your ROM sign.
Of course there are other ways to do that.
What you might do is to get events in your activity and "re-insert" them from your activity to the activity under you. And this is something you cant do through android.
Take a look here and here.
In these links you can find further information about how to inject event into Android system.

How can I interact with the Lockscreen layout to display text into it, like this app:

I just discovered this application : https://market.android.com/details?id=de.j4velin.lockscreenCalendar
It seem that is now possible to write some text inside the lockscreen in the place where the alarm is usually written.
I would like to display custom text on this place, but have totally no idea on how to achieve that.
This guy succeed to write calendar events at this place.
Thank a lot for any clue//snippet that would help me.
This is astonishingly easy to achieve and astonishingly badly documented. All you need to do is set the alarm string in the system settings, as follows:
String message = "This is a test";
Settings.System.putString(context.getContentResolver(),
Settings.System.NEXT_ALARM_FORMATTED, message);
It is not the exact thing you asked for,but the code for custom lockscreen can be found here.It might help you.
http://code.google.com/p/contactowner/
I've never come accross any legit way within the public android APIs to affect the lock screen. Without playing with that app at all I wouldn't know for sure, but my guess is he created that activity that allows him to show whatever text he wants. Then uses a receiver to listen for SCREEN_OFF, or SCREEN_ON events and starts his "lock" activity at that time.
It is worth noting: If you choose to do something like this to achieve the affect you're after, it is not going to behave the exact same as the lock screen. The differences may be fairly slight, and could end up being fine for your purposes but be aware that they are there. Also assuming you go this route it wouldn't work if the user has a "pattern" lock as the KeyguardManager is unable to disable that screen programmatically
you also need to add
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
in androidmanifest.xml
The voted answer will work only if no one else is using the same to display their message. If two receivers are registered for SCREEN_ON/OFF intent action, the latest receiver's message will be displayed.
With marc1s' solution there are 2 problems,
1. it doesn't look good & you can't change its look&fill e.g. text font or color etc
2. any other application can replace it
So its better if you show a view using window manager from a service. So you can show
whatever view you want to show.
e.g. my code below 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);

Categories

Resources