From b9fd6f12f5730ae252e3cf2f4dbead9789ce1d1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20N=C3=BCsse?= Date: Sat, 6 Jan 2024 23:37:49 +0100 Subject: [PATCH] show profiles in checkup --- .../timedsilence/fragments/CheckupFragment.kt | 42 +++++++++--- .../timedsilence/model/contacts/Contact.kt | 5 +- .../model/contacts/ContactUtil.kt | 64 +++++++++++++----- .../timedsilence/ui/ContactsListAdapter.kt | 67 +++++++++++++++++++ app/src/main/res/drawable/icon_person.xml | 11 +++ .../main/res/layout/adapter_contact_list.xml | 62 +++++++++++++++++ app/src/main/res/layout/fragment_checkup.xml | 13 +++- app/src/main/res/values/strings.xml | 1 + 8 files changed, 237 insertions(+), 28 deletions(-) create mode 100644 app/src/main/java/de/felixnuesse/timedsilence/ui/ContactsListAdapter.kt create mode 100644 app/src/main/res/drawable/icon_person.xml create mode 100644 app/src/main/res/layout/adapter_contact_list.xml diff --git a/app/src/main/java/de/felixnuesse/timedsilence/fragments/CheckupFragment.kt b/app/src/main/java/de/felixnuesse/timedsilence/fragments/CheckupFragment.kt index 8c7dba3..2f2ff09 100644 --- a/app/src/main/java/de/felixnuesse/timedsilence/fragments/CheckupFragment.kt +++ b/app/src/main/java/de/felixnuesse/timedsilence/fragments/CheckupFragment.kt @@ -23,22 +23,26 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment +import androidx.recyclerview.widget.RecyclerView import de.felixnuesse.timedsilence.databinding.FragmentCheckupBinding -import de.felixnuesse.timedsilence.extensions.e import de.felixnuesse.timedsilence.model.contacts.Contact import de.felixnuesse.timedsilence.model.contacts.ContactUtil +import de.felixnuesse.timedsilence.ui.ContactsListAdapter +import de.felixnuesse.timedsilence.ui.custom.NestedRecyclerManager import de.felixnuesse.timedsilence.util.PermissionManager class CheckupFragment : Fragment() { - companion object { - private const val TAG = "CheckupFragment" - } + + private lateinit var viewAdapter: RecyclerView.Adapter<*> + private lateinit var viewManager: RecyclerView.LayoutManager private var _binding: FragmentCheckupBinding? = null private val binding get() = _binding!! + private var showContacts = false + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -54,6 +58,12 @@ class CheckupFragment : Fragment() { binding.gotoDND.setOnClickListener { startActivity(Intent("android.settings.ZEN_MODE_SETTINGS")) } + + binding.contactsShowButton.setOnClickListener { + binding.contactsListView.visibility = View.VISIBLE + binding.contactsShowButton.visibility = View.GONE + showContacts = true + } } override fun onDestroyView() { @@ -69,14 +79,18 @@ class CheckupFragment : Fragment() { private fun updateData() { val context = binding.root.context - var l = arrayListOf() + var contactsList = arrayListOf() + if(showContacts) { + binding.contactsListView.visibility = View.VISIBLE + binding.contactsShowButton.visibility = View.GONE + } var permissionManager = PermissionManager(context) if(permissionManager.grantedContacts()) { binding.CheckupContentContainer.visibility = View.VISIBLE binding.CheckupPermissionCheckContainer.visibility = View.GONE - l = ContactUtil(context).getContactList() + contactsList = ContactUtil(context).getContactList() } else{ binding.CheckupContentContainer.visibility = View.GONE binding.buttonRequestContactPermissions.setOnClickListener{ @@ -90,8 +104,6 @@ class CheckupFragment : Fragment() { } else { mNotificationManager?.notificationPolicy } - - /* The following is the current (api 33) list of available categories: @@ -153,8 +165,11 @@ class CheckupFragment : Fragment() { 1 } + if(contactsList.size == 0) { + binding.contactsShowButton.visibility = View.GONE + } - binding.checkboxHavePriorityContacts.isChecked = l.size > 0 + binding.checkboxHavePriorityContacts.isChecked = contactsList.size > 0 binding.checkboxPriorityContactsCanBypass.isChecked = priorityCaller != 0 binding.checkboxRepeatCallerCanBypass.isChecked = repeatCaller != 0 binding.checkboxRepeatMessengerCanBypass.isChecked = repeatMessenger != 0 @@ -162,6 +177,15 @@ class CheckupFragment : Fragment() { binding.checkboxAlarmsCanBypass.isChecked = alarms != 0 binding.checkboxNotificationsVisible.isChecked = !areAllVisualEffectsSuppressed(suppressedVisuals) + viewManager = NestedRecyclerManager(context) + viewAdapter = ContactsListAdapter(contactsList) + + binding.contactsListView.apply { + setHasFixedSize(true) + layoutManager = viewManager + adapter = viewAdapter + } + } /** diff --git a/app/src/main/java/de/felixnuesse/timedsilence/model/contacts/Contact.kt b/app/src/main/java/de/felixnuesse/timedsilence/model/contacts/Contact.kt index eb7832f..d1f66dd 100644 --- a/app/src/main/java/de/felixnuesse/timedsilence/model/contacts/Contact.kt +++ b/app/src/main/java/de/felixnuesse/timedsilence/model/contacts/Contact.kt @@ -1,6 +1,7 @@ package de.felixnuesse.timedsilence.model.contacts -class Contact(var name: String) { - +import android.graphics.Bitmap +class Contact(var name: String) { + var photo: Bitmap? = null } \ No newline at end of file diff --git a/app/src/main/java/de/felixnuesse/timedsilence/model/contacts/ContactUtil.kt b/app/src/main/java/de/felixnuesse/timedsilence/model/contacts/ContactUtil.kt index cc5dd02..5ef501a 100644 --- a/app/src/main/java/de/felixnuesse/timedsilence/model/contacts/ContactUtil.kt +++ b/app/src/main/java/de/felixnuesse/timedsilence/model/contacts/ContactUtil.kt @@ -1,10 +1,15 @@ package de.felixnuesse.timedsilence.model.contacts -import android.content.ContentResolver +import android.content.ContentUris import android.content.Context +import android.database.Cursor +import android.graphics.Bitmap +import android.graphics.BitmapFactory import android.provider.ContactsContract +import de.felixnuesse.timedsilence.R import de.felixnuesse.timedsilence.extensions.e import de.felixnuesse.timedsilence.util.PermissionManager +import java.io.IOException class ContactUtil(private var mContext: Context) { @@ -15,9 +20,10 @@ class ContactUtil(private var mContext: Context) { private val PROJECTION = arrayOf( - ContactsContract.CommonDataKinds.Phone.CONTACT_ID, + ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME, - ContactsContract.Contacts.STARRED + ContactsContract.Contacts.STARRED, + ContactsContract.Contacts.PHOTO_URI ) fun getContactList(): ArrayList { @@ -28,24 +34,50 @@ class ContactUtil(private var mContext: Context) { return contactList } - val cr: ContentResolver = mContext.contentResolver - val cursor = cr.query( - ContactsContract.CommonDataKinds.Phone.CONTENT_URI, - PROJECTION, - null, - null, - ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC" - ) - cursor?.use { cursor -> + + getQuery()?.use { cursor -> val nameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME) - val starredIndex = cursor.getColumnIndex(ContactsContract.Contacts.STARRED) + val photoIndex = cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_URI) + val idIndex = cursor.getColumnIndex(ContactsContract.Contacts._ID) + while (cursor.moveToNext()) { - if(cursor.getInt(starredIndex) == 1) { - contactList.add(Contact(cursor.getString(nameIndex))) - } + var c = Contact(cursor.getString(nameIndex)) + c.photo = getPhoto(cursor.getLong(idIndex)) + contactList.add(c) } + } return contactList } + private fun getQuery(): Cursor? { + return mContext.contentResolver.query( + ContactsContract.Contacts.CONTENT_URI, + PROJECTION, + ContactsContract.Contacts.STARRED + " = ?", + arrayOf("1"), + ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC" + ) + } + + private fun getPhoto(id: Long): Bitmap { + var photo = BitmapFactory.decodeResource(mContext.resources, R.drawable.icon_person) + + val uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, id) + + try { + val inputStream = ContactsContract.Contacts.openContactPhotoInputStream( + mContext.contentResolver, + uri + ) + if (inputStream != null) { + photo = BitmapFactory.decodeStream(inputStream) + } + inputStream?.close() + } catch (e: IOException) { + e.printStackTrace() + } + return photo + } + } \ No newline at end of file diff --git a/app/src/main/java/de/felixnuesse/timedsilence/ui/ContactsListAdapter.kt b/app/src/main/java/de/felixnuesse/timedsilence/ui/ContactsListAdapter.kt new file mode 100644 index 0000000..d8f9918 --- /dev/null +++ b/app/src/main/java/de/felixnuesse/timedsilence/ui/ContactsListAdapter.kt @@ -0,0 +1,67 @@ +package de.felixnuesse.timedsilence.ui; + +import androidx.recyclerview.widget.RecyclerView +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.appcompat.content.res.AppCompatResources +import de.felixnuesse.timedsilence.handler.volume.VolumeState.Companion.TIME_SETTING_LOUD +import de.felixnuesse.timedsilence.handler.volume.VolumeState.Companion.TIME_SETTING_SILENT +import de.felixnuesse.timedsilence.handler.volume.VolumeState.Companion.TIME_SETTING_VIBRATE +import de.felixnuesse.timedsilence.Constants.Companion.WIFI_TYPE_CONNECTED +import de.felixnuesse.timedsilence.Constants.Companion.WIFI_TYPE_SEARCHING +import de.felixnuesse.timedsilence.R +import de.felixnuesse.timedsilence.databinding.AdapterContactListBinding +import de.felixnuesse.timedsilence.databinding.AdapterWifiListBinding +import de.felixnuesse.timedsilence.model.contacts.Contact +import de.felixnuesse.timedsilence.model.data.WifiObject +import de.felixnuesse.timedsilence.model.database.DatabaseHandler +import kotlin.collections.ArrayList + + +/** + * Copyright (C) 2024 Felix Nüsse + * Created on 06.01.24 - 21:53 + *

+ * Edited by: Felix Nüsse felix.nuesse(at)t-online.de + *

+ *

+ * This program is released under the GPLv3 license + *

+ *

+ * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *

+ * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +class ContactsListAdapter(private val myDataset: ArrayList): RecyclerView.Adapter() { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ContactViewHolder { + val binding = AdapterContactListBinding.inflate(LayoutInflater.from(parent.context), parent, false) + return ContactViewHolder(binding) + } + + override fun onBindViewHolder(holder: ContactViewHolder, position: Int) { + val context = holder.contactView.root.context + var contact = myDataset[position] + holder.contactView.name.text = contact.name + holder.contactView.profile.setImageBitmap(contact.photo) + + } + + override fun getItemCount() = myDataset.size + + class ContactViewHolder(val contactView: AdapterContactListBinding) : + RecyclerView.ViewHolder(contactView.root) + +} + + diff --git a/app/src/main/res/drawable/icon_person.xml b/app/src/main/res/drawable/icon_person.xml new file mode 100644 index 0000000..34f96a0 --- /dev/null +++ b/app/src/main/res/drawable/icon_person.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/app/src/main/res/layout/adapter_contact_list.xml b/app/src/main/res/layout/adapter_contact_list.xml new file mode 100644 index 0000000..16425e2 --- /dev/null +++ b/app/src/main/res/layout/adapter_contact_list.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_checkup.xml b/app/src/main/res/layout/fragment_checkup.xml index 7ae9124..bcd0e4e 100644 --- a/app/src/main/res/layout/fragment_checkup.xml +++ b/app/src/main/res/layout/fragment_checkup.xml @@ -68,7 +68,6 @@ app:layout_constraintTop_toTopOf="parent" /> +