From 34fc9220f84e378447ae118d79c0f62f49a31b96 Mon Sep 17 00:00:00 2001 From: Juha Heinanen Date: Tue, 18 Jan 2022 17:29:14 +0200 Subject: [PATCH] Added call details activity that can be accessed by touching time in call history list --- app/src/main/AndroidManifest.xml | 6 ++ .../com/tutpro/baresip/CallDetailsActivity.kt | 64 +++++++++++++++ .../com/tutpro/baresip/CallDetailsAdapter.kt | 77 +++++++++++++++++++ .../com/tutpro/baresip/CallListAdapter.kt | 36 ++++++--- .../main/kotlin/com/tutpro/baresip/CallRow.kt | 14 ++-- .../com/tutpro/baresip/CallsActivity.kt | 36 +++------ .../kotlin/com/tutpro/baresip/MainActivity.kt | 10 +++ .../main/kotlin/com/tutpro/baresip/Utils.kt | 19 ++++- .../main/res/layout/activity_call_details.xml | 65 ++++++++++++++++ app/src/main/res/layout/activity_calls.xml | 1 + app/src/main/res/layout/call_detail_row.xml | 30 ++++++++ app/src/main/res/layout/call_row.xml | 12 +-- app/src/main/res/values-fi/strings.xml | 4 + app/src/main/res/values/strings.xml | 5 ++ 14 files changed, 329 insertions(+), 50 deletions(-) create mode 100644 app/src/main/kotlin/com/tutpro/baresip/CallDetailsActivity.kt create mode 100644 app/src/main/kotlin/com/tutpro/baresip/CallDetailsAdapter.kt create mode 100644 app/src/main/res/layout/activity_call_details.xml create mode 100644 app/src/main/res/layout/call_detail_row.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5ed1462e..aa95a673 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -109,6 +109,12 @@ android:label="@string/call_history" android:parentActivityName=".MainActivity" > + + { + onBackPressed() + return true + } + } + + return super.onOptionsItemSelected(item) + } + + override fun onBackPressed() { + BaresipService.activities.remove("call_details,$aor,$peer,$position") + finish() + super.onBackPressed() + } + +} \ No newline at end of file diff --git a/app/src/main/kotlin/com/tutpro/baresip/CallDetailsAdapter.kt b/app/src/main/kotlin/com/tutpro/baresip/CallDetailsAdapter.kt new file mode 100644 index 00000000..37908f10 --- /dev/null +++ b/app/src/main/kotlin/com/tutpro/baresip/CallDetailsAdapter.kt @@ -0,0 +1,77 @@ +package com.tutpro.baresip + +import android.content.Context +import android.text.format.DateUtils +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ArrayAdapter +import android.widget.ImageView +import android.widget.TextView +import java.text.DateFormat + +import java.util.* + +class CallDetailsAdapter(private val ctx: Context, private val rows: ArrayList) : + ArrayAdapter(ctx, R.layout.call_detail_row, rows) { + + private val layoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater + + private class ViewHolder(view: View?) { + val directionView = view?.findViewById(R.id.direction) as ImageView + val timeView = view?.findViewById(R.id.time) as TextView + val durationView = view?.findViewById(R.id.duration) as TextView + } + + override fun getView(position: Int, view: View?, parent: ViewGroup): View { + + val viewHolder: ViewHolder + val rowView: View + + if (view == null) { + rowView = layoutInflater.inflate(R.layout.call_detail_row, parent, false) + viewHolder = ViewHolder(rowView) + rowView.tag = viewHolder + } else { + rowView = view + viewHolder = rowView.tag as ViewHolder + } + + val direction = rows[position].direction + viewHolder.directionView.setImageResource(direction) + + val startTime = rows[position].startTime + val stopTime = rows[position].stopTime + + val stopText = if (DateUtils.isToday(stopTime.timeInMillis)) { + val fmt = DateFormat.getTimeInstance(DateFormat.LONG) + ctx.getString(R.string.today) + " " + fmt.format(stopTime.time) + } else { + val fmt = DateFormat.getDateTimeInstance() + fmt.format(stopTime.time) + } + if (startTime == GregorianCalendar(0, 0, 0)) { + viewHolder.timeView.text = stopText + viewHolder.durationView.text = "?" + } else { + if (startTime == null) { + viewHolder.timeView.text = stopText + viewHolder.durationView.text = "" + } else { + val startText = if (DateUtils.isToday(startTime.timeInMillis)) { + val fmt = DateFormat.getTimeInstance(DateFormat.LONG) + ctx.getString(R.string.today) + " " + fmt.format(startTime.time) + } else { + val fmt = DateFormat.getDateTimeInstance() + fmt.format(startTime.time) + } + viewHolder.timeView.text = startText + val duration = (stopTime.time.time - startTime.time.time) / 1000 + viewHolder.durationView.text = DateUtils.formatElapsedTime(duration) + } + } + + return rowView + } + +} diff --git a/app/src/main/kotlin/com/tutpro/baresip/CallListAdapter.kt b/app/src/main/kotlin/com/tutpro/baresip/CallListAdapter.kt index ba0d5d4e..ead9b732 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/CallListAdapter.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/CallListAdapter.kt @@ -1,6 +1,8 @@ package com.tutpro.baresip import android.content.Context +import android.content.Intent +import android.os.Bundle import androidx.cardview.widget.CardView import android.view.LayoutInflater import android.view.View @@ -12,15 +14,15 @@ import android.widget.TextView import java.util.* -class CallListAdapter(private val cxt: Context, private val rows: ArrayList) : - ArrayAdapter(cxt, R.layout.call_row, rows) { +class CallListAdapter(private val ctx: Context, private val aor: String, private val rows: ArrayList) : + ArrayAdapter(ctx, R.layout.call_row, rows) { - private val layoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater + private val layoutInflater = LayoutInflater.from(context) private class ViewHolder(view: View?) { val textAvatarView = view?.findViewById(R.id.TextAvatar) as TextView val cardAvatarView = view?.findViewById(R.id.CardAvatar) as CardView - val cardImageAvatarView = view?.findViewById(R.id.CardImageAvatar) as ImageView + val imageAvatarView = view?.findViewById(R.id.ImageAvatar) as ImageView val directionsView = view?.findViewById(R.id.directions) as LinearLayout val etcView = view?.findViewById(R.id.etc) as TextView val peerURIView = view?.findViewById(R.id.peer_uri) as TextView @@ -42,18 +44,22 @@ class CallListAdapter(private val cxt: Context, private val rows: ArrayList 3) { viewHolder.etcView.text = "..." break } - val dirView = ImageView(cxt) + val dirView = ImageView(ctx) val params = LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT) dirView.layoutParams = params dirView.setPadding(0, 5, 0, 0) - dirView.setImageResource(d) + dirView.setImageResource(d.direction) viewHolder.directionsView.addView(dirView) count++ } @@ -84,7 +90,17 @@ class CallListAdapter(private val cxt: Context, private val rows: ArrayList() - val indexes = ArrayList() +class CallRow(val aor: String, val peerUri: String, val direction: Int, + startTime: GregorianCalendar?, val stopTime: GregorianCalendar) { + + class Details(val direction: Int, val startTime: GregorianCalendar?, val stopTime: GregorianCalendar) + + val details = ArrayList
() init { - directions.add(direction) - indexes.add(index) + details.add(Details(direction, startTime, stopTime)) } } diff --git a/app/src/main/kotlin/com/tutpro/baresip/CallsActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/CallsActivity.kt index ef9af8a5..1216c559 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/CallsActivity.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/CallsActivity.kt @@ -7,7 +7,6 @@ import android.os.Bundle import android.os.SystemClock import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity -import android.text.format.DateUtils.isToday import android.view.Menu import android.view.MenuItem import android.view.View @@ -16,7 +15,6 @@ import android.widget.TextView import androidx.activity.result.contract.ActivityResultContracts import com.tutpro.baresip.databinding.ActivityCallsBinding -import java.text.DateFormat import java.util.* class CallsActivity : AppCompatActivity() { @@ -46,7 +44,7 @@ class CallsActivity : AppCompatActivity() { val listView = binding.calls aorGenerateHistory(aor) - clAdapter = CallListAdapter(this, uaHistory) + clAdapter = CallListAdapter(this, aor, uaHistory) listView.adapter = clAdapter listView.isLongClickable = true @@ -117,7 +115,7 @@ class CallsActivity : AppCompatActivity() { } } } - val callText: String = if (uaHistory[pos].directions.size > 1) + val callText: String = if (uaHistory[pos].details.size > 1) getString(R.string.calls_calls) else getString(R.string.calls_call) @@ -236,33 +234,19 @@ class CallsActivity : AppCompatActivity() { R.drawable.arrow_up_green else R.drawable.arrow_up_red - if (uaHistory.isNotEmpty() && (uaHistory.last().peerUri == h.peerUri)) { - uaHistory.last().directions.add(direction) - uaHistory.last().indexes.add(i) - } else { - val time = if (isToday(h.stopTime.timeInMillis)) { - val fmt = DateFormat.getTimeInstance(DateFormat.SHORT) - getString(R.string.today) + "\n" + fmt.format(h.stopTime.time) - } else { - val month = h.stopTime.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.getDefault()) - val day = h.stopTime.get(Calendar.DAY_OF_MONTH) - val currentYear = Calendar.getInstance().get(Calendar.YEAR) - if (h.stopTime.get(Calendar.YEAR) == currentYear) { - val fmt = DateFormat.getTimeInstance(DateFormat.SHORT) - "$month $day" + "\n" + fmt.format(h.stopTime.time) - } else { - "$month $day" + "\n" + h.stopTime.get(Calendar.YEAR) - } - } - uaHistory.add(CallRow(h.aor, h.peerUri, direction, time, i)) - } + if (uaHistory.isNotEmpty() && (uaHistory.last().peerUri == h.peerUri)) + uaHistory.last().details.add(CallRow.Details(direction, h.startTime, h.stopTime)) + else + uaHistory.add(CallRow(h.aor, h.peerUri, direction, h.startTime, h.stopTime)) } } } private fun removeUaHistoryAt(i: Int) { - for (index in uaHistory[i].indexes) - BaresipService.callHistory.removeAt(index) + for (details in uaHistory[i].details) + BaresipService.callHistory.removeAll { + it.startTime == details.startTime && it.stopTime == details.stopTime + } uaHistory.removeAt(i) } diff --git a/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt index 1c334aeb..abf03fe2 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt @@ -88,6 +88,7 @@ class MainActivity : AppCompatActivity() { private lateinit var restoreRequest: ActivityResultLauncher private lateinit var contactsRequest: ActivityResultLauncher private lateinit var callsRequest: ActivityResultLauncher + private lateinit var callDetailsRequest: ActivityResultLauncher private var downloadsInputStream: FileInputStream? = null private var downloadsOutputStream: FileOutputStream? = null @@ -1920,6 +1921,15 @@ class MainActivity : AppCompatActivity() { i.putExtras(b) callsRequest.launch(i) } + "call_details" -> { + val i = Intent(this, CallDetailsActivity::class.java) + val b = Bundle() + b.putString("aor", activity[1]) + b.putString("peer", activity[2]) + b.putInt("position", activity[3].toInt()) + i.putExtras(b) + callsRequest.launch(i) + } } return } diff --git a/app/src/main/kotlin/com/tutpro/baresip/Utils.kt b/app/src/main/kotlin/com/tutpro/baresip/Utils.kt index 1a657b8c..01d99401 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/Utils.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/Utils.kt @@ -18,13 +18,13 @@ import android.provider.MediaStore import android.provider.OpenableColumns import android.text.Editable import android.text.TextWatcher +import android.text.format.DateUtils import android.view.View import android.view.WindowManager import android.widget.TextView import androidx.activity.result.ActivityResultLauncher import androidx.annotation.RequiresApi import androidx.appcompat.app.AlertDialog -import androidx.appcompat.app.AppCompatDelegate import androidx.core.content.ContextCompat import androidx.lifecycle.Lifecycle import androidx.lifecycle.ProcessLifecycleOwner @@ -39,6 +39,7 @@ import java.util.zip.ZipOutputStream import java.net.InetAddress import java.net.NetworkInterface import java.net.SocketException +import java.text.DateFormat import javax.crypto.Cipher import javax.crypto.SecretKeyFactory import javax.crypto.spec.IvParameterSpec @@ -694,4 +695,20 @@ object Utils { } } + fun relativeTime(ctx: Context, time: GregorianCalendar): String { + return if (DateUtils.isToday(time.timeInMillis)) { + val fmt = DateFormat.getTimeInstance(DateFormat.SHORT) + ctx.getString(R.string.today) + "\n" + fmt.format(time.time) + } else { + val month = time.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.getDefault()) + val day = time.get(Calendar.DAY_OF_MONTH) + val currentYear = Calendar.getInstance().get(Calendar.YEAR) + if (time.get(Calendar.YEAR) == currentYear) { + val fmt = DateFormat.getTimeInstance(DateFormat.SHORT) + "$month $day" + "\n" + fmt.format(time.time) + } else { + "$month $day" + "\n" + time.get(Calendar.YEAR) + } + } + } } diff --git a/app/src/main/res/layout/activity_call_details.xml b/app/src/main/res/layout/activity_call_details.xml new file mode 100644 index 00000000..ec0f78a8 --- /dev/null +++ b/app/src/main/res/layout/activity_call_details.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_calls.xml b/app/src/main/res/layout/activity_calls.xml index a9324f85..a26291c5 100644 --- a/app/src/main/res/layout/activity_calls.xml +++ b/app/src/main/res/layout/activity_calls.xml @@ -14,6 +14,7 @@ android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="10dp" + android:textSize="16sp" android:gravity="center_horizontal" > diff --git a/app/src/main/res/layout/call_detail_row.xml b/app/src/main/res/layout/call_detail_row.xml new file mode 100644 index 00000000..9233ac38 --- /dev/null +++ b/app/src/main/res/layout/call_detail_row.xml @@ -0,0 +1,30 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/call_row.xml b/app/src/main/res/layout/call_row.xml index 7d57db56..afb2dab8 100644 --- a/app/src/main/res/layout/call_row.xml +++ b/app/src/main/res/layout/call_row.xml @@ -1,13 +1,9 @@ + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" > Soita puhelut puhelun + Suunta + Pääri + Aika + Kesto Haluatko soittaa tai lähettää viestin kohteeseen \'%1$s\'? diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 90a3da51..b69de576 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -215,9 +215,14 @@ Tap to start application Call History + Call Details Call calls call + Peer + Direction + Time + Duration Do you want to call or send message to \'%1$s\'? Do you want to add \'%1$s\' to contacts or delete %2$s from call history?