A question aimed at Android 4.0.x preferably.
I want to detect immediately, or after a few seconds, any change made to Lock SIM card
in Settings > Security > Set up SIM card lock
.
I tried 3 methods:
1) access read-only com.android.settings
shared preferences.
Context settings = getApplicationContext().createPackageContext("com.android.settings", Context.CONTEXT_IGNORE_SECURITY);
SharedPreferences prefSettings = settings.getSharedPreferences("com.android.settings_preferences", MODE_WORLD_READABLE);
Map<String, ?> allSettings = prefSettings.getAll();
for(String s : allSettings.keySet()){
//do somthing like String value=allSettings.get(s).toString());
}
There is a warning in logcat: "Attempt to read preferences file /data/data/com.android.settings/shared_prefs/com.android.settings_preferences.xml without permission". The map returned by getAll()
is empty.
2) ITelephony.isSimPinEnabled()
always returns false, even when the SIM PIN is enabled and set. So it appears changing the setting has absolutely nothing to do with this interface. I was thinking of polling the interface but this is no good either.
3) creating a ContentObserver
observing Settings.Secure
is not working here. Actually, reading the content of settings.db
with sqlite shows there isn't any record modified when changing this setting. This was also confirmed by the following code:
try {
int lockPattern = android.provider.Settings.Secure.getInt(getContentResolver(), android.provider.Settings.Secure.LOCK_PATTERN_ENABLED);
// check lock Pattern: 0=disabled, 1=enabled
} catch (SettingNotFoundException e) {
e.printStackTrace(); // on run, we reach this line.
}
The only thing I am sure is that modifying the SIM PIN enabled
setting rewrites com.android.settings preferences.xml file as shown below:
$adb shell cat /data/data/com.android.settings/shared_prefs/com.android.settings_preferences.xml
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<boolean name="sim_toggle" value="true" />
<string name="sim_pin"></string>
</map>
The tag affected by the change is sim_toggle
.
Does anyone have an idea? What am I doing wrong here?
Had to implement a way to finde out if the SimPin is Enabled today. The ITelephony.isSimPinEnabled() always returned false for me, too. Didn't try the other methods you described.
I found a way to get the current setting:
First you need to get hold of a proxyPhone Object, how this can be done can be seen here: Can a telephony.Phone object be instantiated through the sdk?
Then you can retrieve the IccCard-Object and on this execute the method getIccLockEnabled.
Code:
Object proxyPhone = PhoneUtil.getProxyPhoneInstance(this);
Class<?> phone = Class.forName("com.android.internal.telephony.Phone");
Method getIccCardMethod = phone.getDeclaredMethod("getIccCard");
Object iccCard = getIccCardMethod.invoke(proxyPhone);
Class<?> iccCardClass = Class.forName("com.android.internal.telephony.IccCard");
Method getIccLockEnabled = iccCardClass.getDeclaredMethod("getIccLockEnabled");
Boolean isIccLockEnabled = (Boolean) getIccLockEnabled.invoke(iccCard);
works for me on Android 2.3(+?), but as mentioned in the other thread you have to run this code as phone-user/as phone-process.
Really kinda disappointed that there is no public api / deviceAdmin-Api for this. Could imagine that companys want to ensure that their employes keep the sim pin enabled (case of theft).
Well, I think I have a easy way to detect if a Sim PIN has to be entered. Best of all it's is avaliable via the SDK. You could run this in a PhoneStateListener
...
public static boolean isSimPinRequired(){
TelephonyManager m = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (m.getSimState() == TelephonyManager.SIM_STATE_PIN_REQUIRED) return true;
return false;
}//end method
来源:https://stackoverflow.com/questions/11211420/detect-changes-of-lock-sim-card-in-settings-security-set-up-sim-card-lock