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.
Related
I made a Xamarin.Forms project to create and show local notifications, and it's supposed to be able to put the app back to the foreground when the notification is clicked.
The thing is, my code works on Android 11 and before, but on Android 12 & 13 the notification click is received by the app, if I have a callback for that notification it is called, but the app stays in background.
This is the part of the code that runs when I received a notification click and that I want to set the app in foreground (this is in the Xamarin Android project) :
var packageManager = Application.Context.PackageManager;
Intent launchIntent = packageManager.GetLaunchIntentForPackage(Constants.PackageName);
if (launchIntent != null)
{
launchIntent.AddCategory(Intent.CategoryLauncher);
Application.Context.StartActivity(launchIntent);
}
I have found a lot of posts on how to start/set to foreground an app, and the code I use is what's working for others, but all these posts where from 2020 and before, so no Android 12+ at the time and I can't find anything about a new way of doing this.
Does anyone have this functionality working on the newest Androids ?
I have found the solution so I'll post it here if someone needs it.
The code I use to put the application back to the foreground is correct, but I was missing the System_Alert_Window permission in my main application.
So to handle this permission I did :
Add it to my main application's manifest
Create a native method that checks if it is enabled
Create a native method that redirect the user to the overlay settings so they can allow the permission.
To check if the permission is enabled :
public bool HasOverlayPermission()
{
if (Build.VERSION.SdkInt < BuildVersionCodes.M)
return true;
return Android.Provider.Settings.CanDrawOverlays(Application.Context);
}
To redirect the user to their phone settings for AppOverlay (this permission can only be allowed from the settings) :
public void AskForOverlayPermission()
{
if (Android.Provider.Settings.CanDrawOverlays(Application.Context))
return;
var uri = Android.Net.Uri.Parse("package:" +
Application.Context.PackageName);
Intent intent = new Intent(
Android.Provider.Settings.ActionManageOverlayPermission, uri);
_mainActivity.StartActivityForResult(intent, 101);
}
The StartActivityFromResult method is only accessible in Activity classes, so you can either write it in you MainActivity or give your MainActivity as constructor parameter of another class.
This code will directly redirect the user to the settings page, so it's better if you ask them if they want to allow this permission in a popup or something beforehand (so they can understand why they're redirected).
I have found the code in this post : How to enable screen overlay permission by default
I would like to add a chat feature in my app that would be available across all activities - you can start a chat within one activity and keep it live when changing activities.
Before Android M (6.0 - API 23), I was able to add the following permission in the app manifest:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
And create a view above all others using TYPE_PHONE LayoutParam.
Since Marshmallow, I am now required to ask for user permission using the following:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, 1234);
}
}
My problem is, this is very intrusive for users, plus I don't need a view visible over all applications - a view visible over my app would be enough.
Does such a solution exist?
One other constraint I have is that I can't always modify the app layout files - my chat feature could be included inside other apps.
Thank you.
I'm trying to implement locking the screen with my app.
I've worked my way through google documentation and studied the sample.
When i call this
void getAdmin(){
Intent activateDeviceAdminIntent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
activateDeviceAdminIntent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mPolicy.getPolicyAdmin());
activateDeviceAdminIntent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
getResources().getString(R.string.AdminReceiverDescr));
startActivityForResult(activateDeviceAdminIntent, REQ_ACTIVATE_DEVICE_ADMIN);
}
The dialogue doesn't show up (maybe it flashes a little, can't say for sure), it just jumps in my onResult routine and result is "not granted". But my app afterwards shows up in the list in settings/security/device admins and if i enable admin rights manually it locks my screen like a charm.
I've added the permission
uses-permission android:name="android.permission.BIND_DEVICE_ADMIN"
as well as
receiver ... android:permission="android.permission.BIND_DEVICE_ADMIN"
to my manifest.
Does anyone have a clue what i may have missed?
Thx in advance!
Found the problem in my manifest: you have to specify the receiver subclass with a $ sign.
Example:
android:name="com.exampl.PolicyClass$PolicyReceiver"
I have encountered strange issue. From Activity onStart() I request Bluetooth activation and 120s discoverability via intent:
Intent activateBTIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
startActivityForResult(activateBTIntent, BT_ACTIVATE_INTENT);
I use it no matter if the Bluetooth is already activated or not. Android documentation says that Bluetooth will be activated if it was not, and that works fine. In both cases I get system Alert dialog
When I rotate the screen I observe flickering. Press on Yes/No removes one dialog, but there is still another one below. Performing screen rotation I can get a pile of Alert dialogs, and have to press Yes/No on each to get rid of them.
Described issue is present only if Bluetooth was not already started when intent was sent, otherwise it works correctly. Tried on different 2.2 phones, and issue is present on all. Looks to me like Android system issue.
Has anybody encountered it also, and maybe have some useful hint how to avoid this?
Thanks and regards.
This is a bug in the Settings app that causes this. The RequestPermissionActivity is duplicating its instance of RequestPermissionHelperActivity on rotations.
I was facing the same problem. After spending lots of time with it, i have found one solution.
You can avoid the duplication of the 'Bluetooth activation Alert dialog' by using
FLAG_ACTIVITY_NO_HISTORY flag for activateBTIntent. But setting this flag will make startActivityForResult unusable.
The code -
Intent activateBTIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
activateBTIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(activateBTIntent);
Using FLAG_ACTIVITY_NO_HISTORY with activateBTIntent will remove the 'Bluetooth activation Alert dialog' activity from the history stack. Thus in this case, when orientation is changed, the 'Bluetooth activation Alert dialog' activity will be finished and newel created(NOT DUPLICATED):
Reference
http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_NO_HISTORY
(Your post doesn't nearly have enough info, so I'm assuming here...)
I'm not too sure about the startActivityForResult.
You shouldn't do showDialog() in onCreate() if you use a managed AlertDialog. If the Bluetooth thingy does that, could you try not running the above code from onCreate()?
The issue has been reported (google issue tracker) but it is already open after 6 years (checked with Android 7.1.2).
Unfortunately the flag FLAG_ACTIVITY_NO_HISTORY does not work anymore. The only quick workaround I found until Android team fix this (if they ever will) is to lock activity screen orientation change, just for the time the dialog is displayed:
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
to be called just before
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
and then use
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_ENABLE_BT) {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
super.onActivityResult(requestCode, resultCode, data);
}
on intent result.
It's a temporary remedy but usually better than showing this possible issue during BT activation.
I'm writing a program for the Android Platform and I would like to implement the code of a preexisting application found here .
There is a button in my application menu that says "Show Friends on Map" so I want this program to start from the button press.
For greater detail I will give a small diagram.
User Starts My application > User Presses "Menu" Key > User Presses "Show Friends on Map" > WAMF.apk (the application in the link above) is launched
Is there any way I can do this?
If I understand you correctly and all you want to do is launch WAMF, see this blog post.
In it is the following code, which will detect whether the OpenTable (or WAMF, in this question) is installed, and if so invoke it, otherwise take the user to the Android Market to download OpenTable:
public void showReserveButton() {
// setup the Intent to call OpenTable
Uri reserveUri = Uri.parse(String.format( "reserve://opentable.com/%s?refId=5449",
opentableId));
Intent opentableIntent = new Intent("com.opentable.action.RESERVE", reserveUri);
// setup the Intent to deep link into Android Market
Uri marketUri = Uri.parse("market://search?q=pname:com.opentable");
Intent marketIntent = new Intent(Intent.ACTION_VIEW).setData(marketUri);
opentableButton.setVisibility(opentableId > 0 ? View.VISIBLE : View.GONE);
opentableButton.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
PackageManager pm = getPackageManager();
startActivity(pm.queryIntentActivities(opentableIntent, 0).size() == 0 ?
opentableIntent : marketIntent);
}
});
}
As commonsware says, this is assuming that WAMF is available in the Android market. If not, you're out of luck.
(I'm hoping Reto Meier sees your question, as WAMF is his app)
Well, as I see it, you have two main choices.
Option #1 says that WAMF is installed as a separate application. That may be tricky, as it is unclear if this application is available for distribution anywhere (e.g., Android Market). But, assuming it is, and assuming the user has the app installed, when the user invokes your desired menu choice, you need to call startActivity(), using an Intent that will resolve to whatever in WAMF you would like to have displayed. You can also use PackageManager to detect if WAMF is installed (i.e., seeing if there are any activities that would match the Intent you want to use in startActivity()) -- that way, you can disable the menu choice, or have it pop up a dialog telling people to install WAMF, or something.
Option #2 says that, since WAMF is Free Software, you simply integrate the relevant portions of code straight into your app. On the plus side, there's no question whether the code is there. However, should Mr. Meier update the year-old WAMF, you would have to re-integrate his changes. Also, his application is released under GPLv3, which may or may not work with your own app's licensing scheme.