Я пытаюсь использовать SharedPreferences в своем приложении Things, но по какой-то причине он всегда возвращает 0. Мой сеттер регистрирует, что он ввел правильные данные с помощью редактора, но каждое чтение, даже после перезапуска действия, всегда равно 0. Я не могу найти причину, по которой Вещи не разрешают использовать SharedPreferences, даже с нужно изменить разрешение, поэтому я немного в недоумении. Очевидно, это мой код, но я не могу понять, почему.
Моя цель - использовать TextView, который можно осязать, чтобы просто обновить дату при прикосновении. Никаких кнопок, никакого реального взаимодействия, все просто и понятно. Но если SharedPreferences не работает, это становится сложнее.
Я использовал разные способы создания экземпляра объекта SharedPreferences в OnCreate каждый раз, когда я использую его безрезультатно. Я также использовал глобальный и локальный редактор для Activity, но безрезультатно. Запись кажется успешной, но чтение всегда возвращает 0 для getLong(). Я переключаюсь с apply() на commit(), думая, что это просто проблема со временем. Однако выход и повторный запуск действия также не показывает значение, оно по-прежнему равно 0.
То, что включено, является последним, основанным на том, что я нашел в документации Android на основе того, что я знаю о Java. Первое — это то, что я считаю относящимся к вопросу. Второй пример кода — это полная активность.
public class DataViewActivity extends Activity {
private static final String TAG = DataViewActivity.class.getSimpleName();
TextView m_textViewTemperature;
TextView m_textViewWaterLevel;
TextView m_textViewIronAddition;
TextView m_textViewWaterChange;
TextView m_textViewFilterChange;
Handler m_exitHandler = new Handler();
SharedPreferences m_preferences;
public static final String PREFERENCES = "aquarium";
public static final String WATER_CHANGE = "waterchange";
public static final String FILTER_CHANGE = "filterchange";
public static final String IRON_ADD = "ironaddition";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
setContentView(R.layout.activity_data_view);
m_preferences = getSharedPreferences(PREFERENCES, Context.MODE_PRIVATE);
m_textViewTemperature = findViewById(R.id.textViewTemperatureData);
m_textViewWaterLevel = findViewById(R.id.textViewWaterLevelData);
m_textViewFilterChange = findViewById(R.id.textViewFilterChangeDateData);
m_textViewIronAddition = findViewById(R.id.textViewIronAdditionDateData);
m_textViewWaterChange = findViewById(R.id.textViewWaterChangeDateData);
m_textViewWaterChange.setOnTouchListener(new View.OnTouchListener() {
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Long time = Calendar.getInstance().getTimeInMillis();
SharedPreferences.Editor e = m_preferences.edit();
e.putLong(WATER_CHANGE, time);
e.commit();
Log.i(TAG, "Stored " + time + " to shared preferences for last water change");
updateWaterChangeDate();
}
return false;
}
});
}
private void updateWaterChangeDate()
{
Calendar c = Calendar.getInstance();
Long item = m_preferences.getLong("WaterChange", 0);
Log.d(TAG, "Got " + item + " for last water change millis");
c.setTimeInMillis(item);
SimpleDateFormat df = new SimpleDateFormat("EEE, MMM d");
m_textViewWaterChange.setText(df.format(c.getTime()));
}
package com.home.pete.aquarium;
import androidx.appcompat.app.AppCompatActivity;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
import java.util.prefs.Preferences;
import static com.home.pete.aquarium.Constants.VIEW_TIMEOUT;
import static java.lang.Long.getLong;
/**
* Skeleton of an Android Things activity.
* <p>
* Android Things peripheral APIs are accessible through the class
* PeripheralManagerService. For example, the snippet below will open a GPIO pin and
* set it to HIGH:
*
* <pre>{@code
* PeripheralManagerService service = new PeripheralManagerService();
* mLedGpio = service.openGpio("BCM6");
* mLedGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
* mLedGpio.setValue(true);
* }</pre>
* <p>
* For more complex peripherals, look for an existing user-space driver, or implement one if none
* is available.
*
* @see <a href = "https://github.com/androidthings/contrib-drivers#readme">https://github.com/androidthings/contrib-drivers#readme</a>
*/
public class DataViewActivity extends Activity {
private static final String TAG = DataViewActivity.class.getSimpleName();
TextView m_textViewTemperature;
TextView m_textViewWaterLevel;
TextView m_textViewIronAddition;
TextView m_textViewWaterChange;
TextView m_textViewFilterChange;
Handler m_exitHandler = new Handler();
SharedPreferences m_preferences;
public static final String PREFERENCES = "aquarium";
public static final String WATER_CHANGE = "waterchange";
public static final String FILTER_CHANGE = "filterchange";
public static final String IRON_ADD = "ironaddition";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
setContentView(R.layout.activity_data_view);
m_preferences = getSharedPreferences(PREFERENCES, Context.MODE_PRIVATE);
m_textViewTemperature = findViewById(R.id.textViewTemperatureData);
m_textViewWaterLevel = findViewById(R.id.textViewWaterLevelData);
m_textViewFilterChange = findViewById(R.id.textViewFilterChangeDateData);
m_textViewIronAddition = findViewById(R.id.textViewIronAdditionDateData);
m_textViewWaterChange = findViewById(R.id.textViewWaterChangeDateData);
m_textViewWaterChange.setOnTouchListener(new View.OnTouchListener() {
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Long time = Calendar.getInstance().getTimeInMillis();
SharedPreferences.Editor e = m_preferences.edit();
e.putLong(WATER_CHANGE, time);
e.commit();
Log.i(TAG, "Stored " + time + " to shared preferences for last water change");
updateWaterChangeDate();
}
return false;
}
});
m_textViewIronAddition.setOnTouchListener(new View.OnTouchListener() {
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Long time = Calendar.getInstance().getTimeInMillis();
SharedPreferences.Editor e = m_preferences.edit();
e.putLong(IRON_ADD, time);
e.commit();
Log.i(TAG, "Stored " + time + " to shared preferences for last iron addition");
updateIronAdditionDate();
}
return false;
}
});
m_textViewFilterChange.setOnTouchListener(new View.OnTouchListener() {
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Long time = Calendar.getInstance().getTimeInMillis();
SharedPreferences.Editor e = m_preferences.edit();
e.putLong(FILTER_CHANGE, time);
e.commit();
Log.i(TAG, "Stored " + time + " to shared preferences for last filter change");
updateFilterChangeDate();
}
return false;
}
});
LocalBroadcastManager.getInstance(this).registerReceiver(temperatureUpdate, new IntentFilter("temperature"));
LocalBroadcastManager.getInstance(this).registerReceiver(waterlevelUpdate, new IntentFilter("waterlevel"));
updateFilterChangeDate();
updateIronAdditionDate();
updateWaterChangeDate();
m_exitHandler.postDelayed(exitViewOnTimeout, VIEW_TIMEOUT);
}
@Override
protected void onDestroy() {
Log.d(TAG, "onDestroy");
super.onDestroy();
}
private void updateFilterChangeDate()
{
Calendar c = Calendar.getInstance();
Long item = m_preferences.getLong("FilterChange", 0);
c.setTimeInMillis(item);
SimpleDateFormat df = new SimpleDateFormat("EEE, MMM d");
m_textViewFilterChange.setText(df.format(c.getTime()));
}
private void updateWaterChangeDate()
{
Calendar c = Calendar.getInstance();
Long item = m_preferences.getLong("WaterChange", 0);
Log.d(TAG, "Got " + item + " for last water change millis");
c.setTimeInMillis(item);
SimpleDateFormat df = new SimpleDateFormat("EEE, MMM d");
m_textViewWaterChange.setText(df.format(c.getTime()));
}
private void updateIronAdditionDate()
{
Calendar c = Calendar.getInstance();
Long item = m_preferences.getLong("IronAddition", 0);
c.setTimeInMillis(item);
SimpleDateFormat df = new SimpleDateFormat("EEE, MMM d");
m_textViewIronAddition.setText(df.format(c.getTime()));
}
public void exitView(View view)
{
Log.d(TAG, "Closing view");
m_exitHandler.removeCallbacks(exitViewOnTimeout);
finish();
}
private BroadcastReceiver temperatureUpdate = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent)
{
Double value = intent.getDoubleExtra("ACTION", 0.0);
m_textViewTemperature.setText(value.toString() + " \u2109");
}
};
private BroadcastReceiver waterlevelUpdate = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent)
{
Integer value = intent.getIntExtra("ACTION", 0);
String text;
if (value > 2760)
text = "full";
else if (value > 2750)
text = "-1 cm";
else if (value > 2730)
text = "-2 cm";
else
text = value.toString();
m_textViewWaterLevel.setText(text);
}
};
@Override
protected void onResume() {
super.onResume();
}
private Runnable exitViewOnTimeout = new Runnable() {
@Override
public void run() {
Log.d(TAG, "Closing view due to timeout handler");
finish();
}
};
}
Регистрация показывает, что допустимое значение миллисекунд хранится в Long в OnTouchListener, который вызывается, когда я касаюсь TextView. При каждом вызове updateWaterChangeDate() регистрируется 0 для элемента, а дата всегда является 1-м числом 1970 года.
2019-06-22 09:20:20.483 2614-2614/com.home.pete.aquarium I/DataViewActivity: Stored 1561213220471 to shared preferences for last water change
2019-06-22 09:20:20.484 2614-2614/com.home.pete.aquarium D/DataViewActivity: Got 0 for last water change millis
...
2019-06-22 09:20:25.647 2614-2614/com.home.pete.aquarium D/DataViewActivity: onDestroy
2019-06-22 09:20:26.710 2614-2614/com.home.pete.aquarium D/MainActivity: Viewing settings
2019-06-22 09:20:26.737 2614-2614/com.home.pete.aquarium D/DataViewActivity: onCreate
2019-06-22 09:20:26.834 2614-2614/com.home.pete.aquarium D/DataViewActivity: Got 0 for last water change millis




Метод getLong возвращает длинный второй параметр метода, который вы вызываете, — это не ссылка для заполнения, а значение по умолчанию, которое будет возвращено в случае, если предпочтение не найдено.
Ваш код просто не проверяет возвращаемое значение из общих настроек.
Спасибо. На самом деле у меня есть две проблемы выше: одна - игнорирование возвращаемого значения, а другая - то, что я не использовал статические строковые константы в геттерах, и ключи не совпадали. Исправлены обе эти проблемы, и теперь это работает. Спасибо большое.