Как достучаться к SharedPreferences из службы?

SQLite, Preferences, файлы, SD, Content Provider, XML, JSON
Ответить
Tamachi
Сообщения: 203
Зарегистрирован: 17 апр 2013, 00:08

Как достучаться к SharedPreferences из службы?

Сообщение Tamachi » 09 май 2013, 10:45

[syntax=java][/syntax]Вот так выглядит класс для работы с настройками

public class SettingsController {
static void setSomething(Context context, Boolean value) {
SharedPreferences prefs = context.getSharedPreferences(SETTINGS, Context.MODE_MULTI_PROCESS);
Editor editor = prefs.edit();
editor.putBoolean(ALLOW_SOMETHING, value);
editor.commit();
}


static Boolean getSomething(Context context) {
SharedPreferences prefs = context.getSharedPreferences(SETTINGS, Context.MODE_MULTI_PROCESS);
return prefs.getBoolean(ALLOW_SOMETHING, false);
}
}

//----------------------

Обращаюсь к настройкам из Activity:
if (SettingsController.getSomething(context)) {
doSomething();
// Вижу, что метод doSomething() выполнен
}

Обращаюсь к настройкам из Службы:
if (SettingsController.getSomething(context)) {
doSomething();
// Вижу, что метод doSomething() НЕ выполнен
} else {
// Попадаю сюда
}

Вопрос 1: что я делаю не так?
Вопрос 2: как правильно достучаться к SharedPreferences из службы?

behzodbek
Сообщения: 58
Зарегистрирован: 23 дек 2012, 22:58
Откуда: UZB Namangan

Re: Как достучаться к SharedPreferences из службы?

Сообщение behzodbek » 11 май 2013, 17:55

Tamachi писал(а):[syntax=java][/syntax]Вот так выглядит класс для работы с настройками

public class SettingsController {
static void setSomething(Context context, Boolean value) {
SharedPreferences prefs = context.getSharedPreferences(SETTINGS, Context.MODE_MULTI_PROCESS);
Editor editor = prefs.edit();
editor.putBoolean(ALLOW_SOMETHING, value);
editor.commit();
}


static Boolean getSomething(Context context) {
SharedPreferences prefs = context.getSharedPreferences(SETTINGS, Context.MODE_MULTI_PROCESS);
return prefs.getBoolean(ALLOW_SOMETHING, false);
}
}

//----------------------

Обращаюсь к настройкам из Activity:
if (SettingsController.getSomething(context)) {
doSomething();
// Вижу, что метод doSomething() выполнен
}

Обращаюсь к настройкам из Службы:
if (SettingsController.getSomething(context)) {
doSomething();
// Вижу, что метод doSomething() НЕ выполнен
} else {
// Попадаю сюда
}

Вопрос 1: что я делаю не так?
Вопрос 2: как правильно достучаться к SharedPreferences из службы?
Тоже мучался :)
Мистер Резак90(Славик) помог.
Context ctx = getApplicationContext();
SharedPreferences prf = ctx
.getSharedPreferences("MyPref", MODE_PRIVATE);
Данный метод работает на ура. Глюков не должно быть. АПП с этим кодом прямо сейчас работает нормально.
Изображение

Tamachi
Сообщения: 203
Зарегистрирован: 17 апр 2013, 00:08

Re: Как достучаться к SharedPreferences из службы?

Сообщение Tamachi » 12 май 2013, 19:10

behzodbek писал(а):
Tamachi писал(а):[syntax=java][/syntax]Вот так выглядит класс для работы с настройками

public class SettingsController {
static void setSomething(Context context, Boolean value) {
SharedPreferences prefs = context.getSharedPreferences(SETTINGS, Context.MODE_MULTI_PROCESS);
Editor editor = prefs.edit();
editor.putBoolean(ALLOW_SOMETHING, value);
editor.commit();
}


static Boolean getSomething(Context context) {
SharedPreferences prefs = context.getSharedPreferences(SETTINGS, Context.MODE_MULTI_PROCESS);
return prefs.getBoolean(ALLOW_SOMETHING, false);
}
}

