From 82afb03c0f27407c2ca14541d12ec930a568bed5 Mon Sep 17 00:00:00 2001 From: Phillip Hsu Date: Tue, 20 Sep 2016 19:43:05 -0700 Subject: [PATCH] Create ThemedRingtonePreference and use in settings --- .../RingtonePickerDialogController.java | 36 +++ .../settings/ThemedRingtonePreference.java | 263 ++++++++++++++++++ app/src/main/res/xml/preferences.xml | 2 +- 3 files changed, 300 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/com/philliphsu/clock2/settings/RingtonePickerDialogController.java create mode 100644 app/src/main/java/com/philliphsu/clock2/settings/ThemedRingtonePreference.java diff --git a/app/src/main/java/com/philliphsu/clock2/settings/RingtonePickerDialogController.java b/app/src/main/java/com/philliphsu/clock2/settings/RingtonePickerDialogController.java new file mode 100644 index 0000000..c03ce40 --- /dev/null +++ b/app/src/main/java/com/philliphsu/clock2/settings/RingtonePickerDialogController.java @@ -0,0 +1,36 @@ +package com.philliphsu.clock2.settings; + +import android.net.Uri; +import android.support.v4.app.FragmentManager; +import android.util.Log; + +import com.philliphsu.clock2.DialogFragmentController; +import com.philliphsu.clock2.RingtonePickerDialog; + +/** + * Created by Phillip Hsu on 9/20/2016. + */ +public class RingtonePickerDialogController extends DialogFragmentController { + private static final String TAG = "RingtonePickerCtrller"; + + private final RingtonePickerDialog.OnRingtoneSelectedListener mListener; + + public RingtonePickerDialogController(FragmentManager fragmentManager, RingtonePickerDialog.OnRingtoneSelectedListener l) { + super(fragmentManager); + mListener = l; + } + + public void show(Uri initialUri, String tag) { + RingtonePickerDialog dialog = RingtonePickerDialog.newInstance(mListener, initialUri); + show(dialog, tag); + } + + @Override + public void tryRestoreCallback(String tag) { + RingtonePickerDialog dialog = findDialog(tag); + if (dialog != null) { + Log.i(TAG, "Restoring on ringtone selected callback"); + dialog.setOnRingtoneSelectedListener(mListener); + } + } +} diff --git a/app/src/main/java/com/philliphsu/clock2/settings/ThemedRingtonePreference.java b/app/src/main/java/com/philliphsu/clock2/settings/ThemedRingtonePreference.java new file mode 100644 index 0000000..46aa4f8 --- /dev/null +++ b/app/src/main/java/com/philliphsu/clock2/settings/ThemedRingtonePreference.java @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.philliphsu.clock2.settings; + +import android.annotation.TargetApi; +import android.content.Context; +import android.content.Intent; +import android.content.res.TypedArray; +import android.media.RingtoneManager; +import android.net.Uri; +import android.os.Parcelable; +import android.preference.Preference; +import android.preference.PreferenceManager; +import android.support.v7.app.AppCompatActivity; +import android.text.TextUtils; +import android.util.AttributeSet; + +import com.philliphsu.clock2.RingtonePickerDialog; + +/** + * Created by Phillip Hsu on 9/20/2016. + * + *

A modified version of the framework's {@link android.preference.RingtonePreference} that + * uses our {@link RingtonePickerDialog} instead of the system's ringtone picker.

Because + * of this difference, we cannot just extend from RingtonePreference and make + * our modifications. + */ +public class ThemedRingtonePreference extends Preference implements RingtonePickerDialog.OnRingtoneSelectedListener { + + private static final String TAG = "ThemedRingtonePreference"; + + private int mRingtoneType; + private boolean mShowDefault; + private boolean mShowSilent; + + private int mRequestCode; + + private RingtonePickerDialogController mController; + + @TargetApi(21) + public ThemedRingtonePreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + public ThemedRingtonePreference(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + public ThemedRingtonePreference(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public ThemedRingtonePreference(Context context) { + super(context); + } + + /** + * Returns the sound type(s) that are shown in the picker. + * + * @return The sound type(s) that are shown in the picker. + * @see #setRingtoneType(int) + */ + public int getRingtoneType() { + return mRingtoneType; + } + + /** + * Sets the sound type(s) that are shown in the picker. + * + * @param type The sound type(s) that are shown in the picker. + * @see RingtoneManager#EXTRA_RINGTONE_TYPE + */ + public void setRingtoneType(int type) { + mRingtoneType = type; + } + + /** + * Returns whether to a show an item for the default sound/ringtone. + * + * @return Whether to show an item for the default sound/ringtone. + */ + public boolean getShowDefault() { + return mShowDefault; + } + + /** + * Sets whether to show an item for the default sound/ringtone. The default + * to use will be deduced from the sound type(s) being shown. + * + * @param showDefault Whether to show the default or not. + * @see RingtoneManager#EXTRA_RINGTONE_SHOW_DEFAULT + */ + public void setShowDefault(boolean showDefault) { + mShowDefault = showDefault; + } + + /** + * Returns whether to a show an item for 'Silent'. + * + * @return Whether to show an item for 'Silent'. + */ + public boolean getShowSilent() { + return mShowSilent; + } + + /** + * Sets whether to show an item for 'Silent'. + * + * @param showSilent Whether to show 'Silent'. + * @see RingtoneManager#EXTRA_RINGTONE_SHOW_SILENT + */ + public void setShowSilent(boolean showSilent) { + mShowSilent = showSilent; + } + + @Override + protected void onClick() { + // Launch the ringtone picker + if (mController == null) { + mController = newController(); + } + mController.show(onRestoreRingtone(), TAG); + } + + @Override + protected void onRestoreInstanceState(Parcelable state) { + super.onRestoreInstanceState(state); + if (mController == null) { + mController = newController(); + } + mController.tryRestoreCallback(TAG); + } + + private RingtonePickerDialogController newController() { + // TODO: BAD! + AppCompatActivity a = (AppCompatActivity) getContext(); + return new RingtonePickerDialogController(a.getSupportFragmentManager(), this); + } + + /** + * Prepares the intent to launch the ringtone picker. This can be modified + * to adjust the parameters of the ringtone picker. + * + * @param ringtonePickerIntent The ringtone picker intent that can be + * modified by putting extras. + */ + protected void onPrepareRingtonePickerIntent(Intent ringtonePickerIntent) { + + ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, + onRestoreRingtone()); + + ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, mShowDefault); + if (mShowDefault) { + ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI, + RingtoneManager.getDefaultUri(getRingtoneType())); + } + + ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, mShowSilent); + ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, mRingtoneType); + ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, getTitle()); +// ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_AUDIO_ATTRIBUTES_FLAGS, +// AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY); + } + + /** + * Called when a ringtone is chosen. + *

+ * By default, this saves the ringtone URI to the persistent storage as a + * string. + * + * @param ringtoneUri The chosen ringtone's {@link Uri}. Can be null. + */ + protected void onSaveRingtone(Uri ringtoneUri) { + persistString(ringtoneUri != null ? ringtoneUri.toString() : ""); + } + + /** + * Called when the chooser is about to be shown and the current ringtone + * should be marked. Can return null to not mark any ringtone. + *

+ * By default, this restores the previous ringtone URI from the persistent + * storage. + * + * @return The ringtone to be marked as the current ringtone. + */ + protected Uri onRestoreRingtone() { + final String uriString = getPersistedString(null); + return !TextUtils.isEmpty(uriString) ? Uri.parse(uriString) : null; + } + + @Override + protected Object onGetDefaultValue(TypedArray a, int index) { + return a.getString(index); + } + + @Override + protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValueObj) { + String defaultValue = (String) defaultValueObj; + + /* + * This method is normally to make sure the internal state and UI + * matches either the persisted value or the default value. Since we + * don't show the current value in the UI (until the dialog is opened) + * and we don't keep local state, if we are restoring the persisted + * value we don't need to do anything. + */ + if (restorePersistedValue) { + return; + } + + // If we are setting to the default value, we should persist it. + if (!TextUtils.isEmpty(defaultValue)) { + onSaveRingtone(Uri.parse(defaultValue)); + } + } + + @Override + protected void onAttachedToHierarchy(PreferenceManager preferenceManager) { + super.onAttachedToHierarchy(preferenceManager); + +// preferenceManager.registerOnActivityResultListener(this); +// mRequestCode = preferenceManager.getNextRequestCode(); + } + + public boolean onActivityResult(int requestCode, int resultCode, Intent data) { + + if (requestCode == mRequestCode) { + + if (data != null) { + Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI); + + if (callChangeListener(uri != null ? uri.toString() : "")) { + onSaveRingtone(uri); + } + } + + return true; + } + + return false; + } + + @Override + public void onRingtoneSelected(Uri uri) { + if (callChangeListener(uri != null ? uri.toString() : "")) { + onSaveRingtone(uri); + } + } +} diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 9df8703..156ba6f 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -72,7 +72,7 @@ android:summary="%s"/> -