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
Related
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 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);
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'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" />
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);