Перейти к содержимому

Android studio shared preference как забрать значения

  • автор:

Зашифрованные предпочтения в Андроид

Добрый день. Меня зовут Дмитрий и я являюсь преподавателем базового курса «Android разработчик» в Otus. Сегодня я решил поделиться переводом статьи, которую считаю интересной и думаю, что она может быть полезной для многих читателей нашего блога.

Хранить данные в SharedPreferences очень быстро и удобно. Злоумышленникам также легко взглянуть на данные, хранящиеся в SharedPreferences …так что будьте осторожны с тем, что вы там поместили, и, возможно, придется задуматься о том, как хранить данные в зашифрованном формате.

Для небольших объемов данных, которые не оправдывают использование механизма БД, такого как SqlCipher, наши возможности были ограничены:

  • Собственные методы шифрования( если вы знаете, что делаете)
  • Готовые решения, такие как Secure-preferences, другие Secure-preferences, Armadillo и т.д.
  • Борьба с самыми странными проблемами жизненного цикла системы Android Keystore в каждой версии Android

Давайте рассмотрим пример того, как его использовать:

Пример EncryptedSharedPreferences

Минимальный SDK

На сегодняшний день 23 (Android 6.0)

minSdkVersion 23

Добавьте зависимости

implementation "androidx.security:security-crypto:1.0.0-alpha02"

Инициализировать / открыть

Просто создайте или извлеките мастер-ключ из хранилища ключей Android и используйте его для инициализации / открытия экземпляра EncryptedSharedPreferences:

// Шаг 1: Создать или получить мастер-ключ для шифрования / дешифрования val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC) // Шаг 2. Инициализируйте / создайте экземпляр EncryptedSharedPreferences val sharedPreferences = EncryptedSharedPreferences.create( "PreferencesFilename", masterKeyAlias, applicationContext, EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM )

Сохранить записи

Сохраните данные, как вы всегда делали с SharedPreferences:

// Шаг 3. Сохраните данные в EncryptedSharedPreferences sharedPreferences.edit() .putString("DATA", saveText.text.toString()) .apply()

Читать записи

Читайте данные, как вы всегда делали с SharedPreferences:

// Шаг 3: Считайте данные из EncryptedSharedPreferences val value = sharedPreferences.getString("DATA", "")

Действительно ли настройки зашифрованы?

Да, и действительно довольно хорошо зашифрованы.

Скажем, я поместил значение akaita в SharedPreferences . Вот как будет выглядеть файл:

  akaita 

Если я добавлю значение akaita в EncryptedSharedPreferences , я получу что-то совсем другое:

  12a901eb372af4775b09f5b51d20d49428931c5d8e0b17dd103d2169c1879b8b13958274d7e25d3cc052f301461495fd40b70806ae244f456726802460318bdf19dce444e7a60f20c903c5a57140ea8e90a19a1b48559961d145a50000d1c0e22ca918b02ea0cc34e433900f44c00e9c791ecb678f26d293c0226d6c2a9e25e610616ec34241b06410481427a850eeedf85ee4c725d5dbd715b5a8d0e017be9a568a9f960989271d14d2d0531a4408a5d0dae705123c0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e4165735369764b6579100118a5d0dae7052001 12880189e734bbbf9cfa3bc15b5e53ea8df03341269cf97112a60a1f6482732dd33248b3f821397fb04ef3372ff54336e9045a0b0c0fb7afdf475dbc98a1107d09de66afcc5ad063e5e5b59a7d616e14834e19769bc84de7e5c8716a811814a6cd7a6d72a1c64ce4317f2f482181c437b70f010219ca6407a98bac18f1101c02fd8e2c4a9009ad2a1ebbdc1a4408e9edbbce02123c0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e41657347636d4b6579100118e9edbbce022001 

Более того, зашифрованный файл будет меняться каждый раз, когда мы сохраняем, что затрудняет доступ к нему.

Большое предостережение: производительность

Существует значительная разница в производительности между SharedPreferences и EncryptedSharedPreferences.

Вы можете проверить сами, используя мой пример кода или просто скачав пример приложения из Play Store. Я сам провожу несколько тестов на реальном устройстве, получая следующие результаты:

EncryptedSharedPreferences в сравнении с SharedPreferences

График «EncryptedSharedPreferences в сравнении с SharedPreferences»

Заключение

EncryptedSharedPreferences является надежным и очень простым решением для Android 6.0 и выше.

