Detect changes of “Lock SIM card” in Settings/Secu

2019-01-25 01:14发布

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?

2条回答
神经病院院长
2楼-- · 2019-01-25 01:43

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:

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).

查看更多
再贱就再见
3楼-- · 2019-01-25 01:47

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
查看更多
登录 后发表回答