//----------------------

Обращаюсь к настройкам из Activity:
if (SettingsController.getSomething(context)) {
doSomething();
// Вижу, что метод doSomething() выполнен
}

Обращаюсь к настройкам из Службы:
if (SettingsController.getSomething(context)) {
doSomething();
// Вижу, что метод doSomething() НЕ выполнен
} else {
// Попадаю сюда
}

Вопрос 1: что я делаю не так?
Вопрос 2: как правильно достучаться к SharedPreferences из службы?
Тоже мучался :)
Мистер Резак90(Славик) помог.
Context ctx = getApplicationContext();
SharedPreferences prf = ctx
.getSharedPreferences("MyPref", MODE_PRIVATE);
Данный метод работает на ура. Глюков не должно быть. АПП с этим кодом прямо сейчас работает нормально.

Дык MODE_PRIVATE мне не годится: читаю настройки не только из Activity, но ещё и из службы и из BroadcastReceiver.

xr0m
Сообщения: 131
Зарегистрирован: 06 апр 2013, 14:01

Re: Как достучаться к SharedPreferences из службы?

Сообщение xr0m » 12 май 2013, 19:20

дык убери флаг

SharedPreferences prf = ctx.getSharedPreferences("MyPref");

update: ошибок в коде не вижу, все верно. смотри настройки сервиса, из-за чего он не имеет допуск.

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: Как достучаться к SharedPreferences из службы?

Сообщение neoksi » 12 май 2013, 19:51

А можно проще, создать синглтон, который будет работать с настройками, а к нему уже обращаться из любой части программы.

Tamachi
Сообщения: 203
Зарегистрирован: 17 апр 2013, 00:08

Re: Как достучаться к SharedPreferences из службы?

Сообщение Tamachi » 12 май 2013, 22:10

neoksi писал(а):А можно проще, создать синглтон, который будет работать с настройками, а к нему уже обращаться из любой части программы.
Собственно, упомянутый фрагмент кода и входит в состав такого синглтона. Я просто всё, не касающееся вопроса из кода поудалял.

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Как достучаться к SharedPreferences из службы?

Сообщение Mikhail_dev » 13 май 2013, 01:31

Самый простой способ это getDefaultSharedPreferences(android.content.Context)
И почему его не привели примером - я понятия не имею.
Он по дефолту работает через MODE_PRIVATE (p.s. смотреть сорцы).
Мы обновялем настройки - в этот момент происходит бродкаст (системный) на изменение настроек. Мы бросаем бродкаст, запускаем updateSettings и после юзаем через гетеры значения. Проще некуда. Но есть один момент. Если процесса два - хоть убейся, это будет ДВА сингтона! Две далвик машины - два синглтона - два вида настроек. Поэтому надо обновлять как в UI, так и в сервисе. Я уже на этом пообжигался.

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: Как достучаться к SharedPreferences из службы?

Сообщение neoksi » 13 май 2013, 07:56

Ну если более одного процесса, то тут лучше работать через ContentProvider'а, запускаем его в одном процессе и из других обращаемся к нему.

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Как достучаться к SharedPreferences из службы?

Сообщение Mikhail_dev » 13 май 2013, 09:40

