java - অ্যান্ড্রয়েড অ্যাপ্লিকেশন ব্যবহারকারী সেটিংস সংরক্ষণ করার সবচেয়ে উপযুক্ত উপায় কি




android encryption (10)

আমি ব্যবহারকারীর নাম / পাসওয়ার্ড ব্যবহার করে সার্ভারের সাথে সংযুক্ত একটি অ্যাপ্লিকেশন তৈরি করছি এবং আমি "পাসওয়ার্ড সংরক্ষণ করুন" বিকল্পটি সক্ষম করতে চাই যাতে অ্যাপ্লিকেশনটি শুরু হওয়ার সময় ব্যবহারকারীকে পাসওয়ার্ড টাইপ করতে হবে না।

আমি ভাগ করা পছন্দগুলি দিয়ে এটি করার চেষ্টা করছিলাম তবে এটি সর্বোত্তম সমাধান কিনা তা আমি নিশ্চিত নই।

আমি অ্যান্ড্রয়েড অ্যাপ্লিকেশন ব্যবহারকারী মান / সেটিংস সংরক্ষণ কিভাবে কোন পরামর্শ কৃতজ্ঞ হবে।


Android কার্যকলাপে একটিও পছন্দসই সঞ্চয় করার সবচেয়ে সরল উপায় হল এটির মতো কিছু করা:

Editor e = this.getPreferences(Context.MODE_PRIVATE).edit();
e.putString("password", mPassword);
e.commit();

আপনি যদি এর নিরাপত্তা সম্পর্কে চিন্তিত হন তবে আপনি এটি সংরক্ষণ করার আগে সর্বদা পাসওয়ার্ড এনক্রিপ্ট করতে পারেন।


অ্যান্ড্রয়েডে সাধারণভাবে পাসওয়ার্ড সুরক্ষিত করার জন্য আমি আমার টুপিটি রিংতে নিক্ষেপ করব। Android এ, ডিভাইস বাইনারিটি আপোস করা উচিত - এটি সরাসরি ব্যবহারকারীর নিয়ন্ত্রণে থাকা কোন শেষ অ্যাপ্লিকেশনের জন্য একই। ধারণাক্রমে, একটি হ্যাকার বাইনারিটিতে প্রয়োজনীয় অ্যাক্সেসটি ব্যবহার করতে এবং এটি আপনার এনক্রিপ্ট করা পাসওয়ার্ডগুলি এবং রুপান্তরিত করতে পারে।

নিরাপত্তাহীনতা আপনার জন্য একটি বড় উদ্বেগ থাকলে আমি সেখানে দুটি প্রস্তাব দিতে চাই:

1) প্রকৃত পাসওয়ার্ড সংরক্ষণ করবেন না। একটি প্রদত্ত অ্যাক্সেস টোকেন সংরক্ষণ করুন এবং সেশন সার্ভার-পার্শ্ব প্রমাণীকরণ অ্যাক্সেস টোকেন এবং ফোনটির স্বাক্ষরটি ব্যবহার করুন। এটির সুবিধাটি হল যে আপনি টোকেনটি সীমিত সময়ের জন্য তৈরি করতে পারেন, আপনি মূল পাসওয়ার্ডটি আপোস করছেন না এবং আপনার কাছে একটি ভাল স্বাক্ষর রয়েছে যা আপনি পরে ট্র্যাফিকের সাথে সম্পর্কযুক্ত করতে ব্যবহার করতে পারেন (উদাহরণস্বরূপ অনুপ্রবেশের প্রচেষ্টাগুলির জন্য চেক করুন এবং অকার্যকর করুন টোকেন এটি নিরর্থক রেন্ডারিং)।

2) 2 ফ্যাক্টর প্রমাণীকরণ ব্যবহার করুন। এটি আরো বিরক্তিকর এবং নিরোধক হতে পারে কিন্তু কিছু সম্মতি পরিস্থিতিতে অপরিহার্য।


আপনি পাসওয়ার্ড সংরক্ষণ করতে sqlite, নিরাপত্তা apit ব্যবহার করতে হবে। এখানে সেরা উদাহরণ, যা পাসওয়ার্ড সংরক্ষণ করে, - passwordwords। এখানে উৎস এবং ব্যাখ্যা জন্য লিঙ্ক - http://code.google.com/p/android-passwordsafe/


