All,
I am having a very strange issue.
I have the following code that enables and disables the PIN based on certain conditions
DevicePolicyManager mDPM;
ComponentName mDeviceAdminSample;
mDPM = (DevicePolicyManager)context.getSystemService(Context.DEVICE_POLICY_SERVICE);
mDeviceAdminSample = new ComponentName(context, DeviceAdminSampleReceiver.class);
public void disablePINLock(DBHelper myDBHelper, Context context) {
mDPM.setPasswordQuality(mDeviceAdminSample,
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
mDPM.setPasswordMinimumLength(mDeviceAdminSample, 0);
boolean result = false;
result = mDPM.resetPassword("", DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY);
if (result) {
// Toast: "Successfully Disabled PIN lock"
}
else {
// Toast: "Could not disable PIN lock"
}
}
public void enablePINLock(DBHelper myDBHelper, Context context) {
mDPM.setPasswordQuality(mDeviceAdminSample,
DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);
mDPM.setPasswordMinimumLength(mDeviceAdminSample, 4);
Cursor c = myDBHelper.getSetting("'random'");
if (c != null) {
boolean result = mDPM.resetPassword("1234",
DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY);
if (result) {
// Toast: "Successfully Enabled PIN lock"
}
else {
// Toast: "Could not enable PIN lock"
}
}
else {
// Toast: "Could not enable PIN lock"
c.close();
}
}
The code was working fine until a few days ago. I restarted the phone to finish updating and since then the disablePINLock function is not working correctly. When the function executes all I get is
"result" is false and toast message "Could not disable PIN". The enablePINLock method is working just fine and has always worked fine.
Since the restart result = mDPM.resetPassword("", DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY); has failed to execute. I tried to catch an exception but it didn't help.
At this point I am clueless as to why the method stopped working after the restart. I checked the device administrators, enabled/disabled the app few times without any success.
Also I am not sure if this is related, but let me say this. The device administrator screen has my app always checked, even after I uncheck the app and deactivate it, the app name has the box checked.
Thank you in advance for any response.
You say you've "checked the device administrators" but you don't say what you saw there. Are there any other active device administrators on the device? DevicePolicyManager.resetPassword() will return false if the password you provide is not compliant with the aggregate of password policies set by all device admins. It sounds like perhaps another device admin is still active.
Also, with regard to your last point:
The device administrator screen has my app always checked, even after I uncheck the app and deactivate it, the app name has the box checked.
That's a common bug with the Device Administrators screen: the checkbox often stays on even when you've successfully disabled an admin. Try backing out of the Device Administrators screen then going back in. It should be unchecked now.
Related
How can I programmatically determine whether the "Remove permissions if app is unused" setting is enabled or disabled for a particular app?
You can check whether the user has enabled or not, and you can also request them to disable it.
Check if the user has it enabled:
val future: ListenableFuture<Int> =
PackageManagerCompat.getUnusedAppRestrictionsStatus(context)
future.addListener(
{ onResult(future.get()) },
ContextCompat.getMainExecutor(context)
)
fun onResult(appRestrictionsStatus: Int) {
when (appRestrictionsStatus) {
// Status could not be fetched. Check logs for details.
ERROR -> { }
// Restrictions do not apply to your app on this device.
FEATURE_NOT_AVAILABLE -> { }
// Restrictions have been disabled by the user for your app.
DISABLED -> { }
// If the user doesn't start your app for months, its permissions
// will be revoked and/or it will be hibernated.
// See the API_* constants for details.
API_30_BACKPORT, API_30, API_31 ->
handleRestrictions(appRestrictionsStatus)
}
}
ask to disable it:
fun handleRestrictions(appRestrictionsStatus: Int) {
// If your app works primarily in the background, you can ask the user
// to disable these restrictions. Check if you have already asked the
// user to disable these restrictions. If not, you can show a message to
// the user explaining why permission auto-reset and Hibernation should be
// disabled. Tell them that they will now be redirected to a page where
// they can disable these features.
Intent intent = IntentCompat.createManageUnusedAppRestrictionsIntent
(context, packageName)
// Must use startActivityForResult(), not startActivity(), even if
// you don't use the result code returned in onActivityResult().
startActivityForResult(intent, REQUEST_CODE)
}
Source: https://android-developers.googleblog.com/2021/09/making-permissions-auto-reset-available.html
That's a great question and I'm still trying to determine what that even means.
It appears on my Bixby app that came installed on my Samsung. It goes off at random at least 4 times an hour.
I've disabled it many times and I feel "remove permissions if app is unused" is worded in such a confusing way intentionally with the intention to be invasive.
Im using connectivity package to track users connection changes. The idea is to pop up a warning page for connection loss when the ConnectivityResult is none (aka wifi and mobile is disconnected). But instead i get these results :
If the wifi is connected and you disconnect it, 50% of the time the warning pops up.
If you are on mobile and turn it off, the connectivity returns that user is still on ConnectivityResult.mobile not ConnectivityResult.none.
Tried to make a doublecheck with pinging google, but even that doesnt work as smooth as i expected it to be.
My code :
I have created seperated file with functions :
void trackNetworkStatus(BuildContext ctx) {
//check in case state is just opened
pingGoogle(ctx);
//add network listener
Connectivity().onConnectivityChanged.listen((ConnectivityResult result) {
print("Network changed to $result");
//if user lost connection
if (result == ConnectivityResult.none) {
openNoInternetScreen(ctx);
}else{
//if user has connection, doublecheck
//mobile network is tricky on android
pingGoogle(ctx);
}
});
}
Future<void> pingGoogle(BuildContext ctx) async {
try {
//ping internet page
final result = await InternetAddress.lookup('google.com');
//if ping is successful
if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
print('connected');
}else{
print('not connected');
openNoInternetScreen(ctx);
}
} on SocketException catch (_) {
print('not connected');
openNoInternetScreen(ctx);
}
}
void openNoInternetScreen(BuildContext ctx) {
Navigator.push(
ctx,
MaterialPageRoute(builder: (context) => noInternetPage()),
);
}
because i am calling them on every apps init like this :
#override
void initState() {
super.initState();
//listen to netwoek changes
trackNetworkStatus(context);
}
which leads to problem that sometimes warning page pops up twice because, as i believe, the previous listener has not been stopped, but i can figure out how to fix it. The question is why connectivity package returns false callback on mobile. Ive tested on virtual Android API 23 and Samsung S9+, both share same results.
I gave my app to couple early testers and everything turned out just fine for them, even if some of them own Samsung devices too. Looks like there is no problem at all with the connectivity package, some of Samsung phones just act weird as they shouldnt. Looks like there will always be a black sheep in the whole community, sadly thats me and im the developer with this buggy device.
Havent found the fix for my device, but looks like the package is safe to go for the most of the devices in market.
The phone model, that is acting strange : SM-G965F.
I've got an app which connect itself programatically to a wifi connection. My problem is, I want to handle the case, that the password is wrong. I want to detect that the password is not correct in runtime. To be precise I've got a progressdialog running while the connection is established, so if the password is wrong the progressdialog is just shown all the time and can't be skipped. A further note: I handled a password which is less than 8 characters by using this code:
if(!m_wifiManager.enableNetwork(netId, true)) {
progressDialogConnecting.dismiss();
createInfoMessageDialog(CONST.WIFI_CON_FAILED_TITLE, CONST.WIFI_CON_FAILED_MSG_CONFAILURE);
m_wifiManager.reconnect();
return;
}
If the key for the wifi connection is less than 8 characters, this if-case gets triggered. But if it is longer than 8 characters and wrong I get an endless state of showing the progress dialog.
What I exactly want to ask: how do I handle 1. wrong password 2. connection states (just like Android system showing me the toasts "Connected to Wifi xyz") ? AND is it even possible to handel the first one (wrong password)?
Here is the code, that did not work for handling connection established event (this is just the wifirecevier, I also registered it in the activity):
public class WifiReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
if (intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false)){
if(wrongNetworkConnected)
progressDialogConnecting.dismiss();
}
}
} else {
}
}
}
}
Edit: What I am currently doing, is that I have a Handler which tells me to whom I am connected. That's useful because I can say that after the reconnect() I am reconnected to the old network (current network) and not the new one - so apparently the password could be wrong (or something else), because I could not connect to the new network.
The problem about this method is that first of all it takes too much time and secondly it is not reliable. I can lie and say that if you will get reconnected to your current network it is the fault of a wrong password, but actually it is not 100% sure that you cannot reconnect because of this - it may also have other reasons. So I am still searching for a simple feedback/handle from the suplicant that the password is wrong, just like the android api does in the wifi settings of each android device...
My problem is, I want to handle the case, that the password is wrong.
After some research I found this post which is not marked as answered but it still worked for me very well.
Here is the if-case in which the program jumps (already tested several times by me) if there is an authentication error --> e.g. wrong password:
int supl_error=intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, -1);
if(supl_error==WifiManager.ERROR_AUTHENTICATING){
// DO SOMETHING
}
NOTE: As seen in the linked post above this if-case should appear in a BroadcastReceiver adding the intent WifiManager.SUPPLICANT_STATE_CHANGED_ACTIONto the receiver-registration in your activity-class.
I am working at an OEM and would like to know how to deactivate the "Disable option" so that our device user can't remove pre loaded App, which is a security App. Is there an AndroidManifest Attribute in SDK 4.0. If so please let me know.
Thank you much.
No there is not a way to prevent the user from disabling pre-installed apps, and that is very much by design. The philosophy for this is that if disabling an app will not prevent the user from being able to get to settings and re-enable it, then they should be allowed to disable it.
I checked the sourcecode of the Settings app which contains the following function.
The SUPPORT_DISABLE_APPS is a systemwide flag. If you want to prevent any(!) app from beeing disabled, you can set this flag to false.
In short, the comment tells everything: The only apps which can not be disabled are:
(home screen-) launchers. These are identified by implementing a Intent with action ACTION_MAIN and category CATEGORY_HOME.
apps signed with the system cert. As you can modifiy and create this certificate during the build-process of the system image, it should be possible to sign your application with this key and thus prevent the disableing.
if (SUPPORT_DISABLE_APPS) {
try {
// Try to prevent the user from bricking their phone
// by not allowing disabling of apps signed with the
// system cert and any launcher app in the system.
PackageInfo sys = mPm.getPackageInfo("android",
PackageManager.GET_SIGNATURES);
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setPackage(mAppEntry.info.packageName);
List<ResolveInfo> homes = mPm.queryIntentActivities(intent, 0);
if ((homes != null && homes.size() > 0) ||
(mPackageInfo != null && mPackageInfo.signatures != null &&
sys.signatures[0].equals(mPackageInfo.signatures[0]))) {
// Disable button for core system applications.
mUninstallButton.setText(R.string.disable_text);
} else if (mAppEntry.info.enabled) {
mUninstallButton.setText(R.string.disable_text);
enabled = true;
} else {
mUninstallButton.setText(R.string.enable_text);
enabled = true;
}
} catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, "Unable to get package info", e);
}
There is nothing in the SDK for this. However, an app you put in the firmware cannot be uninstalled by the user, unless they root their device.
I am facing one strange problem, when i run my android application on the device so either it will be running on foreground or background , it should not loose the WiFi connection, for that I have get the WiFiManager and acquired the lock in Service's onCreate() method and release it on onDestroy method. But facing problem to keep WiFi turned on when device goes to sleep mode, so is there any way to make WiFi turned on even if device goes to sleep mode.
I can't acquire the lock to wake up the device because scenario is our application will run always so whenever user will not use, device should go to sleep mode but wifi connection should always be turned on.
Please do help me resolve this issue, please share some sample code also.
Regards,
Piks
Try to use Services. Just insert you wifi connection code in a service, and this will run forever in background.
Maybe this will help..
private void setNeverSleepPolicy() {
try {
ContentResolver cr = getContentResolver();
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) {
int set = android.provider.Settings.System.WIFI_SLEEP_POLICY_NEVER;
android.provider.Settings.System.putInt(cr, android.provider.Settings.System.WIFI_SLEEP_POLICY, set);
} else {
int set = android.provider.Settings.Global.WIFI_SLEEP_POLICY_NEVER;
android.provider.Settings.System.putInt(cr, android.provider.Settings.Global.WIFI_SLEEP_POLICY, set);
}
} catch (Exception e) {
e.printStackTrace();
}
}