....
This commit is contained in:
parent
74c64c7617
commit
5cc40ee056
@ -18,6 +18,7 @@
|
||||
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
||||
|
||||
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
|
||||
<!-- api 33+ -->
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
||||
<uses-permission
|
||||
|
||||
@ -27,7 +27,10 @@ import android.graphics.Color
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.provider.CallLog
|
||||
import android.provider.ContactsContract
|
||||
import android.provider.Settings
|
||||
import android.util.Log
|
||||
import android.view.WindowInsets
|
||||
import android.view.WindowManager
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
@ -50,7 +53,6 @@ import rasel.lunar.launcher.databinding.LauncherActivityBinding
|
||||
import rasel.lunar.launcher.feeds.Feeds
|
||||
import rasel.lunar.launcher.feeds.WidgetHost
|
||||
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_APPLICATION_THEME
|
||||
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_BACK_HOME
|
||||
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_FIRST_LAUNCH
|
||||
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_STATUS_BAR
|
||||
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_WINDOW_BACKGROUND
|
||||
@ -61,6 +63,7 @@ import rasel.lunar.launcher.helpers.UniUtils.Companion.getColorResId
|
||||
import rasel.lunar.launcher.helpers.ViewPagerAdapter
|
||||
import rasel.lunar.launcher.home.LauncherHome
|
||||
import rasel.lunar.launcher.utils.BLog
|
||||
import java.util.Date
|
||||
|
||||
|
||||
internal class LauncherActivity : AppCompatActivity() {
|
||||
@ -152,16 +155,16 @@ internal class LauncherActivity : AppCompatActivity() {
|
||||
|
||||
/* set up viewpager2 */
|
||||
private fun setupView() {
|
||||
viewPager = binding.viewPager.apply {
|
||||
adapter = ViewPagerAdapter(
|
||||
supportFragmentManager,
|
||||
mutableListOf(Feeds(), LauncherHome(), AppDrawer()),
|
||||
lifecycle
|
||||
)
|
||||
offscreenPageLimit = 1
|
||||
setCurrentItem(1, false)
|
||||
reduceDragSensitivity()
|
||||
}
|
||||
viewPager = binding.viewPager.apply {
|
||||
adapter = ViewPagerAdapter(
|
||||
supportFragmentManager,
|
||||
mutableListOf(Feeds(), LauncherHome(), AppDrawer()),
|
||||
lifecycle
|
||||
)
|
||||
offscreenPageLimit = 1
|
||||
setCurrentItem(1, false)
|
||||
reduceDragSensitivity()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setBgColor() {
|
||||
@ -235,4 +238,6 @@ internal class LauncherActivity : AppCompatActivity() {
|
||||
fun openSearchMenus(keyword : String, dismissCalback: DismissCalback) {
|
||||
SearchMenu().show(supportFragmentManager,keyword) {dismissCalback?.invoke()}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -25,14 +25,23 @@ import android.content.IntentFilter
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Bundle
|
||||
import android.provider.AlarmClock
|
||||
import android.provider.CallLog
|
||||
import android.text.format.DateFormat
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.RadioButton
|
||||
import android.widget.Toast
|
||||
import androidx.biometric.BiometricPrompt
|
||||
import androidx.core.view.get
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.launch
|
||||
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
||||
import rasel.lunar.launcher.R
|
||||
import rasel.lunar.launcher.databinding.LauncherHomeBinding
|
||||
@ -51,10 +60,12 @@ import rasel.lunar.launcher.helpers.UniUtils.Companion.lockMethod
|
||||
import rasel.lunar.launcher.home.weather.WeatherExecutor
|
||||
import rasel.lunar.launcher.qaccess.QuickAccess
|
||||
import rasel.lunar.launcher.settings.SettingsActivity
|
||||
import rasel.lunar.launcher.todos.MissedCallsAdapter
|
||||
import rasel.lunar.launcher.todos.TodoAdapter
|
||||
import rasel.lunar.launcher.todos.TodoManager
|
||||
import rasel.lunar.launcher.utils.BLog
|
||||
import rasel.lunar.launcher.utils.SimpleFingerGestures
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
|
||||
@ -122,6 +133,86 @@ internal class LauncherHome : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
var callList = arrayListOf<MissedCall>()
|
||||
|
||||
private suspend fun getCallDetails() {
|
||||
MainScope().async {
|
||||
var dateParam = Date(System.currentTimeMillis() - (1000 * 60 * 60 * 24 * 3)).time.toString()
|
||||
val managedCursor = lActivity!!.managedQuery(
|
||||
CallLog.Calls.CONTENT_URI, arrayOf(
|
||||
CallLog.Calls.NUMBER,
|
||||
CallLog.Calls.TYPE,
|
||||
CallLog.Calls.DATE,
|
||||
CallLog.Calls.DURATION,
|
||||
CallLog.Calls.CACHED_NAME,
|
||||
), CallLog.Calls.DATE + "> ? AND " + CallLog.Calls.TYPE + " > ?", arrayOf<String>(dateParam, "2"), CallLog.Calls.DATE + " desc")
|
||||
val number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER)
|
||||
val type = managedCursor.getColumnIndex(CallLog.Calls.TYPE)
|
||||
val date = managedCursor.getColumnIndex(CallLog.Calls.DATE)
|
||||
val duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION)
|
||||
val name = managedCursor.getColumnIndex(CallLog.Calls.CACHED_NAME)
|
||||
// sb.append("Call Details : ${managedCursor.count}")
|
||||
var missedCalls = hashMapOf<String, MissedCall>()
|
||||
while (managedCursor.moveToNext()) {
|
||||
val phNumber = managedCursor.getString(number) // mobile number
|
||||
val callType = managedCursor.getString(type) // call type
|
||||
val callDate = managedCursor.getString(date) // call date
|
||||
val callDayTime: Date = Date(callDate.toLong())
|
||||
val callDuration = managedCursor.getString(duration)
|
||||
val callerName = managedCursor.getString(name)
|
||||
|
||||
var dir: String = ""
|
||||
val dircode = callType.toInt()
|
||||
when (dircode) {
|
||||
CallLog.Calls.INCOMING_TYPE -> {
|
||||
dir = "INCOMING_TYPE"
|
||||
}
|
||||
CallLog.Calls.OUTGOING_TYPE -> {
|
||||
dir = "OUTGOING_TYPE"
|
||||
}
|
||||
CallLog.Calls.MISSED_TYPE -> {
|
||||
dir = "MISSED_TYPE"
|
||||
}
|
||||
CallLog.Calls.VOICEMAIL_TYPE -> {
|
||||
dir = "VOICEMAIL_TYPE"
|
||||
}
|
||||
CallLog.Calls.REJECTED_TYPE -> {
|
||||
dir = "REJECTED_TYPE"
|
||||
}
|
||||
CallLog.Calls.BLOCKED_TYPE -> {
|
||||
dir = "BLOCKED_TYPE"
|
||||
}
|
||||
CallLog.Calls.ANSWERED_EXTERNALLY_TYPE -> {
|
||||
dir = "ANSWERED_EXTERNALLY_TYPE"
|
||||
}
|
||||
}
|
||||
// if (dircode > 2) {
|
||||
var missed: MissedCall = if (missedCalls.containsKey(phNumber)) {
|
||||
missedCalls.get(phNumber)!!.apply {
|
||||
count = count + 1
|
||||
}
|
||||
} else {
|
||||
MissedCall(1,callerName,phNumber, dircode, dir, SimpleDateFormat("yyy/MM/dd-HH:mm:ss").format(callDayTime))
|
||||
}
|
||||
missedCalls.put(phNumber, missed)
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
managedCursor.close()
|
||||
return@async missedCalls
|
||||
}.await().apply {
|
||||
if (callList.size == this.size) {
|
||||
|
||||
} else {
|
||||
callList.clear()
|
||||
this.forEach { t, u ->
|
||||
callList.add(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
/* unregister battery changes */
|
||||
@ -383,7 +474,19 @@ internal class LauncherHome : Fragment() {
|
||||
|
||||
/* to-do list */
|
||||
private fun showTodoList() {
|
||||
binding.notes.adapter = TodoAdapter(null, requireContext())
|
||||
if (binding.missedCalls.isChecked == true) {
|
||||
if (callList.size == 0) {
|
||||
GlobalScope.launch { getCallDetails() }
|
||||
} else {
|
||||
BLog.LOGE("callList >>> ${callList.size}")
|
||||
binding.notes.adapter = MissedCallsAdapter(callList, requireContext())
|
||||
binding.notes.post {
|
||||
binding.notes.invalidate()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
binding.notes.adapter = TodoAdapter(null, requireContext())
|
||||
}
|
||||
}
|
||||
|
||||
/* get time format string */
|
||||
@ -422,3 +525,22 @@ internal class LauncherHome : Fragment() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class MissedCall {
|
||||
constructor(count: Int, name: String?, number: String, type: Int, typeString: String, date : String) {
|
||||
this.count = count
|
||||
this.name = name ?: "unknown"
|
||||
this.number = number
|
||||
this.type = type
|
||||
this.typeString = typeString
|
||||
this.date = date
|
||||
}
|
||||
|
||||
var count : Int = 1
|
||||
var name : String = "how"
|
||||
var number : String = ""
|
||||
var type : Int = 0
|
||||
var typeString : String = ""
|
||||
var date : String = ""
|
||||
}
|
||||
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Lunar Launcher
|
||||
* Copyright (C) 2022 Md Rasel Hossain
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package rasel.lunar.launcher.todos
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
||||
import rasel.lunar.launcher.R
|
||||
import rasel.lunar.launcher.databinding.ListItemBinding
|
||||
import rasel.lunar.launcher.databinding.TodoDialogBinding
|
||||
import rasel.lunar.launcher.helpers.UniUtils.Companion.copyToClipboard
|
||||
import rasel.lunar.launcher.home.MissedCall
|
||||
import rasel.lunar.launcher.utils.BLog
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
|
||||
internal class MissedCallsAdapter(
|
||||
private val callList: ArrayList<MissedCall>,
|
||||
private val context: Context) : RecyclerView.Adapter<MissedCallsAdapter.MissedCallsHolder>() {
|
||||
|
||||
private val currentFragment = lActivity!!.supportFragmentManager.findFragmentById(R.id.mainFragmentsContainer)
|
||||
|
||||
override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): MissedCallsHolder {
|
||||
val binding = ListItemBinding.inflate(LayoutInflater.from(viewGroup.context), viewGroup, false)
|
||||
return MissedCallsHolder(binding)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
// BLog.LOGE("callList.size >>> ${callList.size}")
|
||||
return callList.size
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onBindViewHolder(holder: MissedCallsHolder, position: Int) {
|
||||
val todo = callList[position]
|
||||
BLog.LOGE("callList >>> ${callList[position]}")
|
||||
holder.view.itemText.text = "\u25CF ${if(todo.name.equals("unknown")) todo.number else { todo.name}} , ${todo.typeString} : ${todo.count} : ${todo.date}"
|
||||
|
||||
/* multiline texts are enabled for TodoManager */
|
||||
holder.view.itemText.isSingleLine = false
|
||||
/* launch edit or update dialog on item click */
|
||||
holder.view.itemText.setOnClickListener { updateDialog(position) }
|
||||
/* copy texts on long click */
|
||||
holder.view.itemText.setOnLongClickListener {
|
||||
copyToClipboard(context, todo.name)
|
||||
true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inner class MissedCallsHolder(var view: ListItemBinding) : RecyclerView.ViewHolder(view.root)
|
||||
|
||||
/* update dialog */
|
||||
private fun updateDialog(position: Int) {
|
||||
val bottomSheetDialog = BottomSheetDialog(lActivity!!, R.style.BottomSheetDialog)
|
||||
val dialogBinding = TodoDialogBinding.inflate(LayoutInflater.from(context))
|
||||
bottomSheetDialog.setContentView(dialogBinding.root)
|
||||
bottomSheetDialog.show()
|
||||
bottomSheetDialog.dismissWithAnimation = true
|
||||
|
||||
val databaseHandler = DatabaseHandler(context)
|
||||
val todo = databaseHandler.todos[position]
|
||||
|
||||
dialogBinding.apply {
|
||||
deleteAllConfirmation.visibility = View.GONE
|
||||
todoInput.setText(todo.name)
|
||||
todoCancel.text = context.getString(R.string.delete)
|
||||
todoCancel.setTextColor(ContextCompat.getColor(context, android.R.color.holo_red_light))
|
||||
todoOk.text = context.getString(R.string.update)
|
||||
}
|
||||
|
||||
/* delete the item */
|
||||
dialogBinding.todoCancel.setOnClickListener {
|
||||
|
||||
}
|
||||
|
||||
/* update the item */
|
||||
dialogBinding.todoOk.setOnClickListener {
|
||||
val updatedTodoString = Objects.requireNonNull(dialogBinding.todoInput.text).toString().trim { it <= ' ' }
|
||||
if (updatedTodoString.isNotEmpty()) {
|
||||
todo.name = updatedTodoString
|
||||
databaseHandler.updateTodo(todo)
|
||||
bottomSheetDialog.dismiss()
|
||||
} else {
|
||||
dialogBinding.todoInput.error = context.getString(R.string.empty_text_field)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -66,18 +66,54 @@
|
||||
app:layout_constraintTop_toBottomOf="@+id/date"
|
||||
app:layout_constraintVertical_bias="0.100" />
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/summaryChoose"
|
||||
android:layout_width="0dp"
|
||||
android:gravity="center"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@+id/batteryProgress"
|
||||
>
|
||||
<RadioButton
|
||||
android:id="@+id/missedCalls"
|
||||
android:button="@null"
|
||||
android:gravity="center"
|
||||
android:text="전화"
|
||||
android:checked="true"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
<RadioButton
|
||||
android:gravity="center"
|
||||
android:button="@null"
|
||||
android:text="투두"
|
||||
android:checked="false"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
<RadioButton
|
||||
android:gravity="center"
|
||||
android:button="@null"
|
||||
android:text="문자"
|
||||
android:checked="false"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
</RadioGroup>
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/notes"
|
||||
android:layout_width="@dimen/zero"
|
||||
android:layout_height="@dimen/zero"
|
||||
android:layout_height="200dp"
|
||||
android:overScrollMode="never"
|
||||
android:padding="@dimen/fortyEight"
|
||||
android:padding="20dp"
|
||||
android:scrollbars="none"
|
||||
app:layoutManager="LinearLayoutManager"
|
||||
app:layout_constraintBottom_toTopOf="@id/favAppsGroup"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/batteryProgress" />
|
||||
|
||||
app:layout_constraintTop_toBottomOf="@+id/summaryChoose" />
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:id="@+id/favAppsGroup"
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/itemText"
|
||||
android:layout_width="@dimen/zero"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="40dp"
|
||||
android:padding="@dimen/twelve"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user