আমি Reto এবং fiXedd সঙ্গে একমত। উদ্দেশ্যমূলকভাবে এটি ভাগ করে নেওয়া অনেক বেশি সময় এবং প্রচেষ্টাকে ভাগ করে নেওয়া ভাগ্যগুলিতে এনক্রিপ্টিং পাসওয়ার্ডগুলিতে বিনিয়োগ করে না, যেহেতু যে কোন আক্রমণকারীর কাছে আপনার পছন্দসই ফাইলটিতে অ্যাক্সেস রয়েছে সেটি সম্ভবত আপনার অ্যাপ্লিকেশানের বাইনারি অ্যাক্সেসেরও সম্ভাবনা রয়েছে এবং সেইজন্য কীগুলি এনক্রিপ্ট করার কীগুলি পাসওয়ার্ড।

যাইহোক, বলা হচ্ছে, এমন একটি মোবাইল অ্যাপ্লিকেশনের শনাক্তকরণে প্রচারিত একটি প্রচার উদ্যোগ বলে মনে হচ্ছে যা ভাগ করে নেওয়া ভাগ্যগুলিতে তাদের পাসওয়ার্ডগুলি সংরক্ষণ করে এবং সেই অ্যাপ্লিকেশনের প্রতিক্রিয়াশীল আলোকে আলোকিত করে। কিছু উদাহরণের জন্য http://blogs.wsj.com/digits/2011/06/08/some-top-apps-put-data-at-risk/ এবং http://viaforensics.com/appwatchdog দেখুন।

সাধারণভাবে নিরাপত্তার জন্য আমাদের আরো বেশি মনোযোগ দেওয়ার প্রয়োজন হলেও, আমি তর্কবিতর্ক করব যে এই এক বিশেষ সমস্যাটির উপর এই ধরণের মনোযোগ প্রকৃতপক্ষে আমাদের সামগ্রিক নিরাপত্তা বৃদ্ধি করে না। যাইহোক, উপলব্ধিগুলি হচ্ছে যেহেতু, এখানে আপনার ভাগ করা ডেটা এনক্রিপ্ট করার একটি সমাধান।

শুধু আপনার নিজের ভাগ করা পরিচিতিগুলির বস্তুটি এটিকে মোড়ানো করুন এবং যে কোনও ডেটা আপনি পড়তে / লিখবেন সেটি স্বয়ংক্রিয়ভাবে এনক্রিপ্ট করা এবং ডিক্রিপ্ট করা হবে। যেমন।

final SharedPreferences prefs = new ObscuredSharedPreferences( 
    this, this.getSharedPreferences(MY_PREFS_FILE_NAME, Context.MODE_PRIVATE) );

// eg.    
prefs.edit().putString("foo","bar").commit();
prefs.getString("foo", null);

এখানে ক্লাসের জন্য কোড রয়েছে:

/**
 * Warning, this gives a false sense of security.  If an attacker has enough access to
 * acquire your password store, then he almost certainly has enough access to acquire your
 * source binary and figure out your encryption key.  However, it will prevent casual
 * investigators from acquiring passwords, and thereby may prevent undesired negative
 * publicity.
 */
public class ObscuredSharedPreferences implements SharedPreferences {
    protected static final String UTF8 = "utf-8";
    private static final char[] SEKRIT = ... ; // INSERT A RANDOM PASSWORD HERE.
                                               // Don't use anything you wouldn't want to
                                               // get out there if someone decompiled
                                               // your app.


    protected SharedPreferences delegate;
    protected Context context;

    public ObscuredSharedPreferences(Context context, SharedPreferences delegate) {
        this.delegate = delegate;
        this.context = context;
    }

    public class Editor implements SharedPreferences.Editor {
        protected SharedPreferences.Editor delegate;

        public Editor() {
            this.delegate = ObscuredSharedPreferences.this.delegate.edit();                    
        }

        @Override
        public Editor putBoolean(String key, boolean value) {
            delegate.putString(key, encrypt(Boolean.toString(value)));
            return this;
        }

        @Override
        public Editor putFloat(String key, float value) {
            delegate.putString(key, encrypt(Float.toString(value)));
            return this;
        }

        @Override
        public Editor putInt(String key, int value) {
            delegate.putString(key, encrypt(Integer.toString(value)));
            return this;
        }

        @Override
        public Editor putLong(String key, long value) {
            delegate.putString(key, encrypt(Long.toString(value)));
            return this;
        }

        @Override
        public Editor putString(String key, String value) {
            delegate.putString(key, encrypt(value));
            return this;
        }