Если приложения два, то пожалуй и так. Но если приложение одно, а процесса два?
Я работаю через обычные настройки. У меня есть там баг и он вылазит на версии 2.3 , но в целом вроде как работает (пока не смог понять природу бага).
Мы лично используем такую модель представления настроек в виде singlton.
[syntax=java]
public class Preferences {
private static final Context c = App.getInstance().getApplicationContext();
public static final String NAVI_ALTERNATIVE_ROUTES_KEY = c.getString(R.string.navi_alternative_routes_key);
public static final String NAVI_RECALCULATION_ROUTE_KEY = c.getString(R.string.navi_recalculation_route_key);
private boolean useAlternateRoutes;
private int alternateRouteDistance;
private Preferences() {

}

public static synchronized Preferences getInstance() {
if (instance==null) {
instance = new Preferences();
}
return instance;
}
/** Обновляет переменные класса в соответствии с выбранными настройками */
public synchronized void updatePreferences(Context context) {
this.mPreferences = PreferenceManager.getDefaultSharedPreferences(context);
useAlternateRoutes = mPreferences.getBoolean(NAVI_ALTERNATIVE_ROUTES_KEY, false);
alternateRouteDistance = Integer.parseInt(mPreferences.getString(NAVI_RECALCULATION_ROUTE_KEY, "100"));
}

public boolean isUseAlternateRoutes() {
return useAlternateRoutes;
}
[/syntax]
Класс специально показан в урезанном виде.
Также есть активность, которая наследуется от PreferenceActivity и реализует интерфейс
[syntax=java]public class SettingsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener {...}[/syntax]
В ней есть метод
[syntax=java] @Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Intent intent = new Intent(App.I_SETTINGS_CHANGED);
intent.putExtra("key", key);
sendBroadcast(intent);
}[/syntax]
Который и рассылает бродкаст, когда настройки изменились. Ловим бродкаст и обновляем переменные в классе. А дальше Preferences.getInstance.get...
Последний раз редактировалось Mikhail_dev 13 май 2013, 15:00, всего редактировалось 1 раз.

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: Как достучаться к SharedPreferences из службы?

Сообщение neoksi » 13 май 2013, 10:05

no-- писал(а):Если приложения два, то пожалуй и так. Но если приложение одно, а процесса два?
Тоже, если более одного процесса, считай у тебя уже разные приложения.


Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Как достучаться к SharedPreferences из службы?

Сообщение Mikhail_dev » 13 май 2013, 16:44

В общем есть одна печальная новость. Вопрос с проблемой тут
Вкратце: надо менять настройки и использовать их в обоих процессах.
1. До версии 2.3 это успешно работало способом, что я указал.
2. В версии 2.3 это не работает! (38 процентов юзеров на 4 марта!)
3. В версии >2.3 при использовании флага MODE_MULTI_PROCESS это работает.
В чем собственно проблема. Проблема в том, что раньше настройки вступали в силу сразу, а сейчас они кешируются.

P.S. я вроде нашел решение этой проблемы и вроде стало всё работать (даже флаг MODE_MULTI_PROCESS похоже можно пропустить), но пока протестировано на одном устройстве. После пары дней тестов на нескольких устройствах, я опубликую решение, если кому интересно.

Tamachi
Сообщения: 203
Зарегистрирован: 17 апр 2013, 00:08

Re: Как достучаться к SharedPreferences из службы?

Сообщение Tamachi » 13 май 2013, 22:52

no-- писал(а):В общем есть одна печальная новость. Вопрос с проблемой тут
Вкратце: надо менять настройки и использовать их в обоих процессах.
1. До версии 2.3 это успешно работало способом, что я указал.
2. В версии 2.3 это не работает! (38 процентов юзеров на 4 марта!)
3. В версии >2.3 при использовании флага MODE_MULTI_PROCESS это работает.
В чем собственно проблема. Проблема в том, что раньше настройки вступали в силу сразу, а сейчас они кешируются.

P.S. я вроде нашел решение этой проблемы и вроде стало всё работать (даже флаг MODE_MULTI_PROCESS похоже можно пропустить), но пока протестировано на одном устройстве. После пары дней тестов на нескольких устройствах, я опубликую решение, если кому интересно.
У меня есть много андроид-телефонов. Пришли тестик -- я запущу на разных телефонах и скажу тебе, работает или нет.

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Как достучаться к SharedPreferences из службы?

Сообщение Mikhail_dev » 15 май 2013, 13:34

Не стоит, уже потестили - работает. Сделал ответ в виде заметки.

Ответить