在 Android 事物中使用 SharedPreferences
Using SharedPreferences in Android Things
我试图在我的 Things 应用程序中使用 SharedPreferences,但由于某种原因它总是 returns 0。我的 setter 正在记录它使用编辑器推送正确的数据,但每次读取,即使在重新启动 activity 之后,也始终为 0。我找不到事情不会发生的原因允许使用 SharedPreferences,即使需要更改权限,所以我有点不知所措。这明明是我的代码,但我不明白为什么。
我的目标是使用可触摸的 TextView,以便在触摸时简单地更新日期。没有按钮,没有真正的互动,而且简单干净。但是,如果 SharedPreferences 不起作用,这将变得更加困难。
我在 OnCreate 中用过各种不同的方法来实例化 SharedPreferences 对象,但每次都没有效果。我还对 Activity 使用了全局和本地编辑器,但没有效果。写入似乎成功,但对于 getLong() 始终读取 return 0。我从 apply() 切换到 commit() 认为这可能只是一个时间问题。但是,退出并再次启动 activity 也没有显示值,它仍然是 0。
包含的内容是根据我对 Java 的了解在 Android 文档中找到的最新内容。第一个是我认为与问题相关的内容。第二个代码示例是完整的 activity.
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();
}
};
}
日志记录显示在我触摸 TextView 时调用的 OnTouchListener 的 Long 中存储了一个有效的毫秒值。每次调用 updateWaterChangeDate() 都会为项目记录 0,并且日期始终是 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 return 是一个 long,您正在调用的方法的第二个参数不是要填充的引用,而是要 returned 的默认值以防偏好未找到。
您的代码根本没有检查共享首选项中的 return 值。
我试图在我的 Things 应用程序中使用 SharedPreferences,但由于某种原因它总是 returns 0。我的 setter 正在记录它使用编辑器推送正确的数据,但每次读取,即使在重新启动 activity 之后,也始终为 0。我找不到事情不会发生的原因允许使用 SharedPreferences,即使需要更改权限,所以我有点不知所措。这明明是我的代码,但我不明白为什么。
我的目标是使用可触摸的 TextView,以便在触摸时简单地更新日期。没有按钮,没有真正的互动,而且简单干净。但是,如果 SharedPreferences 不起作用,这将变得更加困难。
我在 OnCreate 中用过各种不同的方法来实例化 SharedPreferences 对象,但每次都没有效果。我还对 Activity 使用了全局和本地编辑器,但没有效果。写入似乎成功,但对于 getLong() 始终读取 return 0。我从 apply() 切换到 commit() 认为这可能只是一个时间问题。但是,退出并再次启动 activity 也没有显示值,它仍然是 0。
包含的内容是根据我对 Java 的了解在 Android 文档中找到的最新内容。第一个是我认为与问题相关的内容。第二个代码示例是完整的 activity.
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();
}
};
}
日志记录显示在我触摸 TextView 时调用的 OnTouchListener 的 Long 中存储了一个有效的毫秒值。每次调用 updateWaterChangeDate() 都会为项目记录 0,并且日期始终是 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 return 是一个 long,您正在调用的方法的第二个参数不是要填充的引用,而是要 returned 的默认值以防偏好未找到。
您的代码根本没有检查共享首选项中的 return 值。