Android appwidget иногда меняет настройки обратно на стандартные - PullRequest
1 голос
/ 10 января 2012

У меня есть пара приложений, выпущенных на рынке Android, и они по большей части работают нормально.Однако я заметил, что настройки, сохраненные с использованием общих настроек, иногда сбрасываются до значений по умолчанию.Значения по умолчанию в этом случае являются жестко закодированными переменными.Общие предпочтения, сохраненные в xml, остаются такими же, как и сохраненные пользователем.

В одном поддающемся проверке случае вышеупомянутая проблема, а также другие вещи, такие как кнопки, которые перестают отвечать, возникали после перезагрузки устройства.Я исправил это, создав BroadcastReceiver, у которого есть метод onReceive (), который будет активирован фильтром намерений в манифесте:

<intent-filter>
  <action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>

Другими словами, BroadcastReceiver будет работать после перезагрузки, что прекрасно работает.

Однако устройство по-прежнему иногда сбрасывает настройки, и я заметил, что это происходит после ночи или около того, находясь в режиме ожидания.Я подозреваю, что это связано с тем, что устройство (через некоторое время, возможно, из-за перехода в режим ожидания) может перезапустить appwidget, который затем снова будет использовать настройки по умолчанию.Я попытался решить эту проблему, добавив следующее в манифест как часть BroadcastReceiver:

<intent-filter>
  <action android:name="android.intent.action.PACKAGE_RESTARTED"/>
</intent-filter>

Полный раздел читает:

<receiver android:name=".BroadcastReceiverName">
  <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED"/>
  </intent-filter>
  <intent-filter>
    <action android:name="android.intent.action.PACKAGE_RESTARTED"/>
  </intent-filter>
</receiver>

Но, похоже, это не работает.

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

Для полноты картины это часть(работающий) код BroadcastReceiver, который я получил от Служба не перезапускается после сброса «Очистить память» + appWidget

public class BroadcastReceiverName extends BroadcastReceiver
{
  @Override
  public void onReceive(Context context, Intent intent)
  {
    /* stuff done here to reread shared preferences and refresh button's pending intents etc. */

    SharedPreferences config=context.getSharedPreferences(ExampleWidgetConfig.PREFS_NAME, 0);
    int poll=config.getInt(ExampleWidgetConfig.PREFS_UPDATE_RATE, ExampleWidgetProvider.poll);
    int alert=config.getInt(ExampleWidgetConfig.PREFS_ALERT, ExampleWidgetProvider.alert);
    int backg=config.getInt(ExampleWidgetConfig.PREFS_BACKG, ExampleWidgetProvider.backg);

    /* change hardcoded default preferences in case they differ from saved ones */
    ExampleWidgetProvider.poll=poll;
    ExampleWidgetProvider.alert=alert;
    ExampleWidgetProvider.backg=backg;

    /* ... */
  }
}

Код, который сохраняет настройки.Обратите внимание, что этот код на самом деле работает, и проблема не в том, что настройки не сохраняются и не читаются правильно, а в том, что жестко закодированные значения в приложении, которые были изменены на значения пользователя, снова изменяются (см. Пример выше).

/* change hardcoded values to user's settings */
ExampleWidgetProvider.poll=getpoll();
ExampleWidgetProvider.alert=getalert();
ExampleWidgetProvider.backg=getbackg();

/* store user settings we will continue to use these in the app */
SharedPreferences.Editor configEditor=config.edit();
configEditor.putInt(PREFS_UPDATE_RATE, ExampleWidgetProvider.poll);
configEditor.putInt(PREFS_ALERT, ExampleWidgetProvider.alert);
configEditor.putInt(PREFS_BACKG, ExampleWidgetProvider.backg);
configEditor.commit();

Так что мне нужно знать, как узнать, когда эти жестко заданные значения сбрасываются до значений по умолчанию.Я мог бы обойти это, читая настройки xml каждый час или около того, но это звучит как глупое решение.

1 Ответ

1 голос
/ 11 января 2012

Как указано в документации:

Параметры

ключ Имя предпочтения для получения.defValue Значение, которое возвращается, если этого предпочтения не существует.

Возвращает значение предпочтения, если оно существует, или defValue.Выдает ClassCastException, если есть предпочтение с этим именем, которое не является целым числом.

Если верить документации, то предпочтения вообще не существует, вы можете проверить это, сделав ваш getInt значения, отличающиеся от ваших значений в xml, если он возвращает ваши getInt значения, вы знаете, что предпочтения не существуют.

В приведенном выше случае ваши предпочтения должны быть удалены или не были установленыв первую очередь, это выглядит довольно маловероятно.

Другая вещь, на которую вы могли бы обратить внимание, это то, что вы звоните commit, когда обновляете свои предпочтения, или ваши предпочтения обновляются.

Вы также можете попробовать поиграть с режимами, когда настраиваете свои предпочтения, попробуйте MODE_MULTI_PROCESS, так как приемник широкого вещания - это отдельный процесс, и, вероятно, вы устанавливаете предпочтения в другом месте, а также попробуйте 'MODE_WORLD_WRITEABLE'.

ОБНОВЛЕНИЕ из комментариев

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

Вот как я понимаю проблему: вы устанавливаете эти значения по своему усмотрению, и вы можете позвонить getInt в этих предпочтениях в какой-то момент, и это правильно, затем после определенного события (возможно, вызванного переходом в режим ожидания) вы снова вызываете getInt, и предпочтение возвращается к значению по умолчанию, как указано в preference.xml, а не по умолчаниюзначение, переданное при вызове getInt (поскольку это предполагает, что предпочтение не существует).

Я заметил, что вы копируете значения в эти переменные ExampleWidgetProvider. *, уверены ли вы, что это неправильные значениявы извлекаете данные как настройки, и те значения, которые существуют в настройках, никогда не устанавливаются правильно.Я не вижу смысла в наличии этих переменных, поскольку вы обязаны синхронизировать их, когда вы меняете одну из них.Если они являются частью работы, то их следует удалить, чтобы они не обернулись исходной проблемой.

Как я уверен, вы знаете;если вы перезапустите приложение, настройки должны быть такими же, как и до перезапуска, поскольку значения параметров сохраняются (при условии, что они настроены правильно) и, как сказано в документации:

android: defaultValue Значение по умолчанию для предпочтения, которое будет установлено, если постоянство отключено или постоянство включено, и предпочтение не найдено в постоянном хранилище.

Что говорит о том, что предпочтениене возвращается к исходному значению, а скорее не существует по какой-либо причине (если это конкретное значение по умолчанию появляется снова).

Существует метод setDefaultValues(Context context, int resId, boolean readAgain=true), но вы сказали, что нет 'Я так называю.Так что кажется маловероятным, что предпочтение сбрасывается, а скорее оно удаляется или никогда не существовало.

...