diff --git a/app/build.gradle b/app/build.gradle index 32bb92b..7aa6c2b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -36,6 +36,7 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.4.1' implementation 'com.google.android.material:material:1.5.0' implementation 'androidx.core:core-ktx:1.10.1' + implementation 'androidx.preference:preference:1.2.0' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 08aa5fa..206dda0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,6 +3,7 @@ xmlns:tools="http://schemas.android.com/tools"> + + - + + + - - - - - + + + + + + \ No newline at end of file diff --git a/app/src/main/java/cc/jerryxiao/easterscrsaver/EasterDream.java b/app/src/main/java/cc/jerryxiao/easterscrsaver/EasterDream.java index cd8a742..bf95c24 100644 --- a/app/src/main/java/cc/jerryxiao/easterscrsaver/EasterDream.java +++ b/app/src/main/java/cc/jerryxiao/easterscrsaver/EasterDream.java @@ -4,12 +4,13 @@ import static android.graphics.PixelFormat.TRANSLUCENT; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; +import android.annotation.SuppressLint; import android.app.WallpaperManager; +import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.Paint; -import android.graphics.Point; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; @@ -27,12 +28,17 @@ import android.widget.ImageView; import androidx.annotation.ChecksSdkIntAtLeast; import androidx.core.app.ActivityCompat; +import androidx.preference.PreferenceManager; +import java.util.ArrayList; +import java.util.Random; import java.util.Timer; import java.util.TimerTask; public class EasterDream extends DreamService { - private static String TAG = "easter_daydream"; + private static String TAG = "EasterDream"; + private SharedPreferences prefs; + private Drawable wallPaperDrawable = null; private FrameLayout last = null; private boolean enabled = false; @@ -101,7 +107,9 @@ public class EasterDream extends DreamService { @Override public void onAttachedToWindow() { super.onAttachedToWindow(); + this.prefs = PreferenceManager.getDefaultSharedPreferences(this); + setScreenBright(!this.prefs.getBoolean("dim_screen", false)); // Exit dream upon user touch setInteractive(false); // Hide system UI @@ -119,7 +127,7 @@ public class EasterDream extends DreamService { refresh(); } - private static final String[][] EMOJI_SETS = { + protected static final String[][] EMOJI_SETS = { {"๐Ÿ‡", "๐Ÿˆ", "๐Ÿ‰", "๐ŸŠ", "๐Ÿ‹", "๐ŸŒ", "๐Ÿ", "๐Ÿฅญ", "๐ŸŽ", "๐Ÿ", "๐Ÿ", "๐Ÿ‘", "๐Ÿ’", "๐Ÿ“", "๐Ÿซ", "๐Ÿฅ"}, {"๐Ÿ˜บ", "๐Ÿ˜ธ", "๐Ÿ˜น", "๐Ÿ˜ป", "๐Ÿ˜ผ", "๐Ÿ˜ฝ", "๐Ÿ™€", "๐Ÿ˜ฟ", "๐Ÿ˜พ"}, @@ -245,20 +253,37 @@ class BubblesDrawable extends Drawable { //randomize(); //chooseEmojiSet(); } - }, 10000L); + }, Integer.parseInt(EasterDream.this.prefs.getString("switch_time", "10")) * 1000L); } public void chooseEmojiSet() { - if (Math.random() < 0.8) { - if (Math.random() < 0.4) { - mEmojiSet = 0; - } - else { - mEmojiSet = 13; - } + ArrayList probList = new ArrayList<>(); + int probSum = 0; + for (int i = 0; i < EMOJI_SETS.length; i++) { + @SuppressLint("DefaultLocale") + int p = Integer.parseInt(EasterDream.this.prefs.getString(String.format("prob_%d", i), "5")); + probSum += p; + probList.add(probSum); + //Log.d(TAG, String.format("probList %d %d", i, probSum)); + } + //Log.d(TAG, String.format("probSum %d", probSum)); + if (probSum <= 0) { + mEmojiSet = (int) (Math.random() * EMOJI_SETS.length); } else { - mEmojiSet = (int) (Math.random() * EMOJI_SETS.length); + mEmojiSet = -1; + int r = (new Random()).nextInt(probSum); + for (int i = 0; i < EMOJI_SETS.length; i++) { + if (r < probList.get(i)) { + mEmojiSet = i; + break; + } + } + //Log.d(TAG, String.format("probRand %d", r)); + if (mEmojiSet < 0) { + Log.e(TAG, String.format("unexpected mEmojiSet %d", mEmojiSet)); + mEmojiSet = (int) (Math.random() * EMOJI_SETS.length); + } } final String[] emojiSet = EMOJI_SETS[mEmojiSet]; Log.i(TAG, "chooseEmojiSet: " + mEmojiSet); diff --git a/app/src/main/java/cc/jerryxiao/easterscrsaver/SettingsActivity.java b/app/src/main/java/cc/jerryxiao/easterscrsaver/SettingsActivity.java new file mode 100644 index 0000000..56074b2 --- /dev/null +++ b/app/src/main/java/cc/jerryxiao/easterscrsaver/SettingsActivity.java @@ -0,0 +1,102 @@ +package cc.jerryxiao.easterscrsaver; + +import android.annotation.SuppressLint; +import android.content.pm.PackageManager; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.preference.ListPreference; +import androidx.preference.PreferenceCategory; +import androidx.preference.PreferenceFragmentCompat; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +public class SettingsActivity extends AppCompatActivity { + private static String TAG = "EasterDream"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.settings_activity); + if (savedInstanceState == null) { + getSupportFragmentManager() + .beginTransaction() + .replace(R.id.settings, new SettingsFragment()) + .commit(); + } + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.setDisplayHomeAsUpEnabled(true); + } + + Map permissionsToRequest = new HashMap<>(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + permissionsToRequest.putAll(Map.of("android.permission.READ_EXTERNAL_STORAGE", + getString(R.string.permission_denied_read_external_storage))); + Iterator> it = permissionsToRequest.entrySet().iterator(); + if (it.hasNext()) { + if (checkSelfPermission(it.next().getKey()) == PackageManager.PERMISSION_GRANTED) { + it.remove(); + } + } + } + if (!permissionsToRequest.isEmpty()) { + Log.d(TAG, String.format("requesting permissions %s", String.join(" + ", permissionsToRequest.keySet().toArray(new String[0])))); + ActivityResultLauncher permissionReq = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), (result) -> { + for (var res : result.entrySet()) { + var perm = res.getKey(); + var granted = res.getValue(); + if (!granted) { + Log.d(TAG, String.format("permission denied: %s", perm)); + (new AlertDialog.Builder(this)) + .setTitle(getText(R.string.error_title)) + .setMessage(permissionsToRequest.get(perm)) + .setCancelable(false) + .setPositiveButton(getString(R.string.button_ok), (dialog, id) -> { + }) + .create() + .show(); + } + } + }); + permissionReq.launch(permissionsToRequest.keySet().toArray(new String[0])); + } + } + + @Override + public boolean onSupportNavigateUp() { + onBackPressed(); + return true; + } + + public static class SettingsFragment extends PreferenceFragmentCompat { + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.preferences, rootKey); + PreferenceCategory category = (PreferenceCategory)getPreferenceScreen().getPreference(0); + int index = 0; + for (String[] emojis : EasterDream.EMOJI_SETS) { + var listPreference = new ListPreference(getPreferenceScreen().getContext()); + @SuppressLint("DefaultLocale") + String k = String.format("prob_%d", index); + listPreference.setKey(k); + listPreference.setDefaultValue("1"); + listPreference.setEntries(R.array.probability_entries_values); + listPreference.setEntryValues(R.array.probability_entries_values); + listPreference.setSummaryProvider(ListPreference.SimpleSummaryProvider.getInstance()); + listPreference.setTitle(getString(R.string.prob_fmt, String.join("", Arrays.copyOfRange(emojis, 0, Math.min(emojis.length, 5))))); + category.addPreference(listPreference); + index++; + } + } + } +} diff --git a/app/src/main/res/layout/settings_activity.xml b/app/src/main/res/layout/settings_activity.xml new file mode 100644 index 0000000..de6591a --- /dev/null +++ b/app/src/main/res/layout/settings_activity.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml new file mode 100644 index 0000000..18441be --- /dev/null +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -0,0 +1,12 @@ + + + EasterScrSaver + ่ฎพ็ฝฎ + ๅฑไฟ + ๅ…่ฎธ้™ไฝŽไบฎๅบฆ + ๆข้กตๆ—ถ้—ด + %1$s ็š„ๅ‡บ็Žฐ้ข‘็Ž‡ + ่ฏปๅ–ๅญ˜ๅ‚จ็ฉบ้—ดๆƒ้™่ขซๆ‹’็ป๏ผŒๅฃ็บธๅฐ†ไธไผšๆ˜พ็คบ + ้”™่ฏฏ + ๅฅฝ + \ No newline at end of file diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml new file mode 100644 index 0000000..6149d20 --- /dev/null +++ b/app/src/main/res/values/arrays.xml @@ -0,0 +1,35 @@ + + + + 3600 + 300 + 60 + 30 + 10 + 5 + + + 3600 + 300 + 60 + 30 + 10 + 5 + + + 100 + 50 + 20 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 0 + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5d52f52..113d1f5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,11 @@ EasterScrSaver - \ No newline at end of file + Settings + Daydream + Screen Dimming + Switching time + Occur freq of %1$s + Storage read permission denied, wallpaper can\'t be shown + Error occurred + OK + diff --git a/app/src/main/res/xml/easterdream.xml b/app/src/main/res/xml/easterdream.xml new file mode 100644 index 0000000..628551e --- /dev/null +++ b/app/src/main/res/xml/easterdream.xml @@ -0,0 +1,2 @@ + diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml new file mode 100644 index 0000000..14ba8a1 --- /dev/null +++ b/app/src/main/res/xml/preferences.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 2893c5f..6e1234b 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - id 'com.android.application' version '8.0.2' apply false - id 'com.android.library' version '8.0.2' apply false + id 'com.android.application' version '8.1.0' apply false + id 'com.android.library' version '8.1.0' apply false id 'org.jetbrains.kotlin.android' version '1.9.0' apply false } \ No newline at end of file