This commit is contained in:
lunaticbum 2024-08-23 11:39:16 +09:00
parent ed24af2d41
commit b1fdea3317
10 changed files with 662 additions and 561 deletions

View File

@ -1,3 +1,5 @@
import org.jetbrains.kotlin.fir.scopes.debugCollectOverrides
plugins {
id ("com.android.application")
id ("kotlin-android")
@ -22,17 +24,28 @@ android {
isDebuggable = true
applicationIdSuffix = ".debug"
versionNameSuffix = "-debug"
resValue ("string", "app_name", "Lunar Launcher Debug")
resValue ("string", "app_name", "Bums Launcher Debug")
}
getByName("release") {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles (getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
resValue ("string", "app_name", "Lunar Launcher")
resValue ("string", "app_name", "Bums Launcher")
}
}
signingConfigs {
getByName("debug") {
storeFile = file("./bs_debug.keystore")
storePassword = "android"
keyAlias = "androiddebugkey"
keyPassword = "android"
}
}
applicationVariants.all {
if (buildType.name == "release") {
outputs.all {
@ -61,14 +74,17 @@ android {
dependencies {
val kotlinVersion: String? by extra
implementation ("androidx.appcompat:appcompat:1.6.1")
implementation ("androidx.appcompat:appcompat:1.7.0")
implementation ("androidx.biometric:biometric-ktx:1.2.0-alpha05")
implementation ("androidx.browser:browser:1.8.0")
implementation ("androidx.core:core-ktx:1.12.0")
implementation ("androidx.core:core-ktx:1.13.1")
implementation ("androidx.core:core-splashscreen:1.0.1")
implementation ("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0")
implementation ("com.google.android.material:material:1.10.0")
implementation ("androidx.lifecycle:lifecycle-runtime-ktx:2.8.4")
implementation ("com.google.android.material:material:1.12.0")
implementation (kotlin("stdlib", version = kotlinVersion))
implementation ("com.github.cachapa:ExpandableLayout:2.9.2")
implementation ("com.squareup.picasso:picasso:2.8")
implementation ("com.squareup.picasso:picasso:2.71828")
implementation ("androidx.work:work-runtime:2.9.1")
implementation ("com.google.code.gson:gson:2.11.0")
}

View File

@ -32,6 +32,7 @@ import android.os.Handler
import android.os.Looper
import android.provider.ContactsContract
import android.util.Log
import android.view.KeyEvent
import android.view.KeyEvent.ACTION_UP
import android.view.LayoutInflater
import android.view.View
@ -201,25 +202,29 @@ internal class AppDrawer : Fragment() {
ContactsContract.CommonDataKinds.Phone.NUMBER,
)
val cursor = resolver.query(phoneUri, projection, null, null, null)
if (cursor != null) {
while (cursor.moveToNext()) {
val idx =cursor.getColumnIndex(projection[0])
val nameIndex = cursor.getColumnIndex(projection[1])
val numberIndex = cursor.getColumnIndex(projection[2])
var contactId = cursor.getString(idx)
val name = cursor.getString(nameIndex)
var number = cursor.getString(numberIndex)
number = number.replace("-", "")
if (name?.length ?: 0 > 0 && number?.length ?: 0 > 0) {
contactList.add(SimpleContact(contactId,name, number))
originContactList.add(SimpleContact(contactId,name, number))
}
Log.d("GetContact", "이름 : $name 번호 : $number ")
}
}
// 데이터 계열은 반드시 닫아줘야 한다.
cursor!!.close()
try {
val cursor = resolver.query(phoneUri, projection, null, null, null)
if (cursor != null) {
while (cursor.moveToNext()) {
val idx =cursor.getColumnIndex(projection[0])
val nameIndex = cursor.getColumnIndex(projection[1])
val numberIndex = cursor.getColumnIndex(projection[2])
var contactId = cursor.getString(idx)
val name = cursor.getString(nameIndex)
var number = cursor.getString(numberIndex)
number = number.replace("-", "")
if (name?.length ?: 0 > 0 && number?.length ?: 0 > 0) {
contactList.add(SimpleContact(contactId,name, number))
originContactList.add(SimpleContact(contactId,name, number))
}
Log.d("GetContact", "이름 : $name 번호 : $number ")
}
}
// 데이터 계열은 반드시 닫아줘야 한다.
cursor?.close()
} catch ( e : Exception) {
e.printStackTrace()
}
}
}
@ -238,8 +243,8 @@ internal class AppDrawer : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.searchInput.setOnKeyListener { v, keyCode, event ->
if (keyCode == 66 && contactList.size < 1 && packageList.size < 1) {
binding.searchGoogle.performClick()
if (keyCode == 66 && contactList.size < 1 && packageList.size < 1 && event.action == KeyEvent.ACTION_UP) {
checkResult(binding.searchInput.text.toString())
true
}else {
false
@ -415,7 +420,8 @@ internal class AppDrawer : Fragment() {
fun fetchApps() {
packageList.clear()
oringinPackageList.clear()
GlobalScope.launch {
try {
packageInfoList = (if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
packageManager?.queryIntentActivities(
Intent(Intent.ACTION_MAIN, null).addCategory(Intent.CATEGORY_LAUNCHER),
@ -436,7 +442,8 @@ internal class AppDrawer : Fragment() {
appsAdapter?.updateData(packageList)
} }
}!!
}
} catch (e : Exception) {e.printStackTrace()}
}
private fun getAlphabetItems() {

View File

@ -95,19 +95,23 @@ internal class ContactMenu : BottomSheetDialogFragment() {
)
BLog.LOGE("GetContact", "packageName ${packageName}")
val cursor = resolver.query(phoneUri, projection, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + packageName, null , null)
if (cursor != null) {
while (cursor.moveToNext()) {
val nameIndex = cursor.getColumnIndex(projection[0])
val numberIndex = cursor.getColumnIndex(projection[1])
contactName = cursor.getString(nameIndex)
var number = cursor.getString(numberIndex)
contactPhoneNumber = number.replace("-", "")
BLog.LOGE("GetContact", "이름 : $contactName 번호 : $contactPhoneNumber ")
}
}
// 데이터 계열은 반드시 닫아줘야 한다.
cursor!!.close()
try {
val cursor = resolver.query(phoneUri, projection, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + packageName, null , null)
if (cursor != null) {
while (cursor.moveToNext()) {
val nameIndex = cursor.getColumnIndex(projection[0])
val numberIndex = cursor.getColumnIndex(projection[1])
contactName = cursor.getString(nameIndex)
var number = cursor.getString(numberIndex)
contactPhoneNumber = number.replace("-", "")
BLog.LOGE("GetContact", "이름 : $contactName 번호 : $contactPhoneNumber ")
}
}
// 데이터 계열은 반드시 닫아줘야 한다.
cursor!!.close()
} catch ( e : Exception) {
e.printStackTrace()
}
/* get application info */

View File

@ -25,23 +25,20 @@ 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 androidx.lifecycle.LiveData
import androidx.work.OneTimeWorkRequest
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkInfo
import androidx.work.WorkManager
import com.google.gson.Gson
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
import rasel.lunar.launcher.R
import rasel.lunar.launcher.databinding.LauncherHomeBinding
@ -52,7 +49,6 @@ import rasel.lunar.launcher.helpers.Constants.Companion.KEY_LOCK_METHOD
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_TIME_FORMAT
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_TODO_LOCK
import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_SETTINGS
import rasel.lunar.launcher.helpers.SwipeTouchListener
import rasel.lunar.launcher.helpers.UniUtils.Companion.biometricPromptInfo
import rasel.lunar.launcher.helpers.UniUtils.Companion.canAuthenticate
import rasel.lunar.launcher.helpers.UniUtils.Companion.expandNotificationPanel
@ -61,12 +57,11 @@ 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.MissedCallGetter
import rasel.lunar.launcher.utils.SimpleFingerGestures
import java.text.SimpleDateFormat
import java.util.*
import java.util.Calendar
import java.util.Locale
internal class LauncherHome : Fragment() {
@ -85,12 +80,18 @@ internal class LauncherHome : Fragment() {
batteryReceiver = BatteryReceiver(binding.batteryProgress)
binding.favAppsGroup.visibility = View.GONE
Thread("CALLED").run {
getCallDetails()
}
mWorkManager = WorkManager.getInstance(lActivity!!.application);
mWorkManager?.enqueue(OneTimeWorkRequestBuilder<MissedCallGetter>().addTag("MissedCallGetter").build())
BLog.LOGE("onCreateView()")
return binding.root
}
private var mSavedWorkInfo: LiveData<List<WorkInfo>>? = null
fun getOutputWorkInfo(): LiveData<List<WorkInfo>> {
return mSavedWorkInfo!!
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
/* handle gesture events */
@ -98,11 +99,14 @@ internal class LauncherHome : Fragment() {
batteryProgressGestures()
todosGestures()
BLog.LOGE("onViewCreated()")
// mWorkManager.
/* refresh the to-do list after getting back from TodoManager */
fragManager.addOnBackStackChangedListener {
BLog.LOGE("addOnBackStackChangedListener()")
shouldResume = if (fragManager.backStackEntryCount == 0) {
binding.root.visibility = View.VISIBLE
showTodoList()
true
} else {
binding.root.visibility = View.GONE
@ -113,6 +117,7 @@ internal class LauncherHome : Fragment() {
override fun onResume() {
super.onResume()
BLog.LOGE("onResume()")
if (shouldResume) {
/* register battery changes */
requireContext().registerReceiver(batteryReceiver, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
@ -130,83 +135,31 @@ internal class LauncherHome : Fragment() {
/* show weather */
WeatherExecutor(settingsPrefs).generateWeatherString(binding.weather)
/* show to-do list */
showTodoList()
mSavedWorkInfo = mWorkManager?.getWorkInfosByTagLiveData("MissedCallGetter");
getOutputWorkInfo().observeForever {
it.last()?.outputData?.keyValueMap?.forEach { t, u ->
try {
if (u is String) {
Gson().fromJson(u,MissedCall::class.java)?.let {
callList.add(it)
}
}
} catch (e : Exception) {
} finally {
showTodoList()
}
}
}
}
}
private var mWorkManager: WorkManager? = null
var callList = arrayListOf<MissedCall>()
private fun getCallDetails() {
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)
var missedCalls = hashMapOf<String, MissedCall>()
if (missedCalls.size != callList.size) {
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"
}
}
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()
if (callList.size == missedCalls.size) {
} else {
callList.clear()
missedCalls.forEach { t, u ->
callList.add(u)
}
}
}
override fun onPause() {
super.onPause()
@ -463,22 +416,23 @@ internal class LauncherHome : Fragment() {
/* launch TodoManager fragment */
private fun launchTodoManager() {
fragManager.beginTransaction().replace(R.id.mainFragmentsContainer, TodoManager())
.addToBackStack("").commit()
// fragManager.beginTransaction().replace(R.id.mainFragmentsContainer, TodoManager())
// .addToBackStack("").commit()
}
/* to-do list */
@SuppressLint("NotifyDataSetChanged")
private fun showTodoList() {
if (binding.missedCalls.isChecked == true) {
if (callList.size > 0) {
BLog.LOGE("callList >>> ${callList.size}")
binding.notes.adapter = MissedCallsAdapter(callList, requireContext())?.apply {
this.notifyDataSetChanged()
if (binding.missedCalls.isChecked) {
if (callList.size > 0 && isAdded && isResumed && isVisible) {
try {
BLog.LOGE("callList >>> ${callList.size}")
binding.notes.adapter = MissedCallsAdapter(callList, requireContext())
} catch (e : Exception) {
}
}
} else {
binding.notes.adapter = TodoAdapter(null, requireContext())
// binding.notes.adapter = TodoAdapter(null, requireContext())
}
}
@ -536,4 +490,9 @@ class MissedCall {
var type : Int = 0
var typeString : String = ""
var date : String = ""
fun toJson() : String {
return Gson().toJson(this)
}
}

View File

@ -1,107 +1,107 @@
/*
* 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.database.sqlite.SQLiteOpenHelper
import android.database.sqlite.SQLiteDatabase
import android.content.ContentValues
import android.annotation.SuppressLint
import android.content.Context
import android.database.DatabaseUtils
import rasel.lunar.launcher.helpers.Constants.Companion.TODO_COLUMN_CREATED
import rasel.lunar.launcher.helpers.Constants.Companion.TODO_COLUMN_ID
import rasel.lunar.launcher.helpers.Constants.Companion.TODO_COLUMN_NAME
import rasel.lunar.launcher.helpers.Constants.Companion.TODO_DATABASE_NAME
import rasel.lunar.launcher.helpers.Constants.Companion.TODO_DATABASE_VERSION
import rasel.lunar.launcher.helpers.Constants.Companion.TODO_TABLE_NAME
import java.util.ArrayList
internal class DatabaseHandler(context: Context?) :
SQLiteOpenHelper(context, TODO_DATABASE_NAME, null, TODO_DATABASE_VERSION) {
/* create database */
override fun onCreate(database: SQLiteDatabase) {
val createTodoTable = "CREATE TABLE " + TODO_TABLE_NAME + " (" +
TODO_COLUMN_ID + " integer PRIMARY KEY AUTOINCREMENT," +
TODO_COLUMN_CREATED + " datetime DEFAULT CURRENT_TIMESTAMP," +
TODO_COLUMN_NAME + " varchar)"
database.execSQL(createTodoTable)
}
override fun onUpgrade(sqLiteDatabase: SQLiteDatabase, i: Int, i1: Int) {}
/* add new to-do entry */
fun addTodo(todo: Todo) {
val database = writableDatabase
val contentValues = ContentValues()
contentValues.put(TODO_COLUMN_NAME, todo.name)
database.insert(TODO_TABLE_NAME, null, contentValues)
}
/* update or edit existing to-do */
fun updateTodo(todo: Todo) {
val database = writableDatabase
val contentValues = ContentValues()
contentValues.put(TODO_COLUMN_NAME, todo.name)
database.update(
TODO_TABLE_NAME,
contentValues,
"$TODO_COLUMN_ID=?",
arrayOf(todo.id.toString())
)
}
/* delete a single to-do */
fun deleteTodo(todoId: Long) {
writableDatabase.delete(TODO_TABLE_NAME,
"$TODO_COLUMN_ID=?", arrayOf(todoId.toString()))
}
/* delete all existing todos at once */
fun deleteAll() {
writableDatabase.delete(TODO_TABLE_NAME, null, null)
}
@get:SuppressLint("Range")
val todos: ArrayList<Todo>
get() {
val todoList = ArrayList<Todo>()
val queryResult =
readableDatabase.rawQuery("SELECT * from $TODO_TABLE_NAME", null)
if (queryResult.moveToFirst()) {
do {
val todo = Todo()
todo.id = queryResult.getLong(queryResult.getColumnIndex(TODO_COLUMN_ID))
todo.name = queryResult.getString(queryResult.getColumnIndex(TODO_COLUMN_NAME))
todoList.add(todo)
} while (queryResult.moveToNext())
}
queryResult.close()
return todoList
}
/* check if any item exists in the database */
val isTodoExists: Boolean get() {
return DatabaseUtils.queryNumEntries(readableDatabase, TODO_TABLE_NAME, 1.toString()) > 0
}
}
///*
// * 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.database.sqlite.SQLiteOpenHelper
//import android.database.sqlite.SQLiteDatabase
//import android.content.ContentValues
//import android.annotation.SuppressLint
//import android.content.Context
//import android.database.DatabaseUtils
//import rasel.lunar.launcher.helpers.Constants.Companion.TODO_COLUMN_CREATED
//import rasel.lunar.launcher.helpers.Constants.Companion.TODO_COLUMN_ID
//import rasel.lunar.launcher.helpers.Constants.Companion.TODO_COLUMN_NAME
//import rasel.lunar.launcher.helpers.Constants.Companion.TODO_DATABASE_NAME
//import rasel.lunar.launcher.helpers.Constants.Companion.TODO_DATABASE_VERSION
//import rasel.lunar.launcher.helpers.Constants.Companion.TODO_TABLE_NAME
//import java.util.ArrayList
//
//
//internal class DatabaseHandler(context: Context?) :
// SQLiteOpenHelper(context, TODO_DATABASE_NAME, null, TODO_DATABASE_VERSION) {
//
// /* create database */
// override fun onCreate(database: SQLiteDatabase) {
// val createTodoTable = "CREATE TABLE " + TODO_TABLE_NAME + " (" +
// TODO_COLUMN_ID + " integer PRIMARY KEY AUTOINCREMENT," +
// TODO_COLUMN_CREATED + " datetime DEFAULT CURRENT_TIMESTAMP," +
// TODO_COLUMN_NAME + " varchar)"
// database.execSQL(createTodoTable)
// }
//
// override fun onUpgrade(sqLiteDatabase: SQLiteDatabase, i: Int, i1: Int) {}
//
// /* add new to-do entry */
// fun addTodo(todo: Todo) {
// val database = writableDatabase
// val contentValues = ContentValues()
// contentValues.put(TODO_COLUMN_NAME, todo.name)
// database.insert(TODO_TABLE_NAME, null, contentValues)
// }
//
// /* update or edit existing to-do */
// fun updateTodo(todo: Todo) {
// val database = writableDatabase
// val contentValues = ContentValues()
// contentValues.put(TODO_COLUMN_NAME, todo.name)
// database.update(
// TODO_TABLE_NAME,
// contentValues,
// "$TODO_COLUMN_ID=?",
// arrayOf(todo.id.toString())
// )
// }
//
// /* delete a single to-do */
// fun deleteTodo(todoId: Long) {
// writableDatabase.delete(TODO_TABLE_NAME,
// "$TODO_COLUMN_ID=?", arrayOf(todoId.toString()))
// }
//
// /* delete all existing todos at once */
// fun deleteAll() {
// writableDatabase.delete(TODO_TABLE_NAME, null, null)
// }
//
// @get:SuppressLint("Range")
// val todos: ArrayList<Todo>
// get() {
// val todoList = ArrayList<Todo>()
//// val queryResult =
//// readableDatabase.rawQuery("SELECT * from $TODO_TABLE_NAME", null)
////
//// if (queryResult.moveToFirst()) {
//// do {
//// val todo = Todo()
//// todo.id = queryResult.getLong(queryResult.getColumnIndex(TODO_COLUMN_ID))
//// todo.name = queryResult.getString(queryResult.getColumnIndex(TODO_COLUMN_NAME))
//// todoList.add(todo)
//// } while (queryResult.moveToNext())
//// }
////
//// queryResult.close()
// return todoList
// }
//
// /* check if any item exists in the database */
// val isTodoExists: Boolean get() {
// return DatabaseUtils.queryNumEntries(readableDatabase, TODO_TABLE_NAME, 1.toString()) > 0
// }
//
//}

View File

@ -75,39 +75,39 @@ internal class MissedCallsAdapter(
/* 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)
}
}
// 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)
// }
// }
}
}

View File

@ -1,25 +1,25 @@
/*
* 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
internal class Todo {
var id: Long = -1
var name = ""
}
///*
// * 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
//
//
//internal class Todo {
// var id: Long = -1
// var name = ""
//}

View File

@ -1,127 +1,129 @@
/*
* 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.Constants.Companion.KEY_TODO_COUNTS
import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_SETTINGS
import rasel.lunar.launcher.helpers.UniUtils.Companion.copyToClipboard
import java.util.*
internal class TodoAdapter(
private val todoManager: TodoManager?,
private val context: Context) : RecyclerView.Adapter<TodoAdapter.TodoViewHolder>() {
private val currentFragment = lActivity!!.supportFragmentManager.findFragmentById(R.id.mainFragmentsContainer)
private val todoList = DatabaseHandler(context).todos
override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): TodoViewHolder {
val binding = ListItemBinding.inflate(LayoutInflater.from(viewGroup.context), viewGroup, false)
return TodoViewHolder(binding)
}
override fun getItemCount(): Int {
/* if current fragment is LauncherHome,
then return size following the settings value */
val sharedPreferences = context.getSharedPreferences(PREFS_SETTINGS, 0)
val numberOfTodos = sharedPreferences.getInt(KEY_TODO_COUNTS, 3)
return if (currentFragment !is TodoManager) {
todoList.size.coerceAtMost(numberOfTodos)
} else {
todoList.size
}
}
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: TodoViewHolder, position: Int) {
val todo = todoList[position]
holder.view.itemText.text = "\u25CF ${todo.name}"
if (currentFragment is TodoManager) {
/* 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
}
} else {
/* single line text for home screen */
holder.view.itemText.isSingleLine = true
}
}
inner class TodoViewHolder(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 {
databaseHandler.deleteTodo(todo.id)
bottomSheetDialog.dismiss()
todoManager?.refreshList()
}
/* 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()
todoManager?.refreshList()
} else {
dialogBinding.todoInput.error = context.getString(R.string.empty_text_field)
}
}
}
}
///*
// * 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.Constants.Companion.KEY_TODO_COUNTS
//import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_SETTINGS
//import rasel.lunar.launcher.helpers.UniUtils.Companion.copyToClipboard
//import java.util.*
//
//
//internal class TodoAdapter(
// private val todoManager: TodoManager?,
// private val context: Context) : RecyclerView.Adapter<TodoAdapter.TodoViewHolder>() {
//
// private val currentFragment = lActivity!!.supportFragmentManager.findFragmentById(R.id.mainFragmentsContainer)
//// private val todoList = DatabaseHandler(context).todos
//
// override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): TodoViewHolder {
// val binding = ListItemBinding.inflate(LayoutInflater.from(viewGroup.context), viewGroup, false)
// return TodoViewHolder(binding)
// }
//
// override fun getItemCount(): Int {
// /* if current fragment is LauncherHome,
// then return size following the settings value */
// val sharedPreferences = context.getSharedPreferences(PREFS_SETTINGS, 0)
// val numberOfTodos = sharedPreferences.getInt(KEY_TODO_COUNTS, 3)
// return if (currentFragment !is TodoManager) {
//// todoList.size.coerceAtMost(numberOfTodos)
// 0
// } else {
//// todoList.size
// 0
// }
// }
//
// @SuppressLint("SetTextI18n")
// override fun onBindViewHolder(holder: TodoViewHolder, position: Int) {
//// val todo = todoList[position]
//
//// holder.view.itemText.text = "\u25CF ${todo.name}"
////
//// if (currentFragment is TodoManager) {
//// /* 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
//// }
//// } else {
//// /* single line text for home screen */
//// holder.view.itemText.isSingleLine = true
//// }
// }
//
// inner class TodoViewHolder(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 {
// databaseHandler.deleteTodo(todo.id)
// bottomSheetDialog.dismiss()
// todoManager?.refreshList()
// }
//
// /* 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()
// todoManager?.refreshList()
// } else {
// dialogBinding.todoInput.error = context.getString(R.string.empty_text_field)
// }
// }
// }
//
//}

View File

@ -1,129 +1,129 @@
/*
* 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.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import com.google.android.material.bottomsheet.BottomSheetDialog
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
import rasel.lunar.launcher.R
import rasel.lunar.launcher.databinding.TodoDialogBinding
import rasel.lunar.launcher.databinding.TodoManagerBinding
import java.util.*
internal class TodoManager : Fragment() {
private lateinit var binding: TodoManagerBinding
private lateinit var databaseHandler: DatabaseHandler
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
binding = TodoManagerBinding.inflate(inflater, container, false)
databaseHandler = DatabaseHandler(requireContext())
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
/* click listeners for add new and delete all buttons */
binding.addNew.setOnClickListener { addNewDialog() }
binding.deleteAll.setOnClickListener { deleteAllDialog() }
}
override fun onResume() {
super.onResume()
refreshList()
lActivity!!.viewPager.isUserInputEnabled = false
}
override fun onPause() {
super.onPause()
lActivity!!.viewPager.isUserInputEnabled = true
}
fun refreshList() {
binding.todos.adapter = TodoAdapter(this, requireContext())
}
/* add new dialog */
private fun addNewDialog() {
val bottomSheetDialog = BottomSheetDialog(lActivity!!, R.style.BottomSheetDialog)
val dialogBinding = TodoDialogBinding.inflate(LayoutInflater.from(requireContext()))
bottomSheetDialog.setContentView(dialogBinding.root)
bottomSheetDialog.show()
bottomSheetDialog.dismissWithAnimation = true
dialogBinding.deleteAllConfirmation.visibility = View.GONE
/* automatic keyboard popup */
dialogBinding.todoInput.requestFocus()
val inputMethodManager = lActivity!!.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.showSoftInput(dialogBinding.todoInput, InputMethodManager.SHOW_IMPLICIT)
/* dismiss the dialog on cancel button click */
dialogBinding.todoCancel.setOnClickListener { bottomSheetDialog.dismiss() }
/* add new item to the database */
dialogBinding.todoOk.setOnClickListener {
val todo = Todo()
val todoString = Objects.requireNonNull(dialogBinding.todoInput.text).toString().trim { it <= ' ' }
if (todoString.isNotEmpty()) {
todo.name = todoString
databaseHandler.addTodo(todo)
bottomSheetDialog.dismiss()
refreshList()
} else {
dialogBinding.todoInput.error = getString(R.string.empty_text_field)
}
}
}
/* delete all dialog */
private fun deleteAllDialog() {
val bottomSheetDialog = BottomSheetDialog(lActivity!!)
val dialogBinding = TodoDialogBinding.inflate(LayoutInflater.from(requireContext()))
bottomSheetDialog.setContentView(dialogBinding.root)
bottomSheetDialog.show()
bottomSheetDialog.dismissWithAnimation = true
/* if any item does not exist, then disable the ok button */
if (!databaseHandler.isTodoExists) {
dialogBinding.todoOk.isEnabled = false
}
dialogBinding.todoInput.visibility = View.GONE
dialogBinding.todoOk.setTextColor(ContextCompat.getColor(requireContext(), android.R.color.holo_red_light))
/* dismiss the dialog on cancel button click */
dialogBinding.todoCancel.setOnClickListener { bottomSheetDialog.dismiss() }
/* delete all the existing items from the database */
dialogBinding.todoOk.setOnClickListener {
databaseHandler.deleteAll()
bottomSheetDialog.dismiss()
refreshList()
}
}
}
///*
// * 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.content.Context
//import android.os.Bundle
//import android.view.LayoutInflater
//import android.view.View
//import android.view.ViewGroup
//import android.view.inputmethod.InputMethodManager
//import androidx.core.content.ContextCompat
//import androidx.fragment.app.Fragment
//import com.google.android.material.bottomsheet.BottomSheetDialog
//import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
//import rasel.lunar.launcher.R
//import rasel.lunar.launcher.databinding.TodoDialogBinding
//import rasel.lunar.launcher.databinding.TodoManagerBinding
//import java.util.*
//
//
//internal class TodoManager : Fragment() {
//
// private lateinit var binding: TodoManagerBinding
// private lateinit var databaseHandler: DatabaseHandler
//
// override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
//
// binding = TodoManagerBinding.inflate(inflater, container, false)
// databaseHandler = DatabaseHandler(requireContext())
//
// return binding.root
// }
//
// override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// super.onViewCreated(view, savedInstanceState)
// /* click listeners for add new and delete all buttons */
// binding.addNew.setOnClickListener { addNewDialog() }
// binding.deleteAll.setOnClickListener { deleteAllDialog() }
// }
//
// override fun onResume() {
// super.onResume()
// refreshList()
// lActivity!!.viewPager.isUserInputEnabled = false
// }
//
// override fun onPause() {
// super.onPause()
// lActivity!!.viewPager.isUserInputEnabled = true
// }
//
// fun refreshList() {
// binding.todos.adapter = TodoAdapter(this, requireContext())
// }
//
// /* add new dialog */
// private fun addNewDialog() {
// val bottomSheetDialog = BottomSheetDialog(lActivity!!, R.style.BottomSheetDialog)
// val dialogBinding = TodoDialogBinding.inflate(LayoutInflater.from(requireContext()))
// bottomSheetDialog.setContentView(dialogBinding.root)
// bottomSheetDialog.show()
// bottomSheetDialog.dismissWithAnimation = true
//
// dialogBinding.deleteAllConfirmation.visibility = View.GONE
// /* automatic keyboard popup */
// dialogBinding.todoInput.requestFocus()
// val inputMethodManager = lActivity!!.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
// inputMethodManager.showSoftInput(dialogBinding.todoInput, InputMethodManager.SHOW_IMPLICIT)
//
// /* dismiss the dialog on cancel button click */
// dialogBinding.todoCancel.setOnClickListener { bottomSheetDialog.dismiss() }
// /* add new item to the database */
// dialogBinding.todoOk.setOnClickListener {
// val todo = Todo()
// val todoString = Objects.requireNonNull(dialogBinding.todoInput.text).toString().trim { it <= ' ' }
// if (todoString.isNotEmpty()) {
// todo.name = todoString
// databaseHandler.addTodo(todo)
// bottomSheetDialog.dismiss()
// refreshList()
// } else {
// dialogBinding.todoInput.error = getString(R.string.empty_text_field)
// }
// }
// }
//
// /* delete all dialog */
// private fun deleteAllDialog() {
// val bottomSheetDialog = BottomSheetDialog(lActivity!!)
// val dialogBinding = TodoDialogBinding.inflate(LayoutInflater.from(requireContext()))
// bottomSheetDialog.setContentView(dialogBinding.root)
// bottomSheetDialog.show()
// bottomSheetDialog.dismissWithAnimation = true
//
// /* if any item does not exist, then disable the ok button */
// if (!databaseHandler.isTodoExists) {
// dialogBinding.todoOk.isEnabled = false
// }
//
// dialogBinding.todoInput.visibility = View.GONE
// dialogBinding.todoOk.setTextColor(ContextCompat.getColor(requireContext(), android.R.color.holo_red_light))
//
// /* dismiss the dialog on cancel button click */
// dialogBinding.todoCancel.setOnClickListener { bottomSheetDialog.dismiss() }
// /* delete all the existing items from the database */
// dialogBinding.todoOk.setOnClickListener {
// databaseHandler.deleteAll()
// bottomSheetDialog.dismiss()
// refreshList()
// }
// }
//
//}

View File

@ -0,0 +1,113 @@
package rasel.lunar.launcher.utils
import android.annotation.SuppressLint
import android.app.IntentService
import android.content.Context
import android.content.Intent
import android.database.Cursor
import android.os.IBinder
import android.provider.CallLog
import androidx.work.Data
import androidx.work.Worker
import androidx.work.WorkerParameters
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
import rasel.lunar.launcher.home.MissedCall
import java.text.SimpleDateFormat
import java.util.Date
class MissedCallGetter : Worker {
constructor(context: Context, workerParams: WorkerParameters) : super(context, workerParams) {
}
override fun doWork(): Result {
var resultData = Data.Builder()
var dateParam = Date(System.currentTimeMillis() - (1000 * 60 * 60 * 24)).time.toString()
lActivity?.contentResolver?.query(
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")?.let { managedCursor ->
try {
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)
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"
}
}
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)
}
missedCalls.forEach { t, u ->
resultData.put(t, u.toJson())
}
} catch (e: Exception) {
} finally {
managedCursor.close()
}
}
return Result.success(resultData.build());
}
}