        @Override
        public void apply() {
            delegate.apply();
        }

        @Override
        public Editor clear() {
            delegate.clear();
            return this;
        }

        @Override
        public boolean commit() {
            return delegate.commit();
        }

        @Override
        public Editor remove(String s) {
            delegate.remove(s);
            return this;
        }
    }

    public Editor edit() {
        return new Editor();
    }


    @Override
    public Map<String, ?> getAll() {
        throw new UnsupportedOperationException(); // left as an exercise to the reader
    }

    @Override
    public boolean getBoolean(String key, boolean defValue) {
        final String v = delegate.getString(key, null);
        return v!=null ? Boolean.parseBoolean(decrypt(v)) : defValue;
    }

    @Override
    public float getFloat(String key, float defValue) {
        final String v = delegate.getString(key, null);
        return v!=null ? Float.parseFloat(decrypt(v)) : defValue;
    }

    @Override
    public int getInt(String key, int defValue) {
        final String v = delegate.getString(key, null);
        return v!=null ? Integer.parseInt(decrypt(v)) : defValue;
    }

    @Override
    public long getLong(String key, long defValue) {
        final String v = delegate.getString(key, null);
        return v!=null ? Long.parseLong(decrypt(v)) : defValue;
    }

    @Override
    public String getString(String key, String defValue) {
        final String v = delegate.getString(key, null);
        return v != null ? decrypt(v) : defValue;
    }

    @Override
    public boolean contains(String s) {
        return delegate.contains(s);
    }

    @Override
    public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener onSharedPreferenceChangeListener) {
        delegate.registerOnSharedPreferenceChangeListener(onSharedPreferenceChangeListener);
    }

    @Override
    public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener onSharedPreferenceChangeListener) {
        delegate.unregisterOnSharedPreferenceChangeListener(onSharedPreferenceChangeListener);
    }




    protected String encrypt( String value ) {

        try {
            final byte[] bytes = value!=null ? value.getBytes(UTF8) : new byte[0];
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
            SecretKey key = keyFactory.generateSecret(new PBEKeySpec(SEKRIT));
            Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
            pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(Settings.Secure.getString(context.getContentResolver(),Settings.Secure.ANDROID_ID).getBytes(UTF8), 20));
            return new String(Base64.encode(pbeCipher.doFinal(bytes), Base64.NO_WRAP),UTF8);

        } catch( Exception e ) {
            throw new RuntimeException(e);
        }

    }

    protected String decrypt(String value){
        try {
            final byte[] bytes = value!=null ? Base64.decode(value,Base64.DEFAULT) : new byte[0];
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
            SecretKey key = keyFactory.generateSecret(new PBEKeySpec(SEKRIT));
            Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
            pbeCipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(Settings.Secure.getString(context.getContentResolver(),Settings.Secure.ANDROID_ID).getBytes(UTF8), 20));
            return new String(pbeCipher.doFinal(bytes),UTF8);

        } catch( Exception e) {
            throw new RuntimeException(e);
        }
    }

}

আমি জানি এটি একটি সামান্য বিদ্রূপাত্মকতা, তবে আপনাকে Android AccountManager ব্যবহার করতে হবে। এটা এই দৃশ্যকল্প জন্য উদ্দেশ্য-নির্মিত। এটি কিছুটা কষ্টকর তবে সিম কার্ড পরিবর্তিত হলে স্থানীয় শংসাপত্রগুলিকে অবৈধ করে তুললে এটির মধ্যে একটি হল, যাতে কেউ আপনার ফোনটি স্যুইপ করে এবং এটিতে একটি নতুন সিম ফেলে দেয় তবে আপনার শংসাপত্রগুলির সাথে আপোস করা হবে না।

এটি ব্যবহারকারীকে ডিভাইসে থাকা যেকোনো অ্যাকাউন্টের জন্য সঞ্চিত ক্রেডেনশিয়ালগুলি অ্যাক্সেস করার (এবং সম্ভাব্যরূপে মুছে ফেলার) দ্রুত এবং সহজ উপায় দেয়, এক জায়গায়।

SampleSyncAdapter একটি উদাহরণ যা সংরক্ষিত অ্যাকাউন্ট শংসাপত্র ব্যবহার করে।


