java - 在 Android Things 中使用 SharedPreferences

标签 java sharedpreferences android-things

我尝试在我的 Things 应用程序中使用 SharedPreferences,但由于某种原因它总是返回 0。我的 setter 正在记录它使用编辑器推送了正确的数据,但每次读取,即使重新启动 Activity 后,也始终为 0。我找不到为什么 Things 不允许使用 SharedPreferences 的原因,即使有需要更改权限,所以我有点不知所措。这显然是我的代码,但我不明白为什么。

我的目标是使用可触摸的 TextView 来简单地更新触摸时的日期。没有按钮,没有真正的交互,而且简单干净。但如果 SharedPreferences 不起作用,事情就会变得更加困难。

我在 OnCreate 中尝试过各种实例化 SharedPreferences 对象的方法,但每次使用它都没有效果。我还对 Activity 使用了全局和本地编辑器,但没有效果。写入似乎成功,但读取 getLong() 总是返回 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();
        }
    };
}

记录显示有效的毫秒值存储在 OnTouchListener 的 Long 中,当我触摸 TextView 时会调用该值。每次调用 updateWaterChangeDate() 都会记录 0 项,并且日期始终是 1970 年 1 日。

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 返回一个 long,您调用的方法的第二个参数不是要填充的引用,而是在未找到首选项时返回的默认值。

您的代码根本不检查共享首选项的返回值。

关于java - 在 Android Things 中使用 SharedPreferences,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56716344/

相关文章:

flutter - Flutter保存多个用户的共享首选项

android - 如何下载android things OS源代码?

android - com.google.android.things.contrib.driver.button.Button 与 android.widget.Button

java - 无法使用 JDBC 连接到 Syabse 数据库

java - 下面的代码段创建了多少个字符串对象

java - jdbc 资源部署后未出现在 JDBC Resources 节点

java - 使用 Gson 序列化具有非原始值的对象的 ArrayList?

android - 如何保护 Android 共享首选项?

将外设移植到 AndroidThings - 引脚选择

Java 注解反射排序