I am using Device Policy Manager in my Android App and I have a problem with Honeycomb devices. When attempting to call resetPassword I get an exception thrown. This is not the case in Froyo or Gingerbread, as both of those work fine.
The error is:
java.lang.RuntimeException: Unable to start receiver Package.Name.Test: java.lang.SecurityException: Permission Denial: writing com.android.providers.settings.SettingsProvider uri content://settings/secure from pid=x, uid=y requires android.permission.WRITE_SETTINGS
My Android Code is as follows:
DevicePolicyManager mDPM = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
if ((mDPM.getActiveAdmins() != null) && (mDPM.isAdminActive(new ComponentName(context, DeviceAdmin.class)))) {
mDPM.resetPassword(extra, DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY);
mDPM.lockNow();
} else {
Log.d(TAG, "Could not lock because device admin not enabled");
}
The problem occurs at:
mDPM.resetPassword(extra, DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY);
My Device_Admin.xml is:
<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
<uses-policies>
<force-lock />
<wipe-data />
<reset-password />
</uses-policies>
</device-admin>
Like I said the device admin works great on Froyo and Gingerbread devices, although I do have some problems with users using different keyguards, an example is the Droid X and HTC Sense. This problem is with timing. When I call lockNow the device will turn off the screen but HTC Sense or MotoBlur will not actually lock the keyguard until the time that was set in Settings, Security, Lock Phone After.
Any help would be awesome! I just recently got a honeycomb tablet at I/O and haven't tested the app out on this device yet, but I see the errors on the market website with users with the Xoom running 3.0. Have not seen any 3.1 devices yet.
I struggled with this also. The solution is also listed on one of your links, but I'll mention it here also in case it helps someone else.
If the device is brand new (or factory reset) the code fails as you describe.
If the user enters a password using the settings menu just once, somehow the same code starts working and keeps on working.
A very weird bug indeed!!
On Android Honeycomb 3.0 platform, the DevicePolicyServiceManager is very different from Gingerbread, the whole flow of resetPassword() is:
DevicePolicyServiceManager.resetPassword() -->
LockPatternUtils.checkPasswordInHistory() -->
LockPatternUtils.passwordToHash() -->
LockPatternUtils.getSalt() -->
LockPatternUtils.putLong(SALT_KEY, salt) -->
Settings.Secure.putLong(SALT_KEY, salt)
Here you should know why WRITE_SETTINGS is required, it seems that this is Google's mistake, they did not put the LockPatternUtils.checkPasswordInHistory() method in Binder.clearCallingIndentity() block.
One more thing, even if you add WRITE_SETTINGS permission in your AndroidManifest.xml file, it will tell you that WRTITE_SECURE_SETTINGS permission is also required.
Hope Google can fix this issue ASAP.
P.S. It seems that this issue has been fixed on ICS platform, Google has removed the checkPasswordInHistory() from resetPassword() block. I do not think this is a good solutoin and i don't know why? Maybe they wanna release ICS as soon as possible?
I also faced this problem, what i can tell is if you didn't set the password manually even single time, the it will give force close asking for write_settings permission but if you try once by setting password manually from there on-wards it will work like charm.
I was looking at this problem (which is readily reproducible on 3.1 as well, btw), but it appears that you already figured it out, based upon the issue you filed. I just wanted to note that here in case anyone else tried to research the answer.
Related
Here is my code:-
public void onClick(View v) {
try {
startActivity(new Intent(
"android.intent.action.SHOW_ALARMS"));
} catch (ActivityNotFoundException ignore) {
Toast.makeText(ac, "ActivityNotFoundException",
Toast.LENGTH_LONG).show();
}
}
This works on the Android emulator running Android 12 API 31: it shows the system clock application with the alarms page. On my Samsung Galaxy S21, also running Android 12 API 31, I get this error:-
Process: uk.co.yahoo.p1rpp.secondsclock, PID: 27629
java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.SHOW_ALARMS cmp=com.sec.android.app.clockpackage/.alarm.activity.AlarmCTSHandleActivity } from ProcessRecord{769a91e 27629:uk.co.yahoo.p1rpp.secondsclock/u0a362} (pid=27629, uid=10362) requires com.android.alarm.permission.SET_ALARM
at android.os.Parcel.createExceptionOrNull(Parcel.java:2437)
at android.os.Parcel.createException(Parcel.java:2421)
at android.os.Parcel.readException(Parcel.java:2404)
at android.os.Parcel.readException(Parcel.java:2346)
at android.app.IActivityTaskManager$Stub$Proxy.startActivity(IActivityTaskManager.java:2878)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1743)
at android.app.Activity.startActivityForResult(Activity.java:5465)
at android.app.Activity.startActivityForResult(Activity.java:5423)
at android.app.Activity.startActivity(Activity.java:5809)
at android.app.Activity.startActivity(Activity.java:5762)
at uk.co.yahoo.p1rpp.secondsclock.SettingsActivity$25.onClick(SettingsActivity.java:538)
...
Here is the first bit of my AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="uk.co.yahoo.p1rpp.secondsclock">
<uses-permission android:name="android.permission.SET_ALARM" />
...
I'm actually asking for the permission even though I shouldn't need it since I'm asking to look at the alarms, not to set one. Without the permission request in the manifest, it still works on the emulator and fails in the same way on the phone.
I see the same behaviour (on both the emulator and the phone) with both debug and release builds.
In case someone asks why I'm doing this, I've written a home screen seconds clock widget, which will be published on github when I have it fully working. I want clicking on the widget to go to the system's clock app, which doesn't work because of this problem. The code shown is test code to check why the code in the widget fails, because the widget code executes in the context of the home screen launcher and is harder to debug.
I can go to the system clock app by using an Intent with its ComponentName (and this works without an error on the phone), but different Android phone models have different clock apps with different Componentnames, so it will only work on one type of phone. I did have code to search the PackageManager for the ComponentName of a clock, but Google's latest security upgrade in API 31 doesn't allow me to do that any more.
Why is the SecurityException happening and what if anything can I do to prevent it?
Why is the SecurityException happening
Samsung apparently has an android:permission attribute for that <activity> requiring that callers need to hold that permission to be able to start that activity.
what if anything can I do to prevent it?
You cannot prevent it. Samsung requires that permission, either intentionally or due to some screwup. You either need to hold the permission or you need to wrap the startActivity() call in a try/catch and "gracefully degrade" if you get that exception.
It does not required the permission that you have mentioned above rather it requires a different permission.
Replace this
<uses-permission android:name="android.permission.SET_ALARM" />
With
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
I'm trying to find out how to achieve the following:
The people in the chat hinted that it may be a system-app setting, but that was as far as I could get.
Even being a system-app setting I cannot find it anywhere, so what do I need to do in order for my app to be able to do the same thing?
Before anyone comes with comments stating how user-unfriendly this is and not to do it, this is not for a generic app but for a business centered work environment where it is important to ensure the notifications are not turned off, especially when the devices can be passed onto other colleagues between shifts and one of them could've turned something off and the others are not aware of.
As it seems this is only possible with system apps or at least with apps that have special access - which is not available to apps normally installed from the PlayStore or similar.
You can specify which app features your app requires. Such that if they turn off the feature, or don't have the feature, the app won't run. In the manifest file you would declare something like:
<uses-feature android:name="android.hardware.telephony" android:required="true" />
<uses-permission android:name= "android.permission.RECEIVE_WAP_PUSH" />
In your app, you would need to check if the user has granted the permission to RECEIVE_WAP_PUSH and if not, display an error message and force them to exit the app.
I have an app that allows users to login using fingerprint authentication. The feature has been in production for a couple of months, but in the last day I started seeing many of these exceptions:
java.lang.SecurityException: Must have android.permission.USE_FINGERPRINT permission.: Neither user ##### nor current process has android.permission.USE_FINGERPRINT.
The crash occurs when I call fingerprintManager.isHardwareDetected() to check whether or not the device supports fingerprint authentication. I have the USE_FINGERPRINT permission declared in the manifest, so I don't know why the system would think that the process does not have this permission. This should not be something that I have to check at run time since USE_FINGERPRINT is a normal permission.
This has been working fine for months, and when it started crashing yesterday, we had been on a stable release for about a month. This problem sounds almost identical to this FingerprintManager.isHardwareDetected() throwing java.lang.SecurityException?. I am only seeing the crash on Oreo devices.
My current plan is to catch the Security Exception and proceed as if the device did not have the hardware, but my worry is that this might mean that no one is able to use the feature for login if this problem persists. Has anyone else had a recent issue with this exception? Or if not, does anyone have any ideas about why this might have just started happening all of a sudden like this? Thanks for the help!
Use the FingerprintManagerCompat instead, that was handling permissions correctly for me.
See:
https://developer.android.com/reference/android/support/v4/hardware/fingerprint/FingerprintManagerCompat
Additionally you might want to declare the permissions in your Android Manifest:
<!-- Fingerprint -->
<uses-permission-sdk-23 android:name="android.permission.USE_FINGERPRINT" />
Note that I used uses-permission-sdk-23, since I found that FingerprintManager doesn't work reliable in older versions of Android, I know there are some Samsung Galaxy devices with fingerprint reader, but before API 23 you were granting permissions at installation time; that depends more on your market. Try it and see if it makes a difference for your users.
See: https://developer.android.com/guide/topics/manifest/uses-permission-sdk-23-element
I have the following problem:
My app is distributed over an MDM system and runs in Android for Work.
In certain situation, the app must temporarily terminate the DnD mode. To achieve this, the user must grant the DnD permission when the app is started.
So far so good. If I install the app in the unmanaged area, the app shows up in the list and the permission can be granted without any problems.
As soon as the app is distributed via an MDM system, the app no longer appears in the list and the permission cannot be granted. All authorizations have been granted in the MDM system. As an example, I have distributed the Google App over the MDM system. This app appears in the list.
In the Manifest I have set the following permission:
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
When the app is started, the following code is executed:
NotificationManager nm = (NotificationManager).getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M && !nm.isNotificationPolicyAccessGranted()) {
Intent intent = new
Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
startActivity(intent);
}
The problem only occurs with DnD permission. All other permissions such as overlay permission, are displayed without problems.
I hope anyone can help me.
According to Android documentation: NOT POSSIBLE
Users can grant and deny access to Do Not Disturb configuration from here. Managed profiles cannot grant Do Not Disturb access.
I haven't found a proper solution for the problem yet but I found a workaround to display the app in the work area. It seems that the app is only displayed in the dialog if the same app is also installed in the private area.
If the app is not installed in the private area, it will also not appear in the work area.
My workaround was to install the app in the private and work area. After the permission in the work area was granted, I removed the app from the private area. Like I said, it's not a solution to the problem itself, but it worked.
To me this looks like a bug in Android, because for all other permissions the app appears in the list
Apparently there is issure reported regarding this on Google Issue Tracker
https://issuetracker.google.com/issues/77939714
This is the reply from Google:
Status: Won't Fix (Intended Behavior) 11:41AM You can not change DND
settings from a managed profile app. We will be updating the
documentation to clarify this.
There is also a reply stating:
Microsoft Intune has released their fully managed Android Enterprise
profile setup for Android Devices. ... and it can now access and
grant the DnD permission. Not sure if its the fact that we have gone
to fully managed devices or if something else has changed.
And I would believe this is actually because the device is fully managed.
So according to my understadning there are two options:
Fully managed device (will require a factory reset on the phone)
Install it on the personal profile
We have the same issue with the app SignOnSite. Can't get access to the DnD function for emergency evacuations unless we also install the app in the Personal space as well. Makes it to risky doing it this way, so ended up just installing the app in the Personal space.
Using Intune for our MDM.
Try this -
Intent intent = new Intent("android.settings.NOTIFICATION_POLICY_ACCESS_SETTINGS");
startActivity(intent);
I googled for an example source code for blocking calls and came across this EXAMPLE, But later I came to know that Google has updated their policy and
android.permission.MODIFY_PHONE_STATE
is an system level permission from android version 2.3, I have very important module placed on blocking a specific call.
How do I get a system level permission?
Please let me know if there is any way I can do this in my application. Its very important for the product and cannot be released without this functionality.
Please Help!
Thanks in advance
At least as of Android 5.0, MODIFY_PHONE_STATE has the following definition:
<permission android:name="android.permission.MODIFY_PHONE_STATE"
android:permissionGroup="android.permission-group.PHONE_CALLS"
android:protectionLevel="signature|system"
android:label="#string/permlab_modifyPhoneState"
android:description="#string/permdesc_modifyPhoneState" />
Your app can only hold this permission and use it to modify the phone state if it is signed by the firmware's signing key (the "your own custom ROM" scenario from Marcin's comment) or if your app is installed on the system partition. The latter can be accomplished by having your app pre-installed on the device (or having a rooted device user move your app to the system partition, as I understand it).