Need to show the Activity (Theme dialog) over the dialer with some information populated in activity like true caller. In unlocked phone, it is working well.
But in locked phone, it didnt work as expected. Did some googling and found few flags needs to be added to make dialog appear in lock screen.
CallActivity.java
LayoutParams layoutParams = new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT, LayoutParams.TYPE_SYSTEM_DIALOG | LayoutParams.TYPE_SYSTEM_ALERT |
LayoutParams.TYPE_SYSTEM_OVERLAY,
LayoutParams.FLAG_NOT_TOUCH_MODAL |
LayoutParams.FLAG_NOT_FOCUSABLE |
LayoutParams.FLAG_TURN_SCREEN_ON |
LayoutParams.FLAG_SHOW_WHEN_LOCKED |
LayoutParams.FLAG_KEEP_SCREEN_ON |
LayoutParams.FLAG_DISMISS_KEYGUARD,
PixelFormat.TRANSLUCENT);
getWindow().setAttributes(layoutParams);
In the above code, i added changes related to make activity appear as dialog and few flags (FLAG_TURN_SCREEN_ON, FLAG_SHOW_WHEN_LOCKED, FLAG_KEEP_SCREEN_ON, FLAG_DISMISS_KEYGUARD) related to make dialog work well in lock screen (but it didnt).
I also starting the activity with (from broadcast receiver)
Intent intent = new Intent(context, MyActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
context.startActivity(intent);
add view on window manager with System Alert permission
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
mParams = new WindowManager.LayoutParams();
mParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
mParams.format = PixelFormat.TRANSLUCENT;
mParams.flags = 262184;
mWindowManager.addView(view, mParams);
Note: If the app targets API level 23 or higher, the app user must explicitly grant this permission to the app through a permission management screen. The app requests the user's approval by sending an intent with action ACTION_MANAGE_OVERLAY_PERMISSION. The app can check whether it has this authorization by calling Settings.canDrawOverlays().
Related
I am trying to create an activity that would pop up in full screen and be shown over the screen lock (similar to every alarm clock in Android which shows a full screen dialog to dismiss an alarm). Here is my code to display the window:
if (Build.VERSION.SDK_INT>=26) windowType = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
else windowType = WindowManager.LayoutParams.TYPE_TOAST;
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
windowType,
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_FULLSCREEN,
PixelFormat.TRANSLUCENT
);
wm = (WindowManager) getApplicationContext()
.getSystemService(Context.WINDOW_SERVICE);
mTopView = (ViewGroup) getLayoutInflater().inflate(R.layout.activity_alarm_screen, null);
getWindow().setAttributes(params);
wm.addView(mTopView, params);
My concern here is that my app will need a special permission to show this window over other applications, and this scares users off. In API25 and lower I used TYPE_TOAST instead of TYPE_APPLICATION_OVERLAY, but in API26 it leads to:
FATAL EXCEPTION: main Process: com.app.alarm, PID: 31372
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.app.alarm/com.app.alarm.Activities.AlarmScreenActivity}: android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W#601b8a2 -- permission denied for window type 2009
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
I saw this question, but it does not avoid asking a special permission.
Any other trick in API26 to avoid making a user allow a special permission that my app doesn't really need?
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 :)
I've been trying for weeks to find a proper solution to this problem, but I still couldn't find anything.
Basically, what I'm trying to do is to create an alert dialog box from a running service (that monitors for some event). The alert dialog should always appear on top of everything else, even if the phone is locked. I'm looking for something similar to what happens when someone calls you, or when an alarm clock goes off.
The best solution I've found was the following:
WindowManager mWindowManager = (WindowManager)
mContext.getSystemService(Context.WINDOW_SERVICE);
LayoutInflater layoutInflater = (LayoutInflater)
mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mView = layoutInflater.inflate(R.layout.layout_alert, null);
mLayoutParams = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT, 0, 0,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
PixelFormat.RGBA_8888);
mWindowManager.addView(mView, mLayoutParams);
And in the manifest:
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
The problem is that if I use the TYPE_SYSTEM_ALERT, then the dialog is always shown as I wanted, but I cannot receive any touch events on the buttons I have in the view. On the other hand, if I use TYPE_PRIORITY_PHONE, then I do receive all touch events - but the alert isn't shown above the lock screen.
I have a broadcast receiver for intercept an incoming call.
After that, I have to show a popup with some informations, I created an Activity PopupActivity and I call it in this way
Intent newIntent = new Intent(context, PopupActivity.class);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(newIntent);
the activity onCreate method is the follow
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.toast);
WindowManager.LayoutParams wmlp = getWindow().getAttributes();
wmlp.gravity = Gravity.TOP | Gravity.CENTER_VERTICAL;
setFinishOnTouchOutside(false);
and this is the manifest
<activity
android:name=".PopupActivity"
android:theme="#android:style/Theme.Dialog"></activity>
with HsetFinishOnTouchOutside(false) I prevent the dialog closing when I touch outside the popup, this is fine, but I want touch the dialer for answer the call.
So I need to keep the focus outside the popup without closing it.
Second question, I have a delay between the incoming call and the response of the broadcast receiver, how can I make it more responsive?