Application Priority on Screen - android

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

Related

Window over other apps/lock screen only with user permission in API26

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?

Finish app go back to last open app

I have an application that has a transparent background activity and with only a few buttons. When I switch to my application from another (using the button to switch between applications) I would like to keep the previous app visible in the background. Problem is that switching active app minimizes the previous one and is no longer visible.
Is it possible to do that? I realized that in the Play Store when I throw my request the background remains the Play Store.
Please get me out of my doubt if this is possible or not.
Reality: point 4 return home screen
expectation
does this solve your riddle?
LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View oView = layoutInflater.inflate(R.layout.activity_transperant, null);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
0 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(oView, params);

Create an always-on-top alert on Android from a Service

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.

how to avoid system overlay view being closed

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"

How to create always-top fullscreen overlay activity in Android

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" />

Categories

Resources