This commit is contained in:
lunaticbum 2024-08-23 17:05:42 +09:00
parent 853bcc955f
commit b567dba95c
6 changed files with 321 additions and 11 deletions

View File

@ -24,7 +24,9 @@
<uses-permission
android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
<uses-permission
android:name="android.permission.READ_SMS"
tools:ignore="QueryAllPackagesPermission" />
<queries>
<intent>
<action android:name="android.intent.action.MAIN" />

View File

@ -140,8 +140,8 @@ internal class LauncherActivity : AppCompatActivity() {
/* ask for the permissions */
private fun askPermissions() {
/* phone permission */
if (this.checkSelfPermission(Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
this.requestPermissions(arrayOf(Manifest.permission.CALL_PHONE), 1)
if (this.checkSelfPermission(Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED || this.checkSelfPermission(Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED) {
this.requestPermissions(arrayOf(Manifest.permission.CALL_PHONE,Manifest.permission.READ_SMS), 1)
}
/* modify system settings */
if (!Settings.System.canWrite(this)) {

View File

@ -58,8 +58,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.SmsLogsAdapter
import rasel.lunar.launcher.utils.BLog
import rasel.lunar.launcher.utils.MissedCallGetter
import rasel.lunar.launcher.utils.RecentSmsGetter
import rasel.lunar.launcher.utils.RecentSmsLog
import rasel.lunar.launcher.utils.SimpleFingerGestures
import java.util.Calendar
import java.util.Locale
@ -84,7 +87,9 @@ internal class LauncherHome : Fragment() {
binding.favAppsGroup.visibility = View.GONE
mWorkManager = WorkManager.getInstance(lActivity!!.application);
mWorkManager?.enqueue(PeriodicWorkRequestBuilder<RecentSmsGetter>(30, TimeUnit.MINUTES).addTag("RecentSmsGetter").build())
mWorkManager?.enqueue(PeriodicWorkRequestBuilder<MissedCallGetter>(30, TimeUnit.MINUTES).addTag("MissedCallGetter").build())
mSmsWorkInfo = mWorkManager?.getWorkInfosByTagLiveData("RecentSmsGetter");
mSavedWorkInfo = mWorkManager?.getWorkInfosByTagLiveData("MissedCallGetter");
getOutputWorkInfo().observeForever {
it.last()?.outputData?.keyValueMap?.forEach { t, u ->
@ -101,15 +106,37 @@ internal class LauncherHome : Fragment() {
}
}
}
getSmsInfos().observeForever {
it.last()?.outputData?.keyValueMap?.forEach { t, u ->
try {
if (u is String) {
Gson().fromJson(u,RecentSmsLog::class.java)?.let {
smsList.add(it)
}
}
} catch (e : Exception) {
} finally {
showTodoList()
}
}
}
BLog.LOGE("onCreateView()")
return binding.root
}
private var mSavedWorkInfo: LiveData<List<WorkInfo>>? = null
private var mSmsWorkInfo: LiveData<List<WorkInfo>>? = null
fun getOutputWorkInfo(): LiveData<List<WorkInfo>> {
return mSavedWorkInfo!!
}
fun getSmsInfos(): LiveData<List<WorkInfo>> {
return mSmsWorkInfo!!
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
/* handle gesture events */
@ -131,6 +158,55 @@ internal class LauncherHome : Fragment() {
false
}
}
binding.missedCalls.setOnClickListener {
binding.missedCalls.isChecked = true
BLog.LOGE("binding.missedCalls >> ${binding.missedCalls.isChecked}")
if (callList.size > 0 && isAdded && isResumed && isVisible) {
try {
BLog.LOGE("callList >>> ${callList.size}")
binding.notes.adapter = MissedCallsAdapter(callList, requireContext())
binding.notes.invalidate()
} catch (e : Exception) {
}
}}
binding.recentSms.setOnClickListener {
binding.recentSms.isChecked = true
BLog.LOGE("binding.recentSms >> ${binding.recentSms.isChecked}")
if (smsList.size > 0 && isAdded && isResumed && isVisible) {
try {
BLog.LOGE("callList >>> ${smsList.size}")
binding.notes.adapter = SmsLogsAdapter(smsList, requireContext())
binding.notes.invalidate()
} catch (e : Exception) {
}
}
}
binding.summaryChoose.setOnCheckedChangeListener { group, checkedId ->
if (binding.missedCalls.isChecked) {
if (callList.size > 0 && isAdded && isResumed && isVisible) {
try {
BLog.LOGE("callList >>> ${callList.size}")
binding.notes.adapter = MissedCallsAdapter(callList, requireContext())
binding.notes.invalidate()
} catch (e : Exception) {
}
}
} else if(binding.recentSms.isChecked){
//binding.notes.adapter = TodoAdapter(null, requireContext())
if (smsList.size > 0 && isAdded && isResumed && isVisible) {
try {
BLog.LOGE("callList >>> ${callList.size}")
binding.notes.adapter = SmsLogsAdapter(smsList, requireContext())
binding.notes.invalidate()
} catch (e : Exception) {
}
}
}
}
}
override fun onResume() {
@ -160,7 +236,7 @@ internal class LauncherHome : Fragment() {
private var mWorkManager: WorkManager? = null
var callList = arrayListOf<MissedCall>()
var smsList = arrayListOf<RecentSmsLog>()
@ -434,8 +510,16 @@ internal class LauncherHome : Fragment() {
}
}
} else {
} else if(binding.recentSms.isChecked){
//binding.notes.adapter = TodoAdapter(null, requireContext())
if (smsList.size > 0 && isAdded && isResumed && isVisible) {
try {
BLog.LOGE("callList >>> ${callList.size}")
binding.notes.adapter = SmsLogsAdapter(smsList, requireContext())
} catch (e : Exception) {
}
}
}
}

View File

@ -0,0 +1,114 @@
/*
* 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 rasel.lunar.launcher.utils.RecentSmsLog
import java.util.*
import kotlin.collections.ArrayList
internal class SmsLogsAdapter(
private val callList: ArrayList<RecentSmsLog>,
private val context: Context) : RecyclerView.Adapter<SmsLogsAdapter.SmsLogHolder>() {
private val currentFragment = lActivity!!.supportFragmentManager.findFragmentById(R.id.mainFragmentsContainer)
override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): SmsLogHolder {
val binding = ListItemBinding.inflate(LayoutInflater.from(viewGroup.context), viewGroup, false)
return SmsLogHolder(binding)
}
override fun getItemCount(): Int {
// BLog.LOGE("callList.size >>> ${callList.size}")
return callList.size
}
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: SmsLogHolder, position: Int) {
val todo = callList[position]
BLog.LOGE("callList >>> ${callList[position]}")
holder.view.itemText.text = "\u25CF ${todo.person} ${todo.addr} , ${todo.body} : ${todo.pstDate} : ${todo.type}"
/* 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 {
true
}
}
inner class SmsLogHolder(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)
// }
// }
}
}

View File

@ -1,15 +1,12 @@
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 android.provider.Telephony
import androidx.work.Data
import androidx.work.Worker
import androidx.work.WorkerParameters
import com.google.gson.Gson
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
import rasel.lunar.launcher.home.MissedCall
import java.text.SimpleDateFormat
@ -111,3 +108,115 @@ class MissedCallGetter : Worker {
}
}
class RecentSmsGetter : Worker {
constructor(context: Context, workerParams: WorkerParameters) : super(context, workerParams) {
}
override fun doWork(): Result {
BLog.LOGE("phNumber == onStart")
var resultData = Data.Builder()
var dateParam = Date(System.currentTimeMillis() - (1000 * 60 * 60 * 24 * 3)).time.toString()
lActivity?.contentResolver?.query(
Telephony.Sms.CONTENT_URI, arrayOf(
Telephony.Sms.ADDRESS,
Telephony.Sms.TYPE,
Telephony.Sms.DATE,
Telephony.Sms.DATE_SENT,
Telephony.Sms.BODY,
Telephony.Sms.PERSON,
), Telephony.Sms.DATE + ">= ? OR " + Telephony.Sms.DATE_SENT + " >= ?", arrayOf<String>(dateParam, dateParam), Telephony.Sms.DEFAULT_SORT_ORDER)?.let { managedCursor ->
try {
BLog.LOGE("phNumber == onResult")
val address = managedCursor.getColumnIndex(Telephony.Sms.ADDRESS)
val type = managedCursor.getColumnIndex(Telephony.Sms.TYPE)
val date = managedCursor.getColumnIndex(Telephony.Sms.DATE)
val sendDate = managedCursor.getColumnIndex(Telephony.Sms.DATE_SENT)
val bodyIdx = managedCursor.getColumnIndex(Telephony.Sms.BODY)
val name = managedCursor.getColumnIndex(Telephony.Sms.PERSON)
var missedCalls = arrayListOf<RecentSmsLog>()
while (managedCursor.moveToNext()) {
val phNumber = managedCursor.getString(address) // mobile number
val callType = managedCursor.getString(type) // call type
val reciveDate = managedCursor.getString(date) // call date
val sendedDate = managedCursor.getString(sendDate) // call date
val smsBody = managedCursor.getString(bodyIdx)
val callerName = managedCursor.getString(name)
var dir: String = ""
val dircode = callType.toInt()
when (dircode) {
Telephony.Sms.MESSAGE_TYPE_ALL -> {dir = "MESSAGE_TYPE_ALL"}
Telephony.Sms.MESSAGE_TYPE_INBOX -> {dir = "MESSAGE_TYPE_INBOX"}
Telephony.Sms.MESSAGE_TYPE_SENT -> {dir = "MESSAGE_TYPE_SENT"}
Telephony.Sms.MESSAGE_TYPE_DRAFT -> {dir = "MESSAGE_TYPE_DRAFT"}
Telephony.Sms.MESSAGE_TYPE_OUTBOX -> {dir = "MESSAGE_TYPE_OUTBOX"}
Telephony.Sms.MESSAGE_TYPE_FAILED -> {dir = "MESSAGE_TYPE_FAILED"}
Telephony.Sms.MESSAGE_TYPE_QUEUED -> {dir = "MESSAGE_TYPE_QUEUED"}
}
BLog.LOGE("phNumber == ${phNumber}\n" +
" dir == ${dir}\n" +
" reciveDate == ${reciveDate}\n" +
" sendedDate == ${sendedDate}\n" +
" smsBody == ${smsBody}\n" +
" callerName == ${callerName}\n")
var log = RecentSmsLog(
phNumber,
dir,
reciveDate,
sendedDate,
smsBody,
callerName ?: ""
)
resultData.put(phNumber +" _"+ reciveDate, log.toJson())
}
// resultData.put()
} catch (e: Exception) {
} finally {
managedCursor.close()
}
}
return Result.success(resultData.build());
}
}
class RecentSmsLog {
var addr : String = ""
var type : String = ""
var rcvDate : String = ""
var pstDate : String = ""
var body : String = ""
var person : String = ""
constructor(
addr: String,
type: String,
rcvDate: String,
pstDate: String,
body: String,
person: String
) {
this.addr = addr
this.type = type
this.rcvDate = rcvDate
this.pstDate = pstDate
this.body = body
this.person = person
}
fun toJson() : String {
return Gson().toJson(this)
}
}

View File

@ -94,6 +94,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<RadioButton
android:id="@+id/recentSms"
android:gravity="center"
android:button="@null"
android:text="문자"