0

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?

slash33
  • 899
  • 1
  • 11
  • 17
  • I got a better shoot at what I am aiming to do: I want to capture internal/telephony/IccCard class event EVENT_CHANGE_FACILITY_LOCK_DONE. Is there a way to do this? It does not seem one of the three registrant lists does the job. – slash33 Jul 10 '12 at 07:44

2 Answers2

1

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

Community
  • 1
  • 1
icyerasor
  • 4,973
  • 1
  • 43
  • 52
  • I'm going to test your proposal. It seems to match my requirements since I use an external module running in the process com.android.phone. Actually, I already have an ITelephony object in there. – slash33 Dec 13 '12 at 14:02
  • Is PhoneUtil class still there in Android SDK? I was not able to find any related documentation. – Tejzeratul Apr 16 '16 at 05:50
-1

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
slinden77
  • 3,378
  • 2
  • 37
  • 35