Он имеет два больших плюса:

  1. нам не нужно ничего кодировать в нашем коде. Он просто использует Android Keystore для нас, избавляя себя от необходимости справляться с этим
  2. пользователю не нужно устанавливать экран блокировки. EncryptedSharedPreferences будет работать так же хорошо, без блокировки экрана

Это решение определенно останется. Я использую это в любом подходящем сценарии. Теперь я просто хочу сказать, что ребята из Android улучшат его производительность, так что нам можно беспокоиться еще меньше 🙂

Пример приложения

Просто, чтобы было проще протестировать и убедиться, что все хорошо связано, я создал и приложение для вас. Загрузите его или скомпилируйте и попробуйте!

Ставьте плюс, если считаете статью полезной, а на любые вопросы буду рад ответить в комментариях.

  • разработка под android
  • android
  • SharedPreferences
  • EncryptedSharedPreferences
  • Блог компании OTUS
  • Программирование
  • Разработка под Android

Не могу получить значение SharedPreferences в другой активити

Проблема в том, что bl всегда равен false . Перечитав литературу, заметил, что SharedPreferences работает только с одной активностью. Подскажите, как сохранить и получить значение правильно? P.S. Я сохраняю значение настройки, которое равно true или false (по умолчанию) в одном активити, а в другом должен получить данное значение, в зависимости от которого изменить поведение кнопки.

Отслеживать
36.8k 6 6 золотых знаков 48 48 серебряных знаков 125 125 бронзовых знаков
задан 3 авг 2016 в 11:38
1,093 13 13 серебряных знаков 26 26 бронзовых знаков
вы уверены, что ON_CAMERA у вас одинаковый и там и там?
3 авг 2016 в 11:40
@metalurgus, да
3 авг 2016 в 11:41

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Чтобы получить экземпляр класса SharedPreferences для получения доступа к настройкам в коде приложения используются три метода:

getPreferences() — внутри активности, чтобы обратиться к данным одной активности;
getSharedPreferences() — внутри активности, чтобы обратиться к данным на уровне приложения;
getDefaultSharedPreferences() — из объекта PreferencesManager , чтобы получить общедоступную настройку, предоставляемую Android.

Для доступа к настройкам из любого места приложения, вам нужно использовать второй или третий метод:

SharedPreferences sharedPreferences = getSharedPreferences(APP_PREFERENCES, Context.MODE_PRIVATE); 

SharedPreferences. Сохранение данных в постоянное хранилище Android

SharedPreferences – постоянное хранилище на платформе Android, используемое приложениями для хранения своих настроек, например. Это хранилище является относительно постоянным, пользователь может зайти в настройки приложения и очистить данные приложения, тем самым очистив все данные в хранилище.

