What is the most appropriate way to store user settings in Android application

后端 未结 14 2285
隐瞒了意图╮
隐瞒了意图╮ 2020-11-22 05:38

I am creating an application which connects to the server using username/password and I would like to enable the option \"Save password\" so the user wouldn\'t have to type

14条回答
  •  挽巷
    挽巷 (楼主)
    2020-11-22 06:25

    This answer is based on a suggested approach by Mark. A custom version of the EditTextPreference class is created which converts back and forth between the plain text seen in the view and an encrypted version of the password stored in the preferences storage.

    As has been pointed out by most who have answered on this thread, this is not a very secure technique, although the degree of security depends partly on the encryption/decryption code used. But it's fairly simple and convenient, and will thwart most casual snooping.

    Here is the code for the custom EditTextPreference class:

    package com.Merlinia.OutBack_Client;
    
    import android.content.Context;
    import android.preference.EditTextPreference;
    import android.util.AttributeSet;
    import android.util.Base64;
    
    import com.Merlinia.MEncryption_Main.MEncryptionUserPassword;
    
    
    /**
     * This class extends the EditTextPreference view, providing encryption and decryption services for
     * OutBack user passwords. The passwords in the preferences store are first encrypted using the
     * MEncryption classes and then converted to string using Base64 since the preferences store can not
     * store byte arrays.
     *
     * This is largely copied from this article, except for the encryption/decryption parts:
     * https://groups.google.com/forum/#!topic/android-developers/pMYNEVXMa6M
     */
    public class EditPasswordPreference  extends EditTextPreference {
    
        // Constructor - needed despite what compiler says, otherwise app crashes
        public EditPasswordPreference(Context context) {
            super(context);
        }
    
    
        // Constructor - needed despite what compiler says, otherwise app crashes
        public EditPasswordPreference(Context context, AttributeSet attributeSet) {
            super(context, attributeSet);
        }
    
    
        // Constructor - needed despite what compiler says, otherwise app crashes
        public EditPasswordPreference(Context context, AttributeSet attributeSet, int defaultStyle) {
            super(context, attributeSet, defaultStyle);
        }
    
    
        /**
         * Override the method that gets a preference from the preferences storage, for display by the
         * EditText view. This gets the base64 password, converts it to a byte array, and then decrypts
         * it so it can be displayed in plain text.
         * @return  OutBack user password in plain text
         */
        @Override
        public String getText() {
            String decryptedPassword;
    
            try {
                decryptedPassword = MEncryptionUserPassword.aesDecrypt(
                         Base64.decode(getSharedPreferences().getString(getKey(), ""), Base64.DEFAULT));
            } catch (Exception e) {
                e.printStackTrace();
                decryptedPassword = "";
            }
    
            return decryptedPassword;
        }
    
    
        /**
         * Override the method that gets a text string from the EditText view and stores the value in
         * the preferences storage. This encrypts the password into a byte array and then encodes that
         * in base64 format.
         * @param passwordText  OutBack user password in plain text
         */
        @Override
        public void setText(String passwordText) {
            byte[] encryptedPassword;
    
            try {
                encryptedPassword = MEncryptionUserPassword.aesEncrypt(passwordText);
            } catch (Exception e) {
                e.printStackTrace();
                encryptedPassword = new byte[0];
            }
    
            getSharedPreferences().edit().putString(getKey(),
                                              Base64.encodeToString(encryptedPassword, Base64.DEFAULT))
                    .commit();
        }
    
    
        @Override
        protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
            if (restoreValue)
                getEditText().setText(getText());
            else
                super.onSetInitialValue(restoreValue, defaultValue);
        }
    }
    

    This shows how it can be used - this is the "items" file that drives the preferences display. Note it contains three ordinary EditTextPreference views and one of the custom EditPasswordPreference views.

    
    
        
    
        
    
        
    
        
    
    
    

    As for the actual encryption/decryption, that is left as an exercise for the reader. I'm currently using some code based on this article http://zenu.wordpress.com/2011/09/21/aes-128bit-cross-platform-java-and-c-encryption-compatibility/, although with different values for the key and the initialization vector.

提交回复
热议问题