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 <uses-permission
android:name="android.permission.QUERY_ALL_PACKAGES" android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" /> tools:ignore="QueryAllPackagesPermission" />
<uses-permission
android:name="android.permission.READ_SMS"
tools:ignore="QueryAllPackagesPermission" />
<queries> <queries>
<intent> <intent>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />

View File

@ -140,8 +140,8 @@ internal class LauncherActivity : AppCompatActivity() {
/* ask for the permissions */ /* ask for the permissions */
private fun askPermissions() { private fun askPermissions() {
/* phone permission */ /* phone permission */
if (this.checkSelfPermission(Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) { 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), 1) this.requestPermissions(arrayOf(Manifest.permission.CALL_PHONE,Manifest.permission.READ_SMS), 1)
} }
/* modify system settings */ /* modify system settings */
if (!Settings.System.canWrite(this)) { 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.qaccess.QuickAccess
import rasel.lunar.launcher.settings.SettingsActivity import rasel.lunar.launcher.settings.SettingsActivity
import rasel.lunar.launcher.todos.MissedCallsAdapter import rasel.lunar.launcher.todos.MissedCallsAdapter
import rasel.lunar.launcher.todos.SmsLogsAdapter
import rasel.lunar.launcher.utils.BLog import rasel.lunar.launcher.utils.BLog
import rasel.lunar.launcher.utils.MissedCallGetter 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 rasel.lunar.launcher.utils.SimpleFingerGestures
import java.util.Calendar import java.util.Calendar
import java.util.Locale import java.util.Locale
@ -84,7 +87,9 @@ internal class LauncherHome : Fragment() {
binding.favAppsGroup.visibility = View.GONE binding.favAppsGroup.visibility = View.GONE
mWorkManager = WorkManager.getInstance(lActivity!!.application); 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()) mWorkManager?.enqueue(PeriodicWorkRequestBuilder<MissedCallGetter>(30, TimeUnit.MINUTES).addTag("MissedCallGetter").build())
mSmsWorkInfo = mWorkManager?.getWorkInfosByTagLiveData("RecentSmsGetter");
mSavedWorkInfo = mWorkManager?.getWorkInfosByTagLiveData("MissedCallGetter"); mSavedWorkInfo = mWorkManager?.getWorkInfosByTagLiveData("MissedCallGetter");
getOutputWorkInfo().observeForever { getOutputWorkInfo().observeForever {
it.last()?.outputData?.keyValueMap?.forEach { t, u -> 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()") BLog.LOGE("onCreateView()")
return binding.root return binding.root
} }
private var mSavedWorkInfo: LiveData<List<WorkInfo>>? = null private var mSavedWorkInfo: LiveData<List<WorkInfo>>? = null
private var mSmsWorkInfo: LiveData<List<WorkInfo>>? = null
fun getOutputWorkInfo(): LiveData<List<WorkInfo>> { fun getOutputWorkInfo(): LiveData<List<WorkInfo>> {
return mSavedWorkInfo!! return mSavedWorkInfo!!
} }
fun getSmsInfos(): LiveData<List<WorkInfo>> {
return mSmsWorkInfo!!
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
/* handle gesture events */ /* handle gesture events */
@ -131,6 +158,55 @@ internal class LauncherHome : Fragment() {
false 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() { override fun onResume() {
@ -160,7 +236,7 @@ internal class LauncherHome : Fragment() {
private var mWorkManager: WorkManager? = null private var mWorkManager: WorkManager? = null
var callList = arrayListOf<MissedCall>() 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()) //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 package rasel.lunar.launcher.utils
import android.annotation.SuppressLint
import android.app.IntentService
import android.content.Context import android.content.Context
import android.content.Intent
import android.database.Cursor
import android.os.IBinder
import android.provider.CallLog import android.provider.CallLog
import android.provider.Telephony
import androidx.work.Data import androidx.work.Data
import androidx.work.Worker import androidx.work.Worker
import androidx.work.WorkerParameters import androidx.work.WorkerParameters
import com.google.gson.Gson
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
import rasel.lunar.launcher.home.MissedCall import rasel.lunar.launcher.home.MissedCall
import java.text.SimpleDateFormat 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_width="wrap_content"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"/>
<RadioButton <RadioButton
android:id="@+id/recentSms"
android:gravity="center" android:gravity="center"
android:button="@null" android:button="@null"
android:text="문자" android:text="문자"