এই উত্তর মার্ক দ্বারা একটি প্রস্তাবিত পদ্ধতির উপর ভিত্তি করে। EditTextPreference ক্লাসের একটি কাস্টম সংস্করণ তৈরি করা হয়েছে যা ভিউতে দেখা প্লেইন পাঠ্য এবং পছন্দসই সঞ্চয়স্থানে সংরক্ষিত পাসওয়ার্ডের এনক্রিপ্ট করা সংস্করণের মধ্যে পিছনে রূপান্তর করে।

এই থ্রেডে উত্তর দিয়েছেন এমন বেশীরভাগের দ্বারা নির্দেশিত হয়েছে, এটি একটি খুব সুরক্ষিত কৌশল নয়, যদিও সুরক্ষা ডিগ্রী আংশিকভাবে ব্যবহৃত এনক্রিপশন / ডিক্রিপশন কোডের উপর নির্ভর করে। কিন্তু এটি মোটামুটি সহজ এবং সুবিধাজনক, এবং বেশিরভাগ নৈমিত্তিক snooping নষ্ট করবে।

এখানে কাস্টম EditTextPreference ক্লাসের কোডটি রয়েছে:

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);
    }
}

এটি কিভাবে এটি ব্যবহার করা যায় তা দেখায় - এটি "আইটেম" ফাইল যা পছন্দসই প্রদর্শন চালায়। দ্রষ্টব্য এটি তিনটি সাধারণ EditTextPreference মতামত এবং কাস্টম EditPasswordPreference মতামত এক অন্তর্ভুক্ত রয়েছে।

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

    <EditTextPreference
        android:key="@string/useraccountname_key"
        android:title="@string/useraccountname_title"
        android:summary="@string/useraccountname_summary"
        android:defaultValue="@string/useraccountname_default"
        />

    <com.Merlinia.OutBack_Client.EditPasswordPreference
        android:key="@string/useraccountpassword_key"
        android:title="@string/useraccountpassword_title"
        android:summary="@string/useraccountpassword_summary"
        android:defaultValue="@string/useraccountpassword_default"
        />

    <EditTextPreference
        android:key="@string/outbackserverip_key"
        android:title="@string/outbackserverip_title"
        android:summary="@string/outbackserverip_summary"
        android:defaultValue="@string/outbackserverip_default"
        />

    <EditTextPreference
        android:key="@string/outbackserverport_key"
        android:title="@string/outbackserverport_title"
        android:summary="@string/outbackserverport_summary"
        android:defaultValue="@string/outbackserverport_default"
        />

</PreferenceScreen>

প্রকৃত এনক্রিপশন / ডিক্রিপশন হিসাবে, যা পাঠকের জন্য ব্যায়াম হিসাবে বামে। আমি বর্তমানে এই নিবন্ধটির উপর ভিত্তি করে কিছু কোড ব্যবহার করছি http://zenu.wordpress.com/2011/09/21/aes-128bit-cross-platform-java-and-c-encryption-compatibility/ , যদিও বিভিন্ন মানগুলির সাথে কী এবং প্রাথমিক ভেক্টর জন্য।


ঠিক আছে; উত্তরটি কিছুটা মিশ্রিত হয়ে গেছে, কিন্তু এখানে কয়েকটি সাধারণ উত্তর রয়েছে। আমি পাগল মত এই গবেষণা এবং এটি একটি ভাল উত্তর নির্মাণ কঠিন ছিল

  1. MODE_PRIVATE পদ্ধতিটিকে সাধারণত নিরাপদ বলে মনে করা হয়, যদি আপনি অনুমান করেন যে ব্যবহারকারীটি ডিভাইসটিকে রুট করে না। আপনার তথ্য ফাইল সিস্টেমের একটি অংশে প্লেইন পাঠ্যতে সংরক্ষণ করা হয় যা শুধুমাত্র মূল প্রোগ্রাম দ্বারা অ্যাক্সেস করা যেতে পারে। এই মেকিং একটি rooted ডিভাইসে অন্য অ্যাপ্লিকেশন দিয়ে পাসওয়ার্ড grabbing সহজ। তারপর আবার, আপনি রুট ডিভাইস সমর্থন করতে চান?

  2. AES এখনও আপনি করতে পারেন সেরা এনক্রিপশন। এটি পোস্ট করার পরে এটির কিছুক্ষণ পরে যদি আপনি একটি নতুন বাস্তবায়ন শুরু করেন তবে এটি সন্ধান করুন। এর সাথে সবচেয়ে বড় সমস্যা "এনক্রিপশন কী কী করতে হবে?"

