I'd like to be able to create an Activity that is always at the front of display of Android.
It should receive no input, just pass it down to whatever application is next below it. Something like a HUD.
I was able to research that I need to set underlying window type to TYPE_SYSTEM_ALERT but it looks like Android is ignoring my code - no exception thrown even if I delete android.permission.SYSTEM_ALERT_WINDOW permission from manifest. (it is required to use this window type). When I tried to use ALERT type on dialog, it worked OK, but I cannot make dialog into full screen transparent entity.
Here is my code, maybe there is something simple missing.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
getWindow().setBackgroundDrawableResource(android.R.color.transparent);
getWindow().setFormat(PixelFormat.TRANSLUCENT);
setContentView(R.layout.main);
}
Translucent setting has to be enabled externally in xml manifest, otherwise it also didn't work.
<item name="android:windowIsTranslucent">true</item>
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
WindowManager wm = (WindowManager) getApplicationContext()
.getSystemService(Context.WINDOW_SERVICE);
ViewGroup mTopView = (ViewGroup) App.inflater.inflate(R.layout.main, null);
getWindow().setAttributes(params);
wm.addView(mTopView, params);
I found that the accepted answer (by tmouse) did not quite work for me. Maybe it worked for an older API level? I'm using API level 24.
That particular answer had recommended:
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT
);
There is a problem with this. The constructors that exist for WindowManager.LayoutParams are as follows:
So the WindowManager.LayoutParams.FLAG_FULLSCREEN flag gets used as an explicit value for int w and int h. This is no good! Your view's dimensions get set to 1024*1024 — so it does not fill the screen. And even if you explicitly set the layout's width and height to match the device's dimensions: they will not update when the screen orientation changes. We need a different approach…
I found that the correct construction for a full-screen overlay is like so:
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, // TYPE_SYSTEM_ALERT is denied in apiLevel >=19
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_FULLSCREEN,
PixelFormat.TRANSLUCENT
);
This means we no longer explicitly specify a width and height. The layout relies entirely on our flags instead.
Yes, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN is a required flag still; it is necessary if you want to draw over decorations such as the status bar.
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY should be used instead of TYPE_SYSTEM_ALERT in API level >=19. This is a note I wrote a while ago, sadly I've been unable to find citation to corroborate why I thought that, so take that with a pinch of salt.
Bonus notes (if you're reading this, you're probably trying to make a full-screen overlay):
Your manifest will need these permissions (explanation here):
<uses-permission android:name="android.permission.ACTION_MANAGE_OVERLAY_PERMISSION"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
My understanding is that SYSTEM_ALERT_WINDOW is the actual permission required, but that ACTION_MANAGE_OVERLAY_PERMISSION is needed also: it lets you request at runtime that the user grant the SYSTEM_ALERT_WINDOW privilege.
I provide here the source code to my working API level 24 app that creates a full-screen overlay.
Check out this
mention it in your AndroidManifest.xml file
<activity android:name=".MyActivity" android:theme="#android:style/Theme.NoTitleBar.Fullscreen" />
if you want to make your Activity full screen and transparent also
check out this
<activity android:name=".MyActivity" android:theme="#android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
Related
I am trying to click the force stop button using the accessibility service.when i find the FORCE STOP button i click it using:
childNodeView.performAction(AccessibilityNodeInfo.ACTION_CLICK);
this is successful in ordinary scenario, however when I try to hide the process from the user using a window manager overlay the click doesn't work. This makes since maybe because there is a screen over the button I am trying to click, however there are several applications on the play store that have the described functionality with a window overlay
these are my window manager params:
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_FULLSCREEN,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.START;
oneTapProgressView = new OneTapProgressView(this);
windowManager.addView(oneTapProgressView, params);
Note: I run this from a different service and not from the accessibility service
How do I perform the click with the window overlay?
I believe this is related to the overlay type. Specifically TYPE_PHONE. Phone overlays have special mechanisms to trap events so that users don't accidentally touch buttons with their cheek why talking on the phone.
You should try a different type. For Android O Try:
TYPE_APPLICATION_OVERLAY
For prior operating systems you want:
TYPE_SYSTEM_ALERT
Both of these will require the following permission:
SYSTEM_ALERT_WINDOW
Also, the following flags may be useful if the above alone doesn't fix it:
FLAG_NOT_FOCUSABLE
I'm trying to develop an android app that will replace the stock lock screen and acquire the basic functionality of a typical lock screen. I'm planning to support the app from API level 15 and higher. But I'm facing some problem regarding lock screen behaviour. I'm not yet able to disable the home and recent button of soft navigation bar. I've found lot of examples in stack, github and other sources but those are not so useful.
I've tried in following way:
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
Added following flags in LockActivity
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_DIM_BEHIND);
But didn't get any effective solutions. I've found ZUI Locker a very nice app doing what I actually want. How they are accessing the permissions
to work like a default lock screen ?
Any suggestions ?
Thanks in advance!
I've developed a lockscreen app too and I'd like to help you too.
You can check out the answer here for understanding the concept behind Views and TYPE_SYSTEM_ERROR.
But I tweaked the code a bit and here's my version:
WindowManager mWindowManager;
RelativeLayout mLscreenlayout;
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_WATCH_OUTSIDE_TOUCH|
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN|
View.SYSTEM_UI_FLAG_LAYOUT_STABLE|
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION|
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION|
View.SYSTEM_UI_FLAG_FULLSCREEN,
PixelFormat.TRANSLUCENT);
mWindowManager = ((WindowManager)getApplicationContext().getSystemService(WINDOW_SERVICE));
mLscreenlayout = new RelativeLayout(getApplicationContext());
getWindow().setAttributes(localLayoutParams);
View.inflate(this, R.layout.activity_lockscreen, this.mLscreenlayout);
this.mWindowManager.addView(mLscreenlayout, localLayoutParams);
public void onDestroy()
{
mWindowManager.removeView(this.mLscreenlayout);
mLscreenlayout.removeAllViews();
super.onDestroy();
//myThread.interrupt();
Log.i("Daze","Lockscreen Activity Destroyed");
}
Also, there's library on GitHub here to lock the home button. Hope this helps :)
My activity creates a system overlay view on the click of a button. I expect this view to remain visible over everything else till i close it on another button click in the activity.
The problem is Android automatically kills that view in a few seconds if i open couple of other applications. I know this is the expected behaviour of Android to manage it's resources. But is there a way to tell Android not to close this view? I tried creating the overlay in an IntentService, but it made no difference.
View creation code :
mFrameLayout = new FrameLayout(mContext);
mFrameLayout.setBackgroundColor(mContext.getResources().getColor(R.color.black));
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT
);
WindowManager windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
windowManager.addView(mFrameLayout, params);
Use service to create your system overlay view.
Not IntentService, just extend Service.
Make it work even if app goes to backgroung by returning "START_STICKY"
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.
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);