使用SharedPreferences的自定义子类与PreferenceActivity或PreferenceFragment

Jay*_*ont 15 android android-preferences sharedpreferences

我正在使用SharedPreferences的自定义子类来加密我在应用程序中保存的设置,类似于第二个响应中的操作:在Android应用程序中存储用户设置的最合适方式是什么

我必须保存的偏好数量正在增加.在我使用自定义视图更新这些首选项之前,这将变得很麻烦,我想使用PreferenceActivity或PreferenceFragment.问题是,似乎没有办法让这些类中的任何一个使用我的子类访问我的数据,这意味着它从默认首选项文件中提取的数据将是乱码,因为它没有被解密.

我发现有些人已经创建了Preference的自定义实现来加密那里的数据,但是我不想这样做,因为数据已经在我的SharedPreferences子类中加密/解密了,我想保留它办法.我一直在查看PreferenceActivity和PreferenceManager的源代码,我不确定解决这个问题的最佳方法.

有没有其他人有幸做完这样的事情并对我可能从哪里开始有任何建议?

pjc*_*jco 2

我认为通过将加密保留在已有的 SharedPrefs 子类中,您可以限制模块化和关注点分离。

因此,我建议重新考虑对首选项类本身进行子类化(例如 CheckBoxPreference)并在那里执行计算。

理想情况下,您还可以使用某种类型的组合或静态实用程序,这样虽然您可能必须对您使用的每种类型的首选项进行子类化,但您可以使用单个位置来执行加密/解密计算。如果您将来需要加密或解密某些其他数据或者 API 发生更改,这也将为您提供更大的灵活性。

对于子类化,也许你可以这样做:

例如:

class ListPreferenceCrypt extends ListPreference
{
    ListPreferenceCrypt (Context context, AttributeSet attrs)   {
        super ( context, attrs );
    }
    ListPreferenceCrypt (Context context)   {
        super ( context );
    }

    @Override
    public void setValue( String value )
    {
        //encrypt value
        String encryptedVal = MyCryptUtil.encrypt(value);
        super.setValue ( encryptedVal );
    }

    @Override
    public String getValue( String key )
    {
        //decrypt value
        String decryptedValue = MyCryptUtil.decrypt(super.getValue ( key ));
        return decryptedValue;
    }

}
Run Code Online (Sandbox Code Playgroud)

注意上面是伪代码,有不同的方法可以覆盖


您的 XML 可能如下所示:

<PreferenceScreen
        xmlns:android="http://schemas.android.com/apk/res/android">

    <PreferenceCategory
            android:title="@string/inline_preferences">

        <com.example.myprefs.ListPreferenceCrypt
                android:key="listcrypt_preference"
                android:title="@string/title_listcrypt_preference"
                android:summary="@string/summary_listcrypt_preference" />

    </PreferenceCategory>

</PreferenceScreen>
Run Code Online (Sandbox Code Playgroud)

编辑

注意事项/反编译

当我更多地思考这一点时,我意识到其中一个警告是,在反编译 APK 时,这种方法并不是特别难以绕过。这确实给出了布局中重写类的完整类名(尽管可以通过不使用 XML 来避免这种情况)

但是,我认为这并不比子类安全性低得多SharedPreferences。这也很容易被反编译。最终,如果您想要更强的安全性,您应该考虑其他存储方法。也许是 OAuth 或 AccountManager,如您的链接帖子中所建议的。