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.
Related
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().
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 :)
Is there any way to give an app permission to launch an activity on top of another app? For example, when someone calls you on your phone while you're using another app, the calling activity takes priority.
to grant permission, add
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
to your manifest file.
to display view on top of other apps use the window manager
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
WindowManager.LayoutParams paramsForButton = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
windowManager.addView(yourViewWindowManager.LayoutParams, paramsForButton);
I have a service in which, when the user shakes his/her phone, shows a full screen overlay window. I'm using this code to get it done:
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mOverlayView = inflater.inflate(R.layout.overlay, null);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_DIM_BEHIND | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |WindowManager.LayoutParams.FLAG_FULLSCREEN,
PixelFormat.TRANSLUCENT);
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(mOverlayView, params);
It fills up the whole screen, EXCEPT for the navigation bar. Is there a way I can hide the navigation in my service that displays the overlay?
Note that my app is running in the background. The user may be running any other app in the foreground, and I want to show my full screen overlay window even if my main activity is not running.
All examples I could find online all seem to require an activity running...
Thanks for any help!
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"