সুতরাং, এখন আমরা কি "কী কী করবেন?" অংশ। এটি কঠিন অংশ। কী পেয়ে খারাপ যে খারাপ হতে সক্রিয়। আপনি কিছু পাসওয়ার্ড গ্রহণ এবং এটি একটি চমত্কার নিরাপদ কী করতে একটি কী derivation ফাংশন ব্যবহার করতে পারেন। আপনি "PKFDF2 এর সাথে কত পাস করবেন?" এর মতো সমস্যাগুলি পান তবে এটি অন্য একটি বিষয়

  1. আদর্শভাবে, আপনি ডিভাইস বন্ধ AES কী সংরক্ষণ করুন। সার্ভার থেকে নিরাপদে, নির্ভরযোগ্যভাবে এবং সুরক্ষিতভাবে কীটি পুনরুদ্ধার করার জন্য আপনাকে একটি ভাল উপায় খুঁজে বের করতে হবে

  2. আপনার কোনও ধরণের লগইন ক্রম রয়েছে (এমনকি দূরবর্তী অ্যাক্সেসের জন্য আপনি যে আসল লগইন ক্রমটি করেন)। আপনি একই পাসওয়ার্ডে আপনার কী জেনারেটরের দুটি রান করতে পারেন। কিভাবে এটি কাজ করে আপনি একটি নতুন লবণ এবং একটি নতুন নিরাপদ প্রাথমিক ভেক্টর দিয়ে দুবার আবির্ভূত হয়। আপনি ডিভাইসে সেগুলি তৈরি করা পাসওয়ার্ডগুলির মধ্যে একটি সংরক্ষণ করেন এবং আপনি দ্বিতীয় পাসওয়ার্ডটি AES কী হিসাবে ব্যবহার করেন।

যখন আপনি লগ ইন করেন, তখন আপনি স্থানীয় লগইন কীটি পুনঃ-পুনরুদ্ধার করেন এবং এটি সঞ্চিত কীতে তুলনা করেন। একবার এটি সম্পন্ন হলে, আপনি AES এর জন্য কী অর্জন # 2 ব্যবহার করেন।

  1. "সাধারণত নিরাপদ" পদ্ধতি ব্যবহার করে, আপনি AES ব্যবহার করে ডেটা এনক্রিপ্ট করেন এবং MODE_PRIVATE এ কীটি সংরক্ষণ করেন। এটি একটি সাম্প্রতিক-এন্ড্রয়েড ব্লগ পোস্ট দ্বারা প্রস্তাবিত। অবিশ্বাস্যভাবে নিরাপদ নয়, তবে সহজ পাঠ্যক্রমে কিছু লোকের জন্য ভালো উপায়

আপনি এই অনেক বৈচিত্র্য করতে পারেন। উদাহরণস্বরূপ, একটি পূর্ণ লগইন ক্রম পরিবর্তে, আপনি একটি দ্রুত PIN (উদ্ভূত) করতে পারেন। দ্রুত PIN সম্পূর্ণ লগইন ক্রম হিসাবে নিরাপদ নাও হতে পারে তবে এটি প্লেইন পাঠের চেয়ে অনেক বেশি নিরাপদ


প্রথমত আমি মনে করি ব্যবহারকারীর ডেটা ফোনে সংরক্ষণ করা উচিত না এবং ফোনটিতে কোথাও ডেটা সঞ্চয় করতে হবে তা এপ্লিকেশানগুলির ব্যক্তিগত তথ্যতে এনক্রিপ্ট করা উচিত। ব্যবহারকারীদের শংসাপত্রের নিরাপত্তা আবেদন অগ্রাধিকার হওয়া উচিত।

সংবেদনশীল তথ্য নিরাপদে বা সব সময়ে সংরক্ষণ করা উচিত। একটি হারিয়ে যাওয়া ডিভাইস বা ম্যালওয়ার সংক্রমণের ঘটনায়, নিরাপদভাবে সংরক্ষিত তথ্যটি আপোস করা যেতে পারে।


রিচার্ড দ্বারা সরবরাহিত স্নিপেট ব্যবহার করে, আপনি এটি সংরক্ষণ করার আগে পাসওয়ার্ড এনক্রিপ্ট করতে পারেন। পছন্দসই API যদিও মানটি আটকে দেওয়ার এবং এটি এনক্রিপ্ট করার একটি সহজ উপায় সরবরাহ করে না - আপনি এটি অনপ্রেফার্জ চেঞ্জ শ্রেনীর মাধ্যমে সংরক্ষণ করা বন্ধ করে দিতে পারেন এবং আপনি তাত্ত্বিকভাবে পছন্দসই পরিবর্তনটি পরিবর্তন করতে পারেন, তবে এটি একটি অবিচ্ছিন্ন লুপ হিসাবে পরিনত হয়।

