diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..a55e7a1 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index f9f547c..96ae638 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -10,8 +10,8 @@ android { applicationId "com.denizd.substitutionplan" minSdkVersion 21 targetSdkVersion 28 - versionCode 28 - versionName "2.2.5" + versionCode 29 + versionName "2.2.6" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f29991b..b89614a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,6 +6,8 @@ + + , onClickListener: OnClickListener) : RecyclerView.Adapter() { + + val _onClickListener = onClickListener + + class RingtoneViewHolder(view: View, clickListener: OnClickListener) : RecyclerView.ViewHolder(view), View.OnClickListener { + val name: TextView = view.findViewById(R.id.item_text) + val uri: TextView = view.findViewById(R.id.item_text_no_lang) + val cardView: MaterialCardView = view.findViewById(R.id.cardView) + val _clickListener = clickListener + init { view.setOnClickListener(this) } + + override fun onClick(v: View?) { _clickListener.onRingtoneClick(adapterPosition, name.text.toString(), uri.text.toString()) } + + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RingtoneViewHolder { + val v = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false) + return RingtoneViewHolder(v, _onClickListener) + } + + override fun onBindViewHolder(holder: RingtoneViewHolder, position: Int) { + val currentItem = _ringtones[position] + + holder.name.text = currentItem.name + holder.uri.text = currentItem.uri + holder.cardView.setCardBackgroundColor(ContextCompat.getColor(holder.cardView.context, R.color.colorBackground)) + } + + override fun getItemCount(): Int = _ringtones.size + + fun setRingtones(ringtones: List) { + _ringtones = ringtones + notifyDataSetChanged() + } + + public interface OnClickListener { + fun onRingtoneClick(position: Int, name: String, uri: String) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/denizd/substitutionplan/SettingsFragment.kt b/app/src/main/java/com/denizd/substitutionplan/SettingsFragment.kt index e968a59..af3c498 100644 --- a/app/src/main/java/com/denizd/substitutionplan/SettingsFragment.kt +++ b/app/src/main/java/com/denizd/substitutionplan/SettingsFragment.kt @@ -4,10 +4,13 @@ import android.content.ActivityNotFoundException import android.content.Context import android.content.Intent import android.content.SharedPreferences +import android.database.Cursor +import android.media.RingtoneManager import android.net.Uri import android.os.Build import android.os.Bundle import android.preference.PreferenceManager +import android.provider.Settings import android.text.Editable import android.text.TextWatcher import android.view.LayoutInflater @@ -28,7 +31,8 @@ import com.google.firebase.messaging.FirebaseMessaging import com.jaredrummler.android.device.DeviceName import kotlin.collections.ArrayList -class SettingsFragment : Fragment(R.layout.content_settings), View.OnClickListener, CompoundButton.OnCheckedChangeListener, ColourAdapter.OnClickListener { +class SettingsFragment : Fragment(R.layout.content_settings), View.OnClickListener, + CompoundButton.OnCheckedChangeListener, ColourAdapter.OnClickListener, RingtoneAdapter.OnClickListener { private var name = "" private var model = "" @@ -41,6 +45,8 @@ class SettingsFragment : Fragment(R.layout.content_settings), View.OnClickListen private var cs: Int = 7 private var window: Window? = null private lateinit var colourRecycler: RecyclerView + private lateinit var ringtoneCustomiserDialog: AlertDialog + private lateinit var currentRingtone: TextView override fun onAttach(context: Context) { super.onAttach(context) @@ -68,6 +74,8 @@ class SettingsFragment : Fragment(R.layout.content_settings), View.OnClickListen val helpClasses = view.findViewById(R.id.chipHelpClasses) val btnCustomiseColours = view.findViewById(R.id.btnCustomiseColours) val btnVersion = view.findViewById(R.id.btnVersion) + currentRingtone = view.findViewById(R.id.txtCustomiseRingtone2) + setRingtoneText() switchDisableGreeting.setOnCheckedChangeListener(this) switchDark.setOnCheckedChangeListener(this) @@ -77,6 +85,7 @@ class SettingsFragment : Fragment(R.layout.content_settings), View.OnClickListen helpCourses.setOnClickListener(this) helpClasses.setOnClickListener(this) btnCustomiseColours.setOnClickListener(this) + view.findViewById(R.id.btnCustomiseRingtone).setOnClickListener(this) view.findViewById(R.id.btnWebsite).setOnClickListener(this) view.findViewById(R.id.btnLicences).setOnClickListener(this) view.findViewById(R.id.btnTerms).setOnClickListener(this) @@ -132,6 +141,7 @@ class SettingsFragment : Fragment(R.layout.content_settings), View.OnClickListen R.id.chipHelpCourses -> createDialog(getString(R.string.enterCoursesHelpTitle), getString(R.string.enterCoursesHelp)) R.id.chipHelpClasses -> createDialog(getString(R.string.enterGradeHelpTitle), getString(R.string.enterGradeHelp)) R.id.btnCustomiseColours -> createColourDialog() + R.id.btnCustomiseRingtone -> createRingtoneDialog() R.id.btnWebsite -> { try { customTabsIntent.launchUrl(mContext, Uri.parse("http://307.joomla.schule.bremen.de")) @@ -301,6 +311,73 @@ class SettingsFragment : Fragment(R.layout.content_settings), View.OnClickListen return colours } + private fun createRingtoneDialog() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS).apply { + putExtra(Settings.EXTRA_APP_PACKAGE, mContext.applicationContext.packageName) + putExtra(Settings.EXTRA_CHANNEL_ID, "general") + } + startActivity(intent) + } else { + val ringtoneCustomiserBuilder = AlertDialog.Builder(mContext, R.style.AlertDialog) + + val dialogView = LayoutInflater.from(mContext).inflate(R.layout.recycler_dialog, null) + val titleText = dialogView.findViewById(R.id.empty_textviewtitle) + titleText.text = getString(R.string.pickRingtone) + + val recycler = dialogView.findViewById(R.id.recyclerView) + recycler.apply { + hasFixedSize() + layoutManager = GridLayoutManager(mContext, 1) + } + + ringtoneCustomiserDialog = ringtoneCustomiserBuilder.setView(dialogView).create() + ringtoneCustomiserDialog.show() + + recycler.postDelayed({ + val ringtones = getRingtones().toList() + recycler.adapter = RingtoneAdapter(ringtones, this) + }, 100) + } + } + + private fun getRingtones(): ArrayList { + lateinit var _cursor: Cursor + val ringtoneManager = RingtoneManager(activity).apply { + setType(RingtoneManager.TYPE_NOTIFICATION) + _cursor = cursor + } + val alarms = ArrayList() + + while (!_cursor.isAfterLast && _cursor.moveToNext()) { + val position = _cursor.position + alarms.add(Ringtone(ringtoneManager.getRingtone(position).getTitle(mContext), ringtoneManager.getRingtoneUri(position).toString())) + } + return alarms + } + + override fun onRingtoneClick(position: Int, name: String, uri: String) { + prefs.edit().apply { + putString("ringtoneName", name) + putString("ringtoneUri", uri) + }.apply() + setRingtoneText() + ringtoneCustomiserDialog.dismiss() + } + + private fun setRingtoneText() { + currentRingtone.text = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + mContext.getString(R.string.deviceSettingsRedirect) + } else { + val tone = if ((prefs.getString("ringtoneName", "") ?: "").isNotEmpty()) { + prefs.getString("ringtoneName", "") + } else { + mContext.getString(R.string.defaultRingtone) + } + mContext.getString(R.string.setRingtone2, tone) + } + } + override fun onClick(position: Int, title: String, titleNoLang: String) { val colourPickerBuilder = AlertDialog.Builder(mContext, R.style.AlertDialog) val pickerDialogView = LayoutInflater.from(mContext).inflate(R.layout.empty_dialog, null) @@ -338,7 +415,6 @@ class SettingsFragment : Fragment(R.layout.content_settings), View.OnClickListen } private fun debugMenu(): Boolean { - DeviceName.with(mContext).request { deviceInfo, _ -> name = deviceInfo.marketName model = deviceInfo.model diff --git a/app/src/main/res/layout/content_settings.xml b/app/src/main/res/layout/content_settings.xml index 36ea807..c6f7312 100644 --- a/app/src/main/res/layout/content_settings.xml +++ b/app/src/main/res/layout/content_settings.xml @@ -162,7 +162,7 @@ android:text="@string/customiseColoursIndividually" android:textColor="@color/colorHint" android:textSize="12sp" - app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintBottom_toTopOf="@+id/txtNotifications" app:layout_constraintStart_toStartOf="@+id/txtCustomiseColours1" app:layout_constraintTop_toBottomOf="@+id/txtCustomiseColours1" /> @@ -176,10 +176,84 @@ android:clickable="true" android:focusable="true" android:orientation="vertical" - app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/txtRestart" /> + app:layout_constraintTop_toBottomOf="@+id/txtRestart" + app:layout_constraintBottom_toTopOf="@+id/txtNotifications"/> + + + + + + + + + + + + @@ -262,14 +336,16 @@ android:layout_height="wrap_content" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" + android:layout_marginBottom="8dp" android:hint="@string/courses" android:importantForAutofill="no" android:textColorHint="@color/colorHint" app:boxStrokeColor="@color/colorAccent" app:boxStrokeWidth="1dp" - app:layout_constraintEnd_toStartOf="@+id/chipHelpCourses" app:layout_constraintStart_toStartOf="@+id/txtLayoutClasses" - app:layout_constraintTop_toBottomOf="@+id/txtLayoutClasses"> + app:layout_constraintTop_toBottomOf="@+id/txtLayoutClasses" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@+id/chipHelpCourses"> - - - - - - diff --git a/app/src/main/res/layout/recycler_dialog.xml b/app/src/main/res/layout/recycler_dialog.xml index 4d18b9d..925d9ee 100644 --- a/app/src/main/res/layout/recycler_dialog.xml +++ b/app/src/main/res/layout/recycler_dialog.xml @@ -25,7 +25,8 @@ android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" - android:scrollbars="vertical"/> + android:scrollbars="vertical" + android:layoutAnimation="@anim/layout_animation_fall_down"/> diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index b750cc8..126af75 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -127,4 +127,11 @@ Hey, %s! Hi %s! + + Benutzerdefinierter Benachrichtungston + Derzeit: %s + Wähle einen Benachrichtigungston + Keine Klingeltöne gefunden + Öffnet Geräteinstellungen + Standard \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7364666..06ca0af 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -141,4 +141,11 @@ Hey, %s! Hi %s! + + Customise notification ringtone + Currently: %s + Pick a notification ringtone + No ringtones found + Redirects to device settings + Default