Для работы с данными постоянного хранилища нам понадобится экземпляр класса SharedPreferences, который можно получить у любого объекта, унаследованного от класса android.content.Context (например, Activity или Service). У объектов этих классов (унаследованных от Context) есть метод getSharedPreferences, который принимает 2 параметра:

  • name – выбранный файл настроек. Если файл настроек с таким именем не существует, он будет создан при вызове метода edit() и фиксировании изменений с помощью метода commit().
  • mode – режим работы. Возможные значения:
    • MODE_PRIVATE – используется в большинстве случаев для приватного доступа к данным приложением-владельцем
    • MODE_WORLD_READABLE – только для чтения
    • MODE_WORLD_WRITEABLE – только записи
    • MODE_MULTI_PROCESS – несколько процессов совместно используют один файл SharedPreferences.

    ВНИМАНИЕ! Все модификаторы кроме MODE_PRIVATE в настоящий момент объявлены deprecated и не рекомендуются к использованию в целях безопасности. Если необходимо реализовать использование общих данных несколькими приложениями, это можно сделать через сервисы или контент-провайдеры. Подробнее можно почитать, например, здесь.

    Чтобы получить значение необходимой переменной, используйте следующие методы объекта SharedPreferences:

    • getBoolean(String key, boolean defValue),
    • getFloat(String key, float defValue),
    • getInt(String key, int defValue),
    • getLong(String key, long defValue),
    • getString(String key, String defValue),
    • getStringSet(String key, Set defValues).

    Второй параметр – значение, которое вернется в случае если значение по ключу key отсутствует в SharedPreferences. Также, методом getAll() можно получить все доступные значения.

    Чтобы записать значение переменной необходимо:

    1. получить объект SharedPreferences.Editor выполнив метод edit() объекта класса SharedPreferences
    2. записать значение с помощью методов:
      • putBoolean(String key, boolean value),
      • putFloat(String key, float value),
      • putInt(String key, int value),
      • putLong(String key, long value),
      • putString(String key, String value),
      • putStringSet(String key, Set values)
    3. выполнить метод commit()

    Также есть возможность удалить конкретное значение (remove(String key)) или все значения (clear())

    Приведенный ниже код демонстрирует запись переменной типа String в хранилище:

    SharedPreferences settings = context.getSharedPreferences(PERSISTANT_STORAGE_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = settings.edit(); editor.putString( "name", "John" ); editor.commit();

    – context – объект, унаследованный от android.content.Context.

    Представим простой класс для работы с постоянным хранилищем – PersistantStorage.

    Перед записью значений в хранилище или получением значений из хранилища, класс нужно проинициализировать, вызвав метод init() и передав ему объект, унаследованный от android.content.Context (например, Activity или Service).

    import android.content.Context; import android.content.SharedPreferences; public class PersistantStorage < public static final String STORAGE_NAME = "StorageName"; private static SharedPreferences settings = null; private static SharedPreferences.Editor editor = null; private static Context context = null; public static void init( Context cntxt )< context = cntxt; >private static void init() < settings = context.getSharedPreferences(STORAGE_NAME, Context.MODE_PRIVATE); editor = settings.edit(); >public static void addProperty( String name, String value ) < if( settings == null )< init(); >editor.putString( name, value ); editor.commit(); > public static String getProperty( String name ) < if( settings == null )< init(); >return settings.getString( name, null ); > >

    В этом классе реализована работа только со строковыми данными. Вы легко можете самостоятельно его расширить, используя стандартные методы PersistantStorage или написав собственные сериализаторы для сложных объектов.

    ВНИМАНИЕ! Метод commit() устарел и объявлен deprecated. Вместо него следует использовать метод apply() – он появился в API 9 и работает в асинхронном режиме, что является более предпочтительным вариантом.

    Android studio shared preference как забрать значения

    Нередко приложению требуется сохранять небольшие кусочки данных для дальнейшего использования, например, данные о пользователе, настройки конфигурации и т.д. Для этого в Android существует концепция Preferences или настройки. Настройки представляют собой группу пар ключ-значение, которые используются приложением.

    В качестве значений могут выступать данные следующих типов: Boolean, Float, Integer, Long, String, набор строк.

    Настройки общими для всех activity в приложении, но также могут быть и настройки непосредственно для отдельных activity

    Настройки хранятся в xml-файлах в незашифрованном виде в локальном хранилище. Они невидимы, поэтому для простого пользователя недоступны.

    При работе с настройками следует учитывать следующие моменты. Так как они хранятся в незашифрованном виде, то не рекомендуется сохранять в них чувствительные данные типа пароля или номеров кредитных карт. Кроме того, они представляют данные, ассоцииованные с приложением, и через панель управления приложением в Настройках ОС пользователь может удалить эти данные.

    Общие настройки

    Для работы с разделяемыми настройками в классе Activity (точнее в его базовом классе Context) имеется метод getSharedPreferences() :

    import android.content.SharedPreferences; //. SharedPreferences settings = getSharedPreferences("PreferencesName", MODE_PRIVATE);

    Первый параметр метода указывает на название настроек. В данном случае название — «PreferencesName». Если настроек с подобным названием нет, то они создаются при вызове данного метода. Второй параметр указывает на режим доступа. В данном случае режим описан константой MODE_PRIVATE

    Класс android.content.SharedPreferences предоставляет ряд методов для управления настройками:

    • contains(String key) : возвращает true, если в настройках сохранено значение с ключом key
    • getAll() : возвращает все сохраненные в настройках значения
    • getBoolean (String key, boolean defValue) : возвращает из настроек значение типа Boolean, которое имеет ключ key. Если элемента с таким ключом не окажется, то возвращается значение defValue, передаваемое вторым параметром
    • getFloat(String key, float defValue) : возвращает значение типа float с ключом key. Если элемента с таким ключом не окажется, то возвращается значение defValue
    • getInt(String key, int defValue) : возвращает значение типа int с ключом key
    • getLong(String key, long defValue) : возвращает значение типа long с ключом key
    • getString(String key, String defValue) : возвращает строковое значение с ключом key
    • getStringSet(String key, Set defValues) : возвращает массив строк с ключом key
    • edit() : возвращает объект SharedPreferences.Editor , который используется для редактирования настроек

    Для управления настройками используется объект класса SharedPreferences.Editor , возвращаемый метод edit() . Он определяет следующие методы:

    • clear() : удаляет все настройки
    • remove(String key) : удаляет из настроек значение с ключом key
    • putBoolean(String key, boolean value) : добавляет в настройки значение типа boolean с ключом key
    • putFloat(String key, float value) : добавляет в настройки значение типа float с ключом key
    • putInt(String key, int value) : добавляет в настройки значение int с ключом key
    • putLong(String key, long value) : добавляет в настройки значение типа long с ключом key
    • putString(String key, String value) : добавляет в настройки строку с ключом key
    • putStringSet(String key, Set values) : добавляет в настройки строковый массив
    • commit() : подтверждает все изменения в настройках
    • apply() : также, как и метод commit(), подтверждает все изменения в настройках, однако измененный объект SharedPreferences вначале сохраняется во временной памяти, и лишь затем в результате асинхронной операции записывается на мобильное устройство

    Рассмотрим пример сохранения и получения настроек в приложении. Определим в файле activity_main.xml следующий пользовательский интерфейс:

    На экране будут две кнопки — для сохранения и для вывода ранее сохраненного значения, а также поле для ввода и текстовое поля ля вывода сохраненной настройки.

    Определим методы обработчики кнопок в классе MainActivity :

    package com.example.settingsapp; import androidx.appcompat.app.AppCompatActivity; import android.content.SharedPreferences; import android.os.Bundle; import android.view.View; import android.widget.EditText; import android.widget.TextView; public class MainActivity extends AppCompatActivity < private static final String PREFS_FILE = "Account"; private static final String PREF_NAME = "Name"; SharedPreferences settings; @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); settings = getSharedPreferences(PREFS_FILE, MODE_PRIVATE); >public void saveName(View view) < // получаем введенное имя EditText nameBox = findViewById(R.id.nameBox); String name = nameBox.getText().toString(); // сохраняем его в настройках SharedPreferences.Editor prefEditor = settings.edit(); prefEditor.putString(PREF_NAME, name); prefEditor.apply(); >public void getName(View view) < // получаем сохраненное имя TextView nameView = findViewById(R.id.nameView); String name = settings.getString(PREF_NAME,"не определено"); nameView.setText(name); >>

    При отсутствии настроек при попытке их получить, приложение выведет значение по умолчанию:

    Получение настроек SharedPreferences preferences в Android и Java

    Теперь сохраним и выведем заново сохраненное значение:

    Сохранение настроек SharedPreferences preferences в Android и Java

    Нередко возникает задача автоматически сохранять вводимые данные при выходе пользователя из activity. Для этого мы можем переопределить метод onPause:

    package com.example.settingsapp; import androidx.appcompat.app.AppCompatActivity; import android.content.SharedPreferences; import android.os.Bundle; import android.view.View; import android.widget.EditText; public class MainActivity extends AppCompatActivity < private static final String PREFS_FILE = "Account"; private static final String PREF_NAME = "Name"; EditText nameBox; SharedPreferences settings; SharedPreferences.Editor prefEditor; @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); nameBox = findViewById(R.id.nameBox); settings = getSharedPreferences(PREFS_FILE, MODE_PRIVATE); // получаем настройки String name = settings.getString(PREF_NAME,""); nameBox.setText(name); >@Override protected void onPause() < super.onPause(); String name = nameBox.getText().toString(); // сохраняем в настройках prefEditor = settings.edit(); prefEditor.putString(PREF_NAME, name); prefEditor.apply(); >public void saveName(View view) < >public void getName(View view) < >>

    Приватные настройки

    Кроме общих настроек каждая activity может использовать приватные, к которым доступ из других activity будет невозможен. Для получения настроек уровня activity используется метод getPreferences(MODE_PRIVATE) :

    import android.content.SharedPreferences; //. SharedPreferences settings = getPreferences(MODE_PRIVATE);

    То есть в отличие от общих настроек здесь не используется название группы настроек в качестве первого параметра, как в методе getSharedPreferences() . Однако вся остальная работа по добавлению, получению и изменению настроек будет аналогична работает с общими настройками.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *