Skip to content

Commit

Permalink
[feat]current connections in HistoryActivity
Browse files Browse the repository at this point in the history
  • Loading branch information
Steve-Mr committed Jun 1, 2023
1 parent f4e3c56 commit b07c0f6
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 29 deletions.
69 changes: 53 additions & 16 deletions app/src/main/java/com/maary/liveinpeace/ConnectionListAdapter.kt
Original file line number Diff line number Diff line change
@@ -1,58 +1,88 @@
package com.maary.liveinpeace

import android.annotation.SuppressLint
import android.content.Context
import android.content.res.ColorStateList
import android.media.AudioDeviceInfo
import android.media.Image
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.maary.liveinpeace.database.Connection
import java.util.concurrent.TimeUnit
import kotlin.coroutines.coroutineContext

class ConnectionListAdapter : ListAdapter<Connection, ConnectionListAdapter.ConnectionViewHolder>(ConnectionsComparator()){

private var currentItemLayout = R.layout.item_connection

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ConnectionViewHolder {
return ConnectionViewHolder.create(parent)
return ConnectionViewHolder.create(parent, currentItemLayout)
}

override fun onBindViewHolder(holder: ConnectionViewHolder, position: Int) {
val current = getItem(position)
holder.bind( current.name, current.type, current.duration)
holder.bind( current.name, current.type, current.duration, current.disconnectedTime)
}

class ConnectionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val connectionIconView: ImageView = itemView.findViewById(R.id.device_icon)
private val connectionDeviceNameView: TextView = itemView.findViewById(R.id.device_name)
private val connectionDurationView: TextView = itemView.findViewById(R.id.device_connection_time)
private val connectionIndicatorView: ImageView = itemView.findViewById(R.id.connection_time_prefix)

fun bind(deviceName: String?, type: Int?,duration: Long?) {
if (type in listOf(
AudioDeviceInfo.TYPE_BLE_BROADCAST,
AudioDeviceInfo.TYPE_BLE_HEADSET,
AudioDeviceInfo.TYPE_BLE_SPEAKER,
AudioDeviceInfo.TYPE_BLUETOOTH_A2DP,
AudioDeviceInfo.TYPE_BLUETOOTH_SCO
)){
connectionIconView.setImageResource(R.drawable.ic_bluetooth_round)
} else {
connectionIconView.setImageResource(R.drawable.ic_headphone_round)
}
fun bind(deviceName: String?, type: Int?, duration: Long?, disconnectedTime: Long?) {
connectionIconView.setImageResource(
chooseDeviceDrawable(
type = type,
drawableHeadphone = R.drawable.ic_headphone_round,
drawableBLE = R.drawable.ic_bluetooth_round))
connectionDeviceNameView.text = deviceName
connectionDurationView.text = duration?.let { formatMilliseconds(itemView.context, it) }

if (disconnectedTime == null){
// Get the desired tint color from resources
val tintColor = itemView.context.getColor(android.R.color.holo_green_light)

// Create a ColorStateList with the desired tint color
val colorStateList = ColorStateList.valueOf(tintColor)
connectionIndicatorView.imageTintList = colorStateList
connectionIconView.setImageResource(
chooseDeviceDrawable(
type = type,
drawableHeadphone = R.drawable.ic_headphone_round_alt,
drawableBLE = R.drawable.ic_bluetooth_round_alt))
}
}

companion object {
fun create(parent: ViewGroup): ConnectionViewHolder {
fun create(parent: ViewGroup, layoutId: Int): ConnectionViewHolder {
val view: View = LayoutInflater.from(parent.context)
.inflate(R.layout.item_connection, parent, false)
.inflate(layoutId, parent, false)
return ConnectionViewHolder(view)
}
}

private fun chooseDeviceDrawable(type: Int?, drawableHeadphone: Int, drawableBLE: Int): Int{
return if (type in listOf(
AudioDeviceInfo.TYPE_BLE_BROADCAST,
AudioDeviceInfo.TYPE_BLE_HEADSET,
AudioDeviceInfo.TYPE_BLE_SPEAKER,
AudioDeviceInfo.TYPE_BLUETOOTH_A2DP,
AudioDeviceInfo.TYPE_BLUETOOTH_SCO
)){
(drawableBLE)
} else {
(drawableHeadphone)
}
}

private fun formatMilliseconds(context: Context, milliseconds: Long): String {
val hours = TimeUnit.MILLISECONDS.toHours(milliseconds)
val minutes = TimeUnit.MILLISECONDS.toMinutes(milliseconds) % 60
Expand All @@ -64,6 +94,13 @@ class ConnectionListAdapter : ListAdapter<Connection, ConnectionListAdapter.Conn
}
}

@SuppressLint("NotifyDataSetChanged")
fun updateItemLayout(newItemLayout: Int) {
currentItemLayout = newItemLayout
notifyDataSetChanged()
}


class ConnectionsComparator : DiffUtil.ItemCallback<Connection>(){
override fun areItemsTheSame(oldItem: Connection, newItem: Connection): Boolean {
return oldItem == newItem
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.maary.liveinpeace

import com.maary.liveinpeace.database.Connection

interface DeviceMapChangeListener {
fun onDeviceMapChanged(deviceMap: Map<String, Connection>)
}
43 changes: 42 additions & 1 deletion app/src/main/java/com/maary/liveinpeace/HistoryActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,48 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.LinearLayoutManager
import com.maary.liveinpeace.database.Connection
import com.maary.liveinpeace.databinding.ActivityHistoryBinding
import com.maary.liveinpeace.service.ForegroundService
import java.time.LocalDate


class HistoryActivity : AppCompatActivity() {
class HistoryActivity : AppCompatActivity(), DeviceMapChangeListener {

private lateinit var binding: ActivityHistoryBinding
private val connectionViewModel: ConnectionViewModel by viewModels {
ConnectionViewModelFactory((application as ConnectionsApplication).repository)
}
private val currentAdapter = ConnectionListAdapter()

override fun onResume() {
super.onResume()
ForegroundService.addDeviceMapChangeListener(this)
}

override fun onPause() {
super.onPause()
ForegroundService.removeDeviceMapChangeListener(this)
}

private fun currentConnectionsDuration(currentList: MutableList<Connection>) : MutableList<Connection>{
val now = System.currentTimeMillis()

for ( (index, connection) in currentList.withIndex()){
val connectedTime = connection.connectedTime
val duration = now - connectedTime!!
currentList[index] = Connection(
name = connection.name,
type = connection.type,
connectedTime = connection.connectedTime,
disconnectedTime = null,
duration = duration,
date = connection.date
)
}

return currentList
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Expand All @@ -33,6 +65,11 @@ class HistoryActivity : AppCompatActivity() {
finish()
}

binding.currentList.adapter = currentAdapter
binding.currentList.layoutManager = LinearLayoutManager(this)

currentAdapter.submitList(currentConnectionsDuration(ForegroundService.getConnections()))

connectionViewModel.getAllConnectionsOnDate(LocalDate.now().toString()).observe(this) { connections ->
connections.let { connectionAdapter.submitList(it) }
}
Expand All @@ -54,4 +91,8 @@ class HistoryActivity : AppCompatActivity() {


}

override fun onDeviceMapChanged(deviceMap: Map<String, Connection>) {
currentAdapter.submitList(currentConnectionsDuration(ForegroundService.getConnections()))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import com.maary.liveinpeace.Constants.Companion.MODE_NUM
import com.maary.liveinpeace.Constants.Companion.PREF_ICON
import com.maary.liveinpeace.Constants.Companion.PREF_WATCHING_CONNECTING_TIME
import com.maary.liveinpeace.Constants.Companion.SHARED_PREF
import com.maary.liveinpeace.DeviceMapChangeListener
import com.maary.liveinpeace.HistoryActivity
import com.maary.liveinpeace.R
import com.maary.liveinpeace.database.Connection
Expand All @@ -58,7 +59,7 @@ class ForegroundService: Service() {
private lateinit var connectionDao: ConnectionDao

private val deviceTimerMap: MutableMap<String, DeviceTimer> = mutableMapOf()
private val deviceMap: MutableMap<String, Connection> = mutableMapOf()
// private val deviceMap: MutableMap<String, Connection> = mutableMapOf()

private val volumeDrawableIds = intArrayOf(
R.drawable.ic_volume_silent,
Expand All @@ -81,6 +82,29 @@ class ForegroundService: Service() {
fun isForegroundServiceRunning(): Boolean {
return isForegroundServiceRunning
}

private val deviceMap: MutableMap<String, Connection> = mutableMapOf()

// 在伴生对象中定义一个静态方法,用于其他类访问deviceMap
fun getConnections(): MutableList<Connection> {
return deviceMap.values.toMutableList()
}

private val deviceMapChangeListeners: MutableList<DeviceMapChangeListener> = mutableListOf()

fun addDeviceMapChangeListener(listener: DeviceMapChangeListener) {
deviceMapChangeListeners.add(listener)
}

fun removeDeviceMapChangeListener(listener: DeviceMapChangeListener) {
deviceMapChangeListeners.remove(listener)
}
}

private fun notifyDeviceMapChange() {
deviceMapChangeListeners.forEach { listener ->
listener.onDeviceMapChanged(deviceMap)
}
}

private fun getVolumePercentage(context: Context): Int {
Expand Down Expand Up @@ -158,6 +182,7 @@ class ForegroundService: Service() {
duration = null,
date = LocalDate.now().toString()
)
notifyDeviceMapChange()
// 执行其他逻辑,比如将设备信息保存到数据库或日志中
}

Expand Down Expand Up @@ -216,6 +241,7 @@ class ForegroundService: Service() {
}

deviceMap.remove(deviceName)
notifyDeviceMapChange()
}

val sharedPreferences = getSharedPreferences(SHARED_PREF, Context.MODE_PRIVATE)
Expand Down
44 changes: 36 additions & 8 deletions app/src/main/res/layout/activity_history.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">

<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
Expand Down Expand Up @@ -68,13 +69,40 @@
android:background="@android:color/transparent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" >

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/history_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:padding="8dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/current_connections"
android:layout_margin="16dp"
android:textStyle="bold"
android:textSize="16sp"/>

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/current_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false"
android:padding="8dp"
tools:listitem="@layout/item_current_connections"
tools:itemCount="2"/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/connections_history"
android:layout_margin="16dp"
android:textStyle="bold"
android:textSize="16sp"/>

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/history_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false"
android:padding="8dp"
tools:listitem="@layout/item_connection"/>

</LinearLayout>

Expand Down
18 changes: 15 additions & 3 deletions app/src/main/res/layout/item_connection.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,30 @@
android:textSize="18sp"
android:textColor="?android:attr/textColorPrimary"
android:layout_marginStart="16dp"
android:textStyle="bold"

tools:text="Headphone"/>

<ImageView
android:id="@+id/connection_time_prefix"
android:layout_width="8dp"
android:layout_height="8dp"
app:layout_constraintTop_toBottomOf="@id/device_name"
app:layout_constraintStart_toEndOf="@id/device_icon"
android:layout_marginStart="16dp"
app:layout_constraintBottom_toBottomOf="parent"
android:src="@drawable/shape_circle"
app:tint="@android:color/darker_gray"
android:contentDescription="@string/device_connection_state" />

<TextView
android:id="@+id/device_connection_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginStart="8dp"
android:textColor="?android:attr/textColorPrimary"
app:layout_constraintTop_toBottomOf="@id/device_name"
app:layout_constraintBottom_toBottomOf="@id/device_icon"
app:layout_constraintStart_toEndOf="@id/device_icon"
app:layout_constraintStart_toEndOf="@id/connection_time_prefix"
android:textSize="12sp"
tools:text="3hrs"/>

Expand Down
4 changes: 4 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
<string name="duration_hour">%02d h %02d min</string>
<string name="enable_watching">Enable alert</string>
<string name="disable_watching">Disable alert</string>
<string name="current_connections">Current Connections</string>
<string name="connections_history">Connections Histroy</string>
<string name="has_already_connected_for">Already connected</string>
<string name="device_connection_state">Device connection state indicator</string>
<string-array name="array_volume_comment">
<item>Shhhhhhh…</item>
<item>Perfectly Balanced, As All Things Should Be…</item>
Expand Down

0 comments on commit b07c0f6

Please sign in to comment.