package com.javispedro.wallmotion; import android.app.Activity; import android.content.ContentResolver; import android.content.Intent; import android.content.SharedPreferences; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.provider.OpenableColumns; import android.text.TextUtils; import android.util.Log; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; import androidx.preference.Preference; import androidx.preference.PreferenceFragmentCompat; import androidx.preference.PreferenceManager; public class SettingsActivity extends AppCompatActivity { private static final String TAG = "SettingsActivity"; public static final String ACTION_CHOOSE_FILE = "com.javispedro.wallmotion.choose_file"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.settings_activity); SettingsFragment fragment = new SettingsFragment(); getSupportFragmentManager() .beginTransaction() .replace(R.id.settings, fragment) .commit(); ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(true); } } @Override public boolean onSupportNavigateUp() { onBackPressed(); return true; } public static class SettingsFragment extends PreferenceFragmentCompat { private static final String TAG = "SettingsFragment"; private final static int PICK_VIDEO_FILE = 1; @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { setPreferencesFromResource(R.xml.root_preferences, rootKey); Preference video_file = findPreference(getString(R.string.settings_video_file_key)); video_file.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { openVideoFilePicker(); return true; } }); video_file.setSummary(getVideoFileSummary()); Preference video_file_clear = findPreference(getString(R.string.settings_video_file_clear_key)); video_file_clear.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { setVideoFile(null); return true; } }); } @Override public void onStart() { super.onStart(); Intent launchIntent = getActivity().getIntent(); if (launchIntent != null && launchIntent.getAction().equals(ACTION_CHOOSE_FILE)) { openVideoFilePicker(); getActivity().finish(); } } @Override public void onActivityResult(int requestCode, int resultCode, Intent resultData) { switch (requestCode) { case PICK_VIDEO_FILE: if (resultCode == Activity.RESULT_OK && resultData != null) { Uri uri = resultData.getData(); setVideoFile(uri); } break; } } private void openVideoFilePicker() { Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("video/*"); intent.setFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); startActivityForResult(intent, PICK_VIDEO_FILE); } private void setVideoFile(Uri uri) { ContentResolver resolver = getContext().getContentResolver(); // First, release any permission request on the current uri String cur_value = getStringPref(getString(R.string.settings_video_file_key)); if (!TextUtils.isEmpty(cur_value)) { Uri cur_uri = Uri.parse(cur_value); if (cur_uri.equals(uri)) { Log.d(TAG, "identical uri selected"); return; } Log.d(TAG, "release persistable uri permission on uri: " + cur_uri.toString()); try { resolver.releasePersistableUriPermission(cur_uri, Intent.FLAG_GRANT_READ_URI_PERMISSION); } catch (Exception ex) { Log.w(TAG, "could not release persistable uri permission on uri: " + cur_uri.toString()); ex.printStackTrace(); } } // Then, store the new setting if (uri != null) { Log.d(TAG, "storing video_file pref uri: " + uri.toString()); setStringPref(getString(R.string.settings_video_file_key), uri.toString()); // Take a persistent permission on it Log.d(TAG, "take persistable uri permission on uri: " + uri.toString()); resolver.takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION); } else { Log.d(TAG, "clearing video_file pref uri"); clearPref(getString(R.string.settings_video_file_key)); } // Refresh the UI summary Preference video_file = findPreference(getString(R.string.settings_video_file_key)); video_file.setSummary(getVideoFileSummary()); } private String getVideoFileSummary() { String cur_value = getStringPref(getString(R.string.settings_video_file_key)); if (!TextUtils.isEmpty(cur_value)) { ContentResolver resolver = getContext().getContentResolver(); Uri uri = Uri.parse(cur_value); String[] projection = {OpenableColumns.DISPLAY_NAME}; try { Cursor cursor = resolver.query(uri, projection, null, null, null); if (cursor != null) { int col = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); if (col >= 0 && cursor.moveToFirst()) { String name = cursor.getString(col); cursor.close(); Log.d(TAG, "got video file display_name: " + name); return name; } else { Log.w(TAG, "Could not navigate cursor for URI: " + uri.toString()); } cursor.close(); } else { Log.w(TAG, "Could not get cursor for URI: " + uri.toString()); } } catch (java.lang.SecurityException ex) { ex.printStackTrace(); Log.w(TAG, "Security exception while reading URI: " + uri.toString()); } return uri.getLastPathSegment(); } return getString(R.string.settings_not_set); } protected String getStringPref(String pref) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); return prefs.getString(pref, null); } protected void setStringPref(String pref, String new_value) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); String cur_value = prefs.getString(pref, null); if (!TextUtils.equals(cur_value, new_value)) { SharedPreferences.Editor editor = prefs.edit(); editor.putString(pref, new_value); editor.apply(); } } protected void clearPref(String pref) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); if (prefs.contains(pref)) { SharedPreferences.Editor editor = prefs.edit(); editor.remove(pref); editor.apply(); } } } }