Search code examples
javaandroidsharedpreferences

Android how to set and retrieve data from Preference object


I am working on a preference fragment, one preference is to select an external image file as the app background.

I try to save the file path string to the correspond preference, so that I can load that path data from SharedPreferences when the app is launched.

My problem is when using Preference class instead of EditTextPreference, there is no setText() method to save the path value, and I cannot figure out how to store the data onto a Preference object and then retrieve through SharedPreferences.getString("key", "") in my activity.

If I use a EditTextPreference instead, indeed it works but I have to disable or customize the dialog component of EditTextPreference, since I need to start a new activity to pick a image when tapping this preference.

I notice in the official documentation they use Preference when using intent together. Is there any way to save data to a Preference object and then retrieve that data in an activity?

// In preference fragment
private Preference bgPref;
@Override
  public void onActivityResult(
      int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK && data != null) {
      Uri imageUri = data.getData();
      final String path = getFilePath(requireContext(), imageUri);
      if (path != null) {
        bgPref.setText(path); // how to set a string value for a Preference?
        Drawable d = Drawable.createFromPath(path);
        if (containerView != null) {
          containerView.setBackground(d);
        }
      }
    } else {
      Toast.makeText(requireContext(), "You haven't picked Image", Toast.LENGTH_LONG).show();
    }
  }

// In Main activity
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);

String bgPath = sharedPrefs.getString("bgPath", "");

Drawable d = Drawable.createFromPath(bgPath);
if (!bgPath.isEmpty()) findViewById(R.id.nav_host_fragment).setBackground(d);
//...

Solution

  • You can edit this preference directly. In onActivityResult():

    @Override
    public void onActivityResult(
        int requestCode, int resultCode, @Nullable Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            if (resultCode == RESULT_OK && data != null) {
                Uri imageUri = data.getData();
                final String path = getFilePath(requireContext(), imageUri);
                if (path != null) {
                    // Save preference here
                    SharedPreferences.Editor editor = sharedPrefs.edit();
                    editor.putString("bgPath", path);
                    editor.apply();
                    // Now recreate activity to refresh the UI
                    requireActivity().recreate();
                    // In onCreateView, you can use this preference to set background
                }
            } else {
                Toast.makeText(requireContext(), "You haven't picked Image", Toast.LENGTH_LONG).show();
            }
        }
    }