Android dismiss a system dialog programmatically - android

I want to dismiss a system generated alert dialog programmatically. I have tried all solutions provided here(stackoverflow) but it does not seem to work.
This is the accepted answer mostly everywhere, but it only dismisses notification panel and recent tasks menu.
I have tested it on devices with os version 4.0.3, 4.2.2, 4.4.2 and 5.1.1, it has the same behavior on all of them. There are apps which can actually dismiss all system dialogs (Mubble). Can someone suggest how it is done?
Thanks

The usual answer to this is
sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
However, this does not work for everything. In particular, on some devices it does not work for the "recent apps" list.
The solution is to detect when your app loses focus and then move your app to the front. Note that your app will need the permission android.permission.REORDER_TASKS to do this.
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
this.keepFocus = true;
}
if (! hasFocus && this.keepFocus) {
ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
am.moveTaskToFront(getTaskId(), ActivityManager.MOVE_TASK_WITH_HOME );
}
}

Related

Screen Overlay Detected | (Android 6.x) Lenovo, Redmi & Samsung Devices

I have created an app which continuously run in background and show an floating overlay TextView(By using the permission android.permission.SYSTEM_ALERT_WINDOW).
I have problem in Lenovo android devices, when other applications try to request for user permission there is an alert dialog says "Screen Overlay Detected". While I have test the same application on Redmi 3S Prime device the "Allow" button in permission dialog is not clickable, until I have turned off the Floating Overlay TextView in my application.
So is there any solution to resolve this device specific issue? One of the possible solution may be disable floating TextView while permission dialog is visible to user and show floating overlay when permission dialog is closed, but the problem is how can I detect the permission dialog open/close state for other foreground application from my app.
Please suggest...
Unfortunately it seems that this is inherent to the Android OS, and as far as I know there is no way to detect when another app is requesting permissions. The general flow for interacting with other apps is to send intents to them in a push manner, so theoretically it could be done if the other apps send an intent to your app to disable the overlay, though this is not a practical solution.
I could be completely wrong, but I am yet to see a programmatic solution to this problem. The best you can probably do is warn your users that your app may cause this problem, and provide them with a quick temporary disable button.
how can I detect the permission dialog open/close state from my app??
Implement Method Mentioned Below, to run this check at the onCreate of the first Activity
public final static int PERM_REQUEST_CODE_DRAW_OVERLAYS = 1234;
/**
* Permission to draw Overlays/On Other Apps, related to
'android.permission.SYSTEM_ALERT_WINDOW'
in Manifest
Resolves issue of popup in Android M and above "Screen overlay detected- To change this permission setting you first have to turn off the screen overlay from Settings > Apps"
If app has not been granted permission to draw on the screen, create an Intent &
set its destination to
Settings.ACTION_MANAGE_OVERLAY_PERMISSION
&
* add a URI in the form of
"package:"
to send users directly to your app's page.
Note: Alternative Ignore URI to send user to the full list of apps.
public void permissionToDrawOverlays() {
if (android.os.Build.VERSION.SDK_INT >= 23) { //Android M Or Over
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, PERM_REQUEST_CODE_DRAW_OVERLAYS);
}
}
}
Called on the activity, to check on the results returned of the user action within the settings
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PERM_REQUEST_CODE_DRAW_OVERLAYS) {
if (android.os.Build.VERSION.SDK_INT >= 23) { //Android M Or Over
if (!Settings.canDrawOverlays(this)) {
// ADD UI FOR USER TO KNOW THAT UI for SYSTEM_ALERT_WINDOW permission was not granted earlier...
}
}
}
}
NOTE:Above code and extract is taken from following gist.
Hope this Helps!!!..
Just clear data of the Es explorer from device then after restart device.
I think these two links could help you.
firstlink
secondlink
Try to use for debug build -- targetSdkVersion 22.
After signed APK (for all targetSdkVersion(s)) application will work fine.

Screen Pinning unreliable: sometimes asks for passcode on awakening, other times skips directly to pinned app

(this question was originally posted on the android enthusiasts stub in a slightly altered form)
I've been trying to lock an android tablet in kiosk mode for a survey app I'm making; for that I've made use of the Screen Pinning lollipop feature (with passcode enabled).
I used the following code
#Override
protected void onResume() {
super.onResume();
startLockTask();
}
For the most part, this worked "reliably",
- If the application is pinned and the user lets the device screen time out (or presses the power/lock button), the device will enter sleep and next time he tries to awaken the device (via the power/lock button) the pinned app will pop into view again (without the user having to enter the passcode that he obviously doesn't know).
- On the other hand if the user attempts to unpin it, he/she is presented with the lock screen and the passcode.
So far so good.
However some times (and this is puzzling me) when the user tries to awaken the device, instead of going directly to the pinned app, the device will display the lock screen and ask the user for the passcode!
I'm not sure why the inconsistency in behavior (ie on wake, it sometimes asks for passcode, while other times goes directly to the pinned app) and couldn't find any mention anywhere of such a behavior.
Any input will be greatly appreciated!
Thanks!
Apparently every time the device wakes up, the startLockTask() is being executed. In case it was already in pinned mode this would run again, and cause issues.
Eventually, I tested out my initial assumption and edited the onResume() function to perform a startLockTask() only if it is not pinned already.
This seems to have solved the problems (even though I don't understand why it this behavior). Would be glad if somebody could explain this.
I'm posting the answer here for anybody who bumps into this issue.
onResume()
#Override
protected void onResume() {
super.onResume();
if(Build.VERSION.SDK_INT >=Build.VERSION_CODES.LOLLIPOP) {
if (!isAppInLockTaskMode()) {
startLockTask();
}
}
}
isAppInLockTaskMode() was taken from enter link description here and solves the issue for different API versions.
public boolean isAppInLockTaskMode() {
ActivityManager activityManager=(ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
if(Build.VERSION.SDK_INT >=Build.VERSION_CODES.M) { // When SDK version is 23
int lockTaskMode=activityManager.getLockTaskModeState();
return lockTaskMode != ActivityManager.LOCK_TASK_MODE_NONE ? true : false;
}
else if(Build.VERSION.SDK_INT >=Build.VERSION_CODES.LOLLIPOP &&
Build.VERSION.SDK_INT< Build.VERSION_CODES.M) {
//When SDK version <=21 and <23. This API is deprecated in 23.
return activityManager.isInLockTaskMode();
}
else {
return false;
}
}

Close status bar when opened: Android

I am trying to come up with some ways of disabling the status bar without hiding it completely. This is an introlude attempt at disabling status bars in 3rd party apps. For now, I want to disable it in my own app, and then eventually create a background service to see if I can do so in other apps. The app I am creating is an operating system for children, and I am trying to develop a closed system.
Here is what I have tried. My initial idea was to monitor when status bar was accessed and then closing it.
#Override
public void onWindowFocusChanged(boolean hasFocus) {
Log.i(TAG, "onWindowFocusChanged()");
try {
if (!hasFocus) {
Log.d(TAG, "close status bar attempt");
Object service = getSystemService("statusbar");
Class<?> statusbarManager = Class
.forName("android.app.StatusBarManager");
Method collapse = statusbarManager.getMethod("collapse");
collapse.setAccessible(true);
collapse.invoke(service);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
This is the method I used. It works for detecting when status bar is being accessed, however, it does not close the status bar once it has focus. What am I missing? Thanks in advance.
I have found answer to my question. First, I was missing the following permission
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
With that permission, the following code now works really well.
#Override
public void onWindowFocusChanged(boolean hasFocus) {
Log.i(TAG, "onWindowFocusChanged()");
try {
if (!hasFocus) {
Log.d(TAG, "close status bar attempt");
//option 1
int currentApiVersion = android.os.Build.VERSION.SDK_INT;
Object service = getSystemService("statusbar");
Class<?> statusbarManager = Class
.forName("android.app.StatusBarManager");
if (currentApiVersion <= 16) {
Method collapse = statusbarManager.getMethod("collapse");
collapse.setAccessible(true);
collapse.invoke(service);
} else {
Method collapse = statusbarManager.getMethod("collapsePanels");
collapse.setAccessible(true);
collapse.invoke(service);
}
// option 2
Intent it = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
mContext.sendBroadcast(it);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
If you notice, there is a second option as well that I found to be working good. You can comment out option 1 if you want to use option 2, or vise versa. Both accomplish the same thing, although I believe option 2 is better.
Intent it = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
mContext.sendBroadcast(it);
The only downfall I found is that it is slow(er) when closing. However, both methods collapse quick enough to where no one can click on any notifications or options in the status bar. Hopefully this is helpful to someone else. Good luck, Cheers!
I am also working on the same thing. With Android 5.0 Lolipop they have released Screen Pinning mode (which is essentially Kiosk mode) which does a few things:
The status bar is blank, and user notifications and status information are hidden.
The Home and Recent Apps buttons are hidden.
Other apps cannot launch new activities.
The current app can start new activities, as long as doing so does not create new tasks.
When screen pinning is invoked by a device owner, the user remains locked to your app until the app calls stopLockTask().
If screen pinning is activity by another app that is not a device owner or by the user directly, the user can exit by holding both the Back and Recent buttons.
You can read about it further in the Android 5.0 Lolipop release documentation.
However, if you are looking for a more controlable solution, then you may want to create a custom ROM. Here is a great overview on making Kiosk applications (which also require disabling status bar).
Developing Kiosk Mode Applications in Android Tutorial
Here's an updated answer if anyone is still looking for a solution to something like this: https://developer.android.com/training/system-ui/immersive.html
For me, I added the following in my onResume() method:
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
decorView.setSystemUiVisibility(uiOptions);
This allows the status bar to stay hidden but the user can still access it by swiping the edge of the screen. Then after a few seconds of inactivity it will collapse and disappear again!

Closing android system dialog box automatically

Is there a way to close the android system dialog box automatically from the app code?? Or else to click a particular portion of a system dialog box when it appears?? I am trying to write a calling app and in that when someone tries to call and if the airplane mode is "on" a system dialog will appear asking to turn off the airplane mode. I want to know whether it is possible to click "ok" in this dialog box automatically...
Thanks in advance...
onWindowFocusChanged method is called when focus is changed. So, we can use that method to disappear system dialog.
#Override
public void onWindowFocusChanged(boolean hasFocus) {
if(!hasFocus) {
// Close every kind of system dialog
Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
sendBroadcast(closeDialog);
}
}

android intercept recent apps button

I have an application meant for children and I do not want them to be able to click the "Recent Apps" button (the one that looks like two rectangles on top of each other). I am taking care of capturing the back button and the home button and I have searched and read a lot about about trying to capture the Recent Apps button, but most say you cannot or the way they do it is very questionable.
The App "Kids Place" pops up a view that says "Action Not Allowed" and redirects you to its home screen if you press the Recent Apps button, this works even if you are in a different app, so how are they doing this?
Any suggestions, hints would be appreciated.
Thanks.
After lots of searching and coding the current best solution I found is the following:
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (!hasFocus) {
windowCloseHandler.postDelayed(windowCloserRunnable, 0);
}
}
private void toggleRecents() {
Intent closeRecents = new Intent("com.android.systemui.recent.action.TOGGLE_RECENTS");
closeRecents.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
ComponentName recents = new ComponentName("com.android.systemui", "com.android.systemui.recent.RecentsActivity");
closeRecents.setComponent(recents);
this.startActivity(closeRecents);
}
private Handler windowCloseHandler = new Handler();
private Runnable windowCloserRunnable = new Runnable() {
#Override
public void run() {
ActivityManager am = (ActivityManager)getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
ComponentName cn = am.getRunningTasks(1).get(0).topActivity;
if (cn != null && cn.getClassName().equals("com.android.systemui.recent.RecentsActivity")) {
toggleRecents();
}
}
}
This requires that you use <uses-permission android:name="android.permission.GET_TASKS" />
When using this approach when the user presses the recent apps button it will cause your activity will go through the activity lifecycle as follows: onPause -> onWindowFocusChanged -> onResume.
To the user the behavior appears that pressing the recent apps button has no response. NOTE: that I have found that if you press the recent apps button quickly it will display that view for brief time.
This is not the best solution, but it is a stab at it. If you have a better solution please share.
The best way I have found is to do this:
public class BaseActivity extends Activity {
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
Log.d("Focus debug", "Focus changed !");
if(!hasFocus) {
Log.d("Focus debug", "Lost focus !");
Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
sendBroadcast(closeDialog);
}
}
}// all credit goes here: http://www.juliencavandoli.com/how-to-disable-recent-apps-dialog-on-long-press-home-button/
This is not my own code, but this just hides the recent apps list from showing.
In the accepted answer you're using ClassName only for Android 4.2 - 4.4. It won't work on 5.0 and higher, or Android 4.1.
Here is the list of ClassNames for main Android versions:
Android 4.1: "com.android.internal.policy.impl.RecentApplicationsDialog"
Android 4.2 - 4.4: "com.android.systemui.recent.RecentsActivity"
Android 5.0 - 7.1: "com.android.systemui.recents.RecentsActivity" ("s" letter was added)
The best solution for you will be to utilize Accessibility Service.
Override onAccessibilityEvent() method, filter out ClassNames listed above and do something when you detect this event. For example simulate pressing the 'Home' button. You can do this by making a global action in Accessibility Service.
thanks esse for solution for higher SDK! I missed it.
But in my case I need to duplicate call (or effect is unstable)
if (SDK>15){
windowCloseHandler.postDelayed(windowCloserRunnable, 10);
windowCloseHandler.postDelayed(windowCloserRunnable, 300);
}
If you are interested in disabling all system buttons, may be the option would be to kill system bar completely, see Easy way to hide system bar on Android ICS

Categories

Resources