আমি পূর্বে এই কাজ সম্পন্ন করার জন্য একটি "লুকানো" পছন্দ যোগ করার প্রস্তাব ছিল। এটা অবশ্যই সবচেয়ে ভাল উপায় নয়। আমি আরো দুটি কার্যকর বিকল্প উপস্থাপন করতে যাচ্ছি যা আমি আরও কার্যকর বলে মনে করি।

প্রথমে, সর্বাধিক, একটি পছন্দসই চ্যানেললিস্টারের মধ্যে, আপনি প্রবেশ করা মানটি ধরে নিতে পারেন, এটিকে এনক্রিপ্ট করতে পারেন এবং তারপরে বিকল্প বিকল্পের ফাইলে সংরক্ষণ করতে পারেন:

  public boolean onPreferenceChange(Preference preference, Object newValue) {
      // get our "secure" shared preferences file.
      SharedPreferences secure = context.getSharedPreferences(
         "SECURE",
         Context.MODE_PRIVATE
      );
      String encryptedText = null;
      // encrypt and set the preference.
      try {
         encryptedText = SimpleCrypto.encrypt(Preferences.SEED,(String)newValue);

         Editor editor = secure.getEditor();
         editor.putString("encryptedPassword",encryptedText);
         editor.commit();
      }
      catch (Exception e) {
         e.printStackTrace();
      }
      // always return false.
      return false; 
   }

দ্বিতীয় উপায়, এবং যেভাবে আমি এখন পছন্দ করি, সেটি আপনার নিজস্ব পছন্দসই পছন্দ তৈরি করা, সম্পাদনযোগ্য এক্সটেনশান প্রসারিত করা, @ setText() এবং getText() পদ্ধতিগুলি ওভাররাইড করা, যাতে setText() পাসওয়ার্ডটি এনক্রিপ্ট করে এবং getText() ফেরত দেয় খালি.


এই প্রশ্ন শিরোনামের উপর ভিত্তি করে এখানে পৌঁছানোর জন্য এটি একটি সম্পূরক উত্তর (যেমন আমি করেছি) এবং সংরক্ষণের পাসওয়ার্ড সম্পর্কিত নিরাপত্তা সমস্যাগুলির সাথে মোকাবিলা করতে হবে না।

শেয়ার্ড পছন্দ কিভাবে ব্যবহার করবেন

ব্যবহারকারীর সেটিংস সাধারণত কী-মান জুড়ি দিয়ে ভাগ করা SharedPreferences ব্যবহার করে Android এ স্থানীয়ভাবে সংরক্ষিত হয়। আপনি সংরক্ষণ মান বা সংরক্ষণ মান String কী ব্যবহার করুন।

ভাগ করা পছন্দ লিখুন

String key = "myInt";
int valueToSave = 10;

SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt(key, valueToSave).commit();

অবিলম্বে পরিবর্তে পটভূমি সংরক্ষণ apply() পরিবর্তে apply() ব্যবহার করুন।

ভাগ করা পছন্দ থেকে পড়ুন

String key = "myInt";
int defaultValue = 0;

SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
int savedValue = sharedPref.getInt(key, defaultValue);

কী পাওয়া না গেলে ডিফল্ট মান ব্যবহার করা হয়।

নোট

  • আমি উপরের মত বহুবিধ স্থানে একটি স্থানীয় কী স্ট্রিং ব্যবহার করার পরিবর্তে, একক অবস্থানে ধ্রুবক ব্যবহার করা ভাল। আপনি আপনার সেটিং কার্যকলাপের শীর্ষে এটির মতো কিছু ব্যবহার করতে পারেন:

    final static String PREF_MY_INT_KEY = "myInt";
  • আমি আমার উদাহরণে একটি int ব্যবহার করেছি, তবে আপনি putString() , putBoolean() , getString() , getBoolean() , ইত্যাদি ব্যবহার করতে পারেন।

  • আরো বিস্তারিত জানার জন্য documentation দেখুন।
  • ভাগ করা পরিচিতি পেতে একাধিক উপায় আছে। কি সন্ধান করা উচিত জন্য এই উত্তর দেখুন।




credentials