This commit is contained in:
lunaticbum 2024-09-11 18:09:16 +09:00
parent 87263747f3
commit 7b9dab0891
26 changed files with 1000 additions and 266 deletions

View File

@ -90,4 +90,6 @@ dependencies {
implementation ("org.jsoup:jsoup:1.18.1") implementation ("org.jsoup:jsoup:1.18.1")
implementation ("org.apache.commons:commons-text:1.12.0") implementation ("org.apache.commons:commons-text:1.12.0")
implementation("com.squareup.okhttp:okhttp:2.7.5") implementation("com.squareup.okhttp:okhttp:2.7.5")
// implementation ("androidx.window:window:1.0.0")
// implementation("io.github.vaneproject:hanguleditor:1.0.0")
} }

View File

@ -20,6 +20,7 @@ package rasel.lunar.launcher
//import rasel.lunar.launcher.home.LauncherHome.Companion.rssSet //import rasel.lunar.launcher.home.LauncherHome.Companion.rssSet
import android.Manifest import android.Manifest
import android.annotation.SuppressLint
import android.app.NotificationManager import android.app.NotificationManager
import android.appwidget.AppWidgetManager import android.appwidget.AppWidgetManager
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
@ -37,12 +38,15 @@ import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Environment import android.os.Environment
import android.os.Environment.isExternalStorageManager import android.os.Environment.isExternalStorageManager
import android.os.Handler
import android.os.Looper
import android.print.PDFPrint import android.print.PDFPrint
import android.provider.Settings import android.provider.Settings
import android.telephony.TelephonyManager import android.telephony.TelephonyManager
import android.view.View import android.view.View
import android.view.WindowInsets import android.view.WindowInsets
import android.view.WindowManager import android.view.WindowManager
import android.webkit.JavascriptInterface import android.webkit.JavascriptInterface
import android.webkit.SslErrorHandler import android.webkit.SslErrorHandler
import android.webkit.WebResourceError import android.webkit.WebResourceError
@ -63,8 +67,12 @@ import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding import androidx.core.view.updatePadding
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2 import androidx.viewpager2.widget.ViewPager2
import androidx.window.layout.FoldingFeature
import androidx.window.layout.WindowLayoutInfo
import androidx.work.ExistingPeriodicWorkPolicy import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.PeriodicWorkRequestBuilder import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager import androidx.work.WorkManager
@ -96,12 +104,15 @@ import rasel.lunar.launcher.model.RssTagItem
import rasel.lunar.launcher.model.getRssData import rasel.lunar.launcher.model.getRssData
import rasel.lunar.launcher.model.getT import rasel.lunar.launcher.model.getT
import rasel.lunar.launcher.utils.BLog import rasel.lunar.launcher.utils.BLog
import rasel.lunar.launcher.utils.JamoUtils
import rasel.lunar.launcher.utils.NLService import rasel.lunar.launcher.utils.NLService
import rasel.lunar.launcher.utils.RssList.jGuruMain import rasel.lunar.launcher.utils.RssList.jGuruMain
import rasel.lunar.launcher.utils.beforeDay import rasel.lunar.launcher.utils.beforeDay
import rasel.lunar.launcher.utils.make0H import rasel.lunar.launcher.utils.make0H
import rasel.lunar.launcher.workers.AppInfoGetter
import rasel.lunar.launcher.workers.ArcaGetter import rasel.lunar.launcher.workers.ArcaGetter
import rasel.lunar.launcher.workers.ClienGetter import rasel.lunar.launcher.workers.ClienGetter
import rasel.lunar.launcher.workers.ContactInfoGetter
import rasel.lunar.launcher.workers.DCGetter import rasel.lunar.launcher.workers.DCGetter
import rasel.lunar.launcher.workers.DotaxGetter import rasel.lunar.launcher.workers.DotaxGetter
import rasel.lunar.launcher.workers.FmKoreaGetter import rasel.lunar.launcher.workers.FmKoreaGetter
@ -160,16 +171,37 @@ internal class LauncherActivity : AppCompatActivity() {
}, 1, TimeUnit.SECONDS) }, 1, TimeUnit.SECONDS)
} }
fun refreshCalls() { fun refreshCalls() {
var delay = 1L
Executors.newSingleThreadScheduledExecutor().schedule({ Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(CALL_WORK_TAG) mWorkManager?.cancelAllWorkByTag(ContactInfoGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork( mWorkManager?.enqueueUniquePeriodicWork(
CALL_WORK_TAG, ContactInfoGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<ContactInfoGetter>(12, TimeUnit.HOURS)
.addTag(ContactInfoGetter.TAG)
.build())
}, delay, TimeUnit.SECONDS)
delay = delay + 3L
Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(AppInfoGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork(
AppInfoGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<AppInfoGetter>(12, TimeUnit.HOURS)
.addTag(AppInfoGetter.TAG)
.build())
}, delay, TimeUnit.SECONDS)
delay = delay + 3L
Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(RecentCallGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork(
RecentCallGetter.TAG,
ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<RecentCallGetter>(longTimePeriod, TimeUnit.MINUTES) PeriodicWorkRequestBuilder<RecentCallGetter>(longTimePeriod, TimeUnit.MINUTES)
.addTag(CALL_WORK_TAG) .addTag(RecentCallGetter.TAG)
.build()) .build())
}, 1, TimeUnit.SECONDS) }, delay, TimeUnit.SECONDS)
} }
fun refreshFeeds() { fun refreshFeeds() {
var delay = 5L var delay = 5L
Executors.newSingleThreadScheduledExecutor().schedule({ Executors.newSingleThreadScheduledExecutor().schedule({
@ -300,11 +332,13 @@ internal class LauncherActivity : AppCompatActivity() {
// } // }
} }
@SuppressLint("NewApi")
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
installSplashScreen() installSplashScreen()
mWorkManager = WorkManager.getInstance(this) mWorkManager = WorkManager.getInstance(this)
DynamicColors.applyToActivityIfAvailable(this) DynamicColors.applyToActivityIfAvailable(this)
settingsPrefs = getSharedPreferences(PREFS_SETTINGS, 0) settingsPrefs = getSharedPreferences(PREFS_SETTINGS, 0)
AppCompatDelegate.setDefaultNightMode(settingsPrefs.getInt(KEY_APPLICATION_THEME, MODE_NIGHT_FOLLOW_SYSTEM)) AppCompatDelegate.setDefaultNightMode(settingsPrefs.getInt(KEY_APPLICATION_THEME, MODE_NIGHT_FOLLOW_SYSTEM))
@ -325,28 +359,7 @@ internal class LauncherActivity : AppCompatActivity() {
/* handle navigation back events */ /* handle navigation back events */
handleBackPress() handleBackPress()
refreshSms()
refreshCalls()
refreshFeeds()
}
override fun onDestroy() {
super.onDestroy()
appWidgetHost?.stopListening()
}
override fun onStart() {
super.onStart()
BLog.LOGE("LauncherActivity onStart()")
statusBarView()
setBgColor()
}
@RequiresApi(Build.VERSION_CODES.O_MR1)
override fun onResume() {
super.onResume()
BLog.LOGE("LauncherActivity onResume")
val cn: ComponentName = ComponentName(this, NLService::class.java) val cn: ComponentName = ComponentName(this, NLService::class.java)
val n = applicationContext.getSystemService(NOTIFICATION_SERVICE) as NotificationManager val n = applicationContext.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
if (n.isNotificationListenerAccessGranted(cn)) { if (n.isNotificationListenerAccessGranted(cn)) {
@ -368,6 +381,25 @@ internal class LauncherActivity : AppCompatActivity() {
} }
} }
} }
}
override fun onDestroy() {
super.onDestroy()
appWidgetHost?.stopListening()
}
override fun onStart() {
super.onStart()
BLog.LOGE("LauncherActivity onStart()")
statusBarView()
setBgColor()
}
@RequiresApi(Build.VERSION_CODES.O_MR1)
override fun onResume() {
super.onResume()
BLog.LOGE("LauncherActivity onResume")
} }
private fun welcomeDialog() { private fun welcomeDialog() {
@ -397,6 +429,12 @@ internal class LauncherActivity : AppCompatActivity() {
}.show() }.show()
} }
} }
if (!needAsk) {
refreshSms()
refreshCalls()
refreshFeeds()
}
} }
/* ask for the permissions */ /* ask for the permissions */
@ -728,6 +766,18 @@ internal class LauncherActivity : AppCompatActivity() {
} }
} }
} else if(url?.contains("translate.google.com") == true) {
binding.searcher01.postDelayed({
binding.searcher01.evaluateJavascript(
"function getAll() {\n" +
" MyJavaScriptInterface.sendValueFromHtml(document.getElementsByTagName('html')[0].innerHTML)" +
" };getAll()"
) { result ->
(result as? String)?.let {
}
}
}, 6000L)
} else { } else {
//if (url?.contains("guru", true) == true) //if (url?.contains("guru", true) == true)
view?.evaluateJavascript( view?.evaluateJavascript(
@ -939,6 +989,29 @@ internal class LauncherActivity : AppCompatActivity() {
"date >>>>> ${date}" + "date >>>>> ${date}" +
"") "")
} }
} else if(lastedFinishedPageUrl?.contains("https://translate.google.com") == true){
callBackHandler.removeCallbacks(postNext)
val doc: Document = Jsoup.parse(result)
doc.getElementsByTag("span").forEach { span ->
// BLog.LOGE("on getHangule ${span.text()}")
if(span.hasAttr("jsaction") &&
span.attr("jsaction").contains("mouseout") &&
span.attr("jsaction").contains("contextmenu") &&
span.attr("jsaction").contains("click") &&
span.attr("jsaction").contains("mouseover")
) {
BLog.LOGE("on getHangule $span")
val resultString = span.text()
if (resultString != null && resultString.length > 0) {
callBackHandler.removeCallbacks(postNext)
callBack?.onConsoleLog("result::${span.text()}")
callBack = null
}
}
}.apply {
callBackHandler.removeCallbacks(postNext)
callBackHandler.postDelayed(postNext,25000L)
}
} else { } else {
val doc: Document = Jsoup.parse(result) val doc: Document = Jsoup.parse(result)
callBack?.onConsoleLog("lastedFinishedPageUrl >>> ${doc}") callBack?.onConsoleLog("lastedFinishedPageUrl >>> ${doc}")
@ -947,8 +1020,17 @@ internal class LauncherActivity : AppCompatActivity() {
} }
} }
var postNext : Runnable = Runnable{
callBack?.collectComplete()
}
val callBackHandler = Handler(Looper.getMainLooper())
} }
class MissD : RssDataInterface { class MissD : RssDataInterface {
var link : String? = null var link : String? = null
@ -981,6 +1063,10 @@ class MissD : RssDataInterface {
override fun category(): RssDataType { override fun category(): RssDataType {
return RssDataType.GURU return RssDataType.GURU
} }
override fun getCho(): String? {
return JamoUtils.split(title!!).joinToString("")
}
} }
fun beforeDay(date: Date): Long { fun beforeDay(date: Date): Long {
val cal: Calendar = Calendar.getInstance() val cal: Calendar = Calendar.getInstance()

View File

@ -33,7 +33,6 @@ import android.os.Looper
import android.provider.ContactsContract import android.provider.ContactsContract
import android.util.Log import android.util.Log
import android.view.KeyEvent import android.view.KeyEvent
import android.view.KeyEvent.ACTION_UP
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.View.GONE import android.view.View.GONE
@ -44,18 +43,36 @@ import androidx.appcompat.app.AlertDialog
import androidx.core.widget.doOnTextChanged import androidx.core.widget.doOnTextChanged
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import kotlinx.coroutines.GlobalScope import io.realm.kotlin.ext.query
import io.realm.kotlin.notifications.InitialResults
import io.realm.kotlin.notifications.ResultsChange
import io.realm.kotlin.notifications.UpdatedResults
import io.realm.kotlin.query.RealmResults
import io.realm.kotlin.query.Sort
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.jsoup.Jsoup
import rasel.lunar.launcher.BuildConfig import rasel.lunar.launcher.BuildConfig
import rasel.lunar.launcher.CommadCallabck
import rasel.lunar.launcher.LauncherActivity
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
import rasel.lunar.launcher.databinding.AppDrawerBinding import rasel.lunar.launcher.databinding.AppDrawerBinding
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_APPS_COUNT import rasel.lunar.launcher.helpers.Constants.Companion.KEY_APPS_COUNT
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_APPS_LAYOUT import rasel.lunar.launcher.helpers.Constants.Companion.KEY_APPS_LAYOUT
import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_APP_NAMES import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_APP_NAMES
import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_SETTINGS import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_SETTINGS
import rasel.lunar.launcher.model.AppInfo
import rasel.lunar.launcher.model.RssData
import rasel.lunar.launcher.utils.AlphabetToChosungMap
import rasel.lunar.launcher.utils.BLog import rasel.lunar.launcher.utils.BLog
import rasel.lunar.launcher.utils.JamoUtils
import rasel.lunar.launcher.workers.WorkersDb
import java.net.URLEncoder import java.net.URLEncoder
import java.text.Normalizer import java.text.Normalizer
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
import java.util.regex.Pattern import java.util.regex.Pattern
@ -63,36 +80,25 @@ internal class AppDrawer : Fragment() {
private lateinit var binding: AppDrawerBinding private lateinit var binding: AppDrawerBinding
private var layoutType: Int = 0 private var layoutType: Int = 0
// private var isSearchShown: Boolean = false // private var isSearchShown: Boolean = false
private var isKeyboardShowing: Boolean = false private var isKeyboardShowing: Boolean = false
companion object { companion object {
private var packageManager: PackageManager? = null private var packageManager: PackageManager? = null
private var appsAdapter: AppsAdapter? = null private var appsAdapter: AppsAdapter? = null
private var contactAdapter : ContactAdapter? = null private var contactAdapter : ContactAdapter? = null
private var packageInfoList: MutableList<ResolveInfo> = mutableListOf() private var packageList = mutableListOf<AppInfo>()
private var packageList = mutableListOf<Packages>()
var oringinPackageList = mutableListOf<Packages>()
val originContactList = arrayListOf<SimpleContact>()
// private val numberPattern = Pattern.compile("[0-9]")
// private val alphabetPattern = Pattern.compile("[A-Z]")
@JvmStatic var settingsPrefs: SharedPreferences? = null @JvmStatic var settingsPrefs: SharedPreferences? = null
@JvmStatic var appNamesPrefs: SharedPreferences? = null @JvmStatic var appNamesPrefs: SharedPreferences? = null
private fun appName(resolver: ResolveInfo): String { fun appName(resolver: ResolveInfo): String {
if(appNamesPrefs?.contains(resolver.activityInfo.packageName) != null && appNamesPrefs?.getString(resolver.activityInfo.packageName,"")?.length ?: 0 > 0) {
BLog.LOGE("it.activityInfo.packageName >>>> ${resolver.activityInfo.packageName} == name : ${appNamesPrefs?.getString(resolver.activityInfo.packageName,"") ?: ""}")
return appNamesPrefs?.getString(resolver.activityInfo.packageName,"") ?: ""
} else {
return resolver.loadLabel(packageManager).toString().apply { return resolver.loadLabel(packageManager).toString().apply {
appNamesPrefs?.edit()?.putString(resolver.activityInfo.packageName, this)?.apply() appNamesPrefs?.edit()?.putString(resolver.activityInfo.packageName, this)?.apply()
} }
} }
} fun getCategory(category : Int) : String {
private fun getCategory(category : Int) : String {
return when(category) { return when(category) {
ApplicationInfo.CATEGORY_UNDEFINED -> "UNDEFINED" ApplicationInfo.CATEGORY_UNDEFINED -> "UNDEFINED"
ApplicationInfo.CATEGORY_GAME -> "GAME" ApplicationInfo.CATEGORY_GAME -> "GAME"
@ -192,53 +198,8 @@ internal class AppDrawer : Fragment() {
} }
} }
val appNames = hashSetOf<AppInfo>()
val contactList = arrayListOf<SimpleContact>() val contactList = arrayListOf<SimpleContact>()
private fun GetContact() {
if (originContactList.size > 0) {
contactList.clear()
for (item in originContactList) {
contactList.add(item)
}
} else {
contactList.clear()
originContactList.clear()
val resolver = lActivity!!.contentResolver
val phoneUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI
val projection = arrayOf(
ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER,
)
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()
}
}
}
fun openSearchApps(schemeString : String, pakage : String? = null) { fun openSearchApps(schemeString : String, pakage : String? = null) {
val gmmIntentUri = Uri.parse(schemeString) val gmmIntentUri = Uri.parse(schemeString)
@ -281,7 +242,7 @@ internal class AppDrawer : Fragment() {
dialog?.setMessage("${keyword} 검색 결과 '${packageList[0].appName}' 준비됨") dialog?.setMessage("${keyword} 검색 결과 '${packageList[0].appName}' 준비됨")
dialog?.setPositiveButton("실행") { s, d -> dialog?.setPositiveButton("실행") { s, d ->
runonUi { runonUi {
startActivity(packageManager?.getLaunchIntentForPackage(packageList[0].packageName)) startActivity(packageManager?.getLaunchIntentForPackage(packageList[0].pkgName!!))
s.dismiss() s.dismiss()
} }
} }
@ -289,14 +250,14 @@ internal class AppDrawer : Fragment() {
dialog?.setMessage("${keyword} 검색 결과 '${filted[0].appName}' 준비됨") dialog?.setMessage("${keyword} 검색 결과 '${filted[0].appName}' 준비됨")
dialog?.setPositiveButton("${filted[0].appName} 실행") { s, d -> dialog?.setPositiveButton("${filted[0].appName} 실행") { s, d ->
runonUi { runonUi {
startActivity(packageManager?.getLaunchIntentForPackage(filted[0].packageName)) startActivity(packageManager?.getLaunchIntentForPackage(filted[0].pkgName!!))
s.dismiss() s.dismiss()
} }
} }
if(filted.size > 1) { if(filted.size > 1) {
dialog?.setNeutralButton("${filted[1].appName} 실행") { s, d -> dialog?.setNeutralButton("${filted[1].appName} 실행") { s, d ->
runonUi { runonUi {
startActivity(packageManager?.getLaunchIntentForPackage(filted[1].packageName)) startActivity(packageManager?.getLaunchIntentForPackage(filted[1].pkgName!!))
s.dismiss() s.dismiss()
} }
} }
@ -366,23 +327,10 @@ internal class AppDrawer : Fragment() {
super.onResume() super.onResume()
BLog.LOGE("onResume") BLog.LOGE("onResume")
fetchApps() fetchApps()
GetContact()
binding.appsCount.visibility = if (settingsPrefs!!.getBoolean(KEY_APPS_COUNT, true)) VISIBLE else GONE binding.appsCount.visibility = if (settingsPrefs!!.getBoolean(KEY_APPS_COUNT, true)) VISIBLE else GONE
// if (settingsPrefs!!.getInt(KEY_APPS_LAYOUT, 0) in 0..1) {
// appsAdapter?.updateGravity(settingsPrefs!!.getInt(KEY_DRAW_ALIGN, Gravity.CENTER))
// }
// openSearch()
// setKeyboardPadding()
contactList.sortBy { it.name }
contactAdapter?.updateData(contactList)
/* pop up the keyboard */
openSearch() openSearch()
registCancelSearch() registCancelSearch()
BLog.LOGE("onResume after chechHandler.postDelayed(cancelSearch, 3000L)") BLog.LOGE("onResume after chechHandler.postDelayed(cancelSearch, 3000L)")
} }
@ -420,35 +368,142 @@ internal class AppDrawer : Fragment() {
binding.appsList.adapter = appsAdapter binding.appsList.adapter = appsAdapter
binding.contactList.adapter = contactAdapter binding.contactList.adapter = contactAdapter
} }
var appQuery : RealmResults<AppInfo>? = null
/* update app list with app and package name */ fun fetchApps(keyword : String? = null) {
fun fetchApps() { WorkersDb.getRealm().apply {
var newQ = query<AppInfo>()
if (keyword != null && keyword.length > 0) {
if (JamoUtils.CHOSUNG.contains(keyword.split("")[0])) {
newQ = newQ.query("appName CONTAINS $0 OR appNameChosung CONTAINS $0 OR koreanName CONTAINS $0 OR alphaCho CONTAINS $0 OR category CONTAINS $0", keyword)
} else if(Pattern.matches("^[가-힣]*\$", keyword)){
newQ = newQ.query("appName CONTAINS $0 OR koreanName CONTAINS $0 OR category CONTAINS $0", keyword)
}else {
keyword.split("").forEach {
if (it.length > 0) {
newQ = newQ.query(
"appName CONTAINS $0 OR category CONTAINS $0 OR pkgName CONTAINS $0 OR appName CONTAINS $1 OR category CONTAINS $1 OR pkgName CONTAINS $1",
keyword.lowercase(),
keyword.uppercase()
)
}
}
}
}
appQuery = newQ.sort(Pair("clickCount", Sort.DESCENDING),Pair("lastUseDate",Sort.DESCENDING)).limit(20).find()
appQuery?.let {
if(it.size > 0) {
WorkersDb.getRealm().apply {
packageList.clear() packageList.clear()
oringinPackageList.clear() packageList.addAll(copyFromRealm(it))
try { BLog.LOGE("packageList >>> ${packageList.size}")
packageInfoList = (if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
packageManager?.queryIntentActivities(
Intent(Intent.ACTION_MAIN, null).addCategory(Intent.CATEGORY_LAUNCHER),
PackageManager.ResolveInfoFlags.of(0)
)
} else {
(packageManager?.queryIntentActivities(
Intent(Intent.ACTION_MAIN, null).addCategory(Intent.CATEGORY_LAUNCHER), 0
))
})?.apply {
removeIf { it.activityInfo.packageName.equals(BuildConfig.APPLICATION_ID) }
forEach { oringinPackageList.add(Packages(it.activityInfo.packageName, normalize(appName(it)), getCategory(it.activityInfo.applicationInfo.category))) }
oringinPackageList.sortBy { it.appName }
packageList.addAll(
oringinPackageList
)
binding.appsList.post { if (packageList.size > 0) { binding.appsList.post { if (packageList.size > 0) {
appsAdapter?.updateData(packageList) appsAdapter?.updateData(packageList)
} } } }
}!! // val clo = packageList.clone()
// appNames.clear()
// appNames.addAll(packageList.filter { it.koreanName?.trim()?.length ?: 0 < 1 })
// getHangule()
}
}
}
}
fetcContact(keyword)
}
} catch (e : Exception) {e.printStackTrace()}
var contactQuery : RealmResults<SimpleContact>? = null
fun fetcContact(keyword : String? = null) {
WorkersDb.getRealm().apply {
var newQ = query<SimpleContact>()
if (keyword != null && keyword.length > 0) {
if(Pattern.matches("^[0-9]*\$", keyword)){
keyword.split("").forEach {
if (it.length > 0) newQ = newQ.query("phoneNumber CONTAINS $0", keyword)
}
} else {
newQ = newQ.query(
"name CONTAINS $0 OR chosung CONTAINS $0",
keyword
)
}
}
contactQuery = newQ.sort(Pair("touchCount", Sort.DESCENDING),Pair("lastedTouchDateTime",Sort.DESCENDING)).find()
contactQuery?.let {
if (it.size > 0)
WorkersDb.getRealm().apply {
contactList.clear()
contactList.addAll(copyFromRealm(it).toList())
BLog.LOGE("packageList >>> ${contactList.size}")
binding.contactList.post { if (contactList.size > 0) {
contactAdapter?.updateData(contactList)
} }
}
}
}
}
fun getHangule() {
BLog.LOGE("on getHangule")
Executors.newSingleThreadScheduledExecutor().schedule({
if (appNames.size > 0) {
val info = appNames.first()
appNames.remove(info)
if (info.koreanName?.length ?: 0 > 0 || info.appNameChosung?.length ?: 0 > 0) {
getHangule()
} else {
BLog.LOGE("on getHangule ${info.appName}")
if (Pattern.matches("^[a-zA-Z]*$", info.appName)) {
// Jsoup.connect("https://translate.google.com/?hl=ko&sl=en&tl=ko&text=${info.appName}&op=translate").get().let { trans ->
// BLog.LOGE("on getHangule ${trans.title()}")
// trans.getElementsByTag("span").forEach {
// BLog.LOGE("on getHangule ${it.text()}")
// if(it.hasAttr("jsaction") &&
// it.attr("jsaction").contains("mouseout") &&
// it.attr("jsaction").contains("contextmenu") &&
// it.attr("jsaction").contains("mouseover")
// ) {
// BLog.LOGE("on getHangule $it")
// }
// }
//
// }.apply {
// getHangule()
// }
Handler(Looper.getMainLooper()).post {
LauncherActivity.Companion.lActivity?.doWebParseStart(
"https://translate.google.com/?hl=ko&sl=en&tl=ko&text=${info.appName}&op=translate",
object : CommadCallabck {
override fun onConsoleLog(log: String) {
if (log.contains("result::")) {
val appHangulName = log.split("result::")[1]
if(appHangulName?.length ?: 0 > 0) {
info.appNameChosung = JamoUtils.split(appHangulName).joinToString("")
info.koreanName = appHangulName
BLog.LOGE("appHangulName >>> $appHangulName")
BLog.LOGE("appHangulName >>> ${info.appNameChosung}")
WorkersDb.update(info)
getHangule()
}
}
}
override fun collectComplete() {
getHangule()
}
})
}
} else {
info.appNameChosung = JamoUtils.split(info.appName).joinToString("")
info.koreanName = info.appName
WorkersDb.update(info)
getHangule()
BLog.LOGE("on getHangule to next")
}
}
}
},5,TimeUnit.SECONDS)
} }
private fun getAlphabetItems() { private fun getAlphabetItems() {
@ -480,73 +535,52 @@ internal class AppDrawer : Fragment() {
var lastSearchString : String = "" var lastSearchString : String = ""
private fun filterAppsList(searchString: String) { private fun filterAppsList(searchString: String) {
/* check each app name and add if it matches the search string */ /* check each app name and add if it matches the search string */
if (searchString.length > 0 && (lastSearchStringLength != searchString.length || lastSearchString.equals(searchString) == false)) { fetchApps(searchString)
BLog.LOGE("START FILTER") // if (searchString.length > 0 && (lastSearchStringLength != searchString.length || lastSearchString.equals(searchString) == false)) {
packageList.clear() // BLog.LOGE("START FILTER")
for (pkg in oringinPackageList) { // packageList.clear()
if (pkg.appName.contains(searchString,true) || pkg.category.contains(searchString,true) || pkg.packageName.contains(searchString,true)) { // for (pkg in oringinPackageList) {
BLog.LOGE("pkg >>> ${pkg.category} , ${pkg.appName}") // if (pkg.appName!!.contains(searchString,true) || pkg.category!!.contains(searchString,true) || pkg.pkgName!!.contains(searchString,true)) {
packageList.add(pkg) // BLog.LOGE("pkg >>> ${pkg.category} , ${pkg.appName}")
} // packageList.add(pkg)
} // }
packageList.sortBy { it.appName } // }
BLog.LOGE("MIDDLE FILTER") // packageList.sortBy { it.appName }
// BLog.LOGE("MIDDLE FILTER")
appsAdapter?.updateData(packageList) //
// appsAdapter?.updateData(packageList)
contactList.clear() //
for (item in originContactList) { // contactList.clear()
if (item.name.contains(searchString) || item.phoneNumber.contains(searchString)) { // for (item in originContactList) {
contactList.add(item) // if (item.name!!.contains(searchString) || item.phoneNumber!!.contains(searchString)) {
} // contactList.add(item)
} // }
contactList.sortBy { it.name } // }
contactAdapter?.updateData(contactList) // contactList.sortBy { it.name }
BLog.LOGE("END FILTER") // contactAdapter?.updateData(contactList)
// BLog.LOGE("END FILTER")
//
} else if(lastSearchStringLength == 0){ //
contactList.clear() // } else if(lastSearchStringLength == 0){
for (item in originContactList) { // contactList.clear()
contactList.add(item) // for (item in originContactList) {
} // contactList.add(item)
packageList.clear() // }
for (resolver in oringinPackageList) { // packageList.clear()
packageList.add(resolver) // for (resolver in oringinPackageList) {
} // packageList.add(resolver)
appsAdapter?.updateData(packageList) // }
contactAdapter?.updateData(contactList) // appsAdapter?.updateData(packageList)
} else { // contactAdapter?.updateData(contactList)
afterClearSearch() // } else {
// afterClearSearch()
} //
// }
lastSearchString = searchString lastSearchString = searchString
lastSearchStringLength = searchString.length lastSearchStringLength = searchString.length
registCancelSearch() registCancelSearch()
} }
private fun afterClearSearch() {
contactList.clear()
packageList.clear()
for (item in originContactList) {
contactList.add(item)
}
for (resolver in oringinPackageList) {
packageList.add(resolver)
}
packageList.sortBy { it.appName }
contactList.sortBy { it.name }
appsAdapter?.updateData(packageList)
contactAdapter?.updateData(contactList)
}
private fun normalize(str: String): String {
val normalizedString =
Normalizer.normalize(str.replace("\\W".toRegex(), ""), Normalizer.Form.NFC)
val pattern = Pattern.compile("\\p{InCombiningDiacriticalMarks}+")
return pattern.matcher(normalizedString).replaceAll("").toLowerCase()
}
private fun openSearch() { private fun openSearch() {
binding.searchInput.apply { binding.searchInput.apply {
visibility = VISIBLE visibility = VISIBLE
@ -594,3 +628,9 @@ internal class AppDrawer : Fragment() {
} }
fun normalize(str: String): String {
val normalizedString =
Normalizer.normalize(str.replace("\\W".toRegex(), ""), Normalizer.Form.NFC)
val pattern = Pattern.compile("\\p{InCombiningDiacriticalMarks}+")
return pattern.matcher(normalizedString).replaceAll("").toLowerCase()
}

View File

@ -53,7 +53,6 @@ import com.google.gson.Gson
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
import rasel.lunar.launcher.R import rasel.lunar.launcher.R
import rasel.lunar.launcher.apps.AppDrawer.Companion.appNamesPrefs import rasel.lunar.launcher.apps.AppDrawer.Companion.appNamesPrefs
import rasel.lunar.launcher.apps.AppDrawer.Companion.oringinPackageList
import rasel.lunar.launcher.databinding.ActivityBrowserDialogBinding import rasel.lunar.launcher.databinding.ActivityBrowserDialogBinding
import rasel.lunar.launcher.databinding.AppInfoDialogBinding import rasel.lunar.launcher.databinding.AppInfoDialogBinding
import rasel.lunar.launcher.databinding.AppMenuBinding import rasel.lunar.launcher.databinding.AppMenuBinding

View File

@ -18,7 +18,6 @@
package rasel.lunar.launcher.apps package rasel.lunar.launcher.apps
import android.annotation.SuppressLint
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.util.TypedValue import android.util.TypedValue
import android.view.Gravity import android.view.Gravity
@ -26,18 +25,23 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import androidx.core.view.updatePadding
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.textview.MaterialTextView import io.realm.kotlin.ext.query
import kotlinx.coroutines.MainScope import kotlinx.coroutines.MainScope
import kotlinx.coroutines.async import kotlinx.coroutines.async
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
import rasel.lunar.launcher.R import rasel.lunar.launcher.R
import rasel.lunar.launcher.apps.IconPackManager.Companion.getDrawableIconForPackage import rasel.lunar.launcher.apps.IconPackManager.Companion.getDrawableIconForPackage
import rasel.lunar.launcher.databinding.AppsChildBinding import rasel.lunar.launcher.databinding.AppsChildBinding
import rasel.lunar.launcher.helpers.UniUtils.Companion.dpToPx import rasel.lunar.launcher.model.AppInfo
import rasel.lunar.launcher.utils.BLog
import rasel.lunar.launcher.utils.EnToKo.engToKor
import rasel.lunar.launcher.workers.WorkersDb
import java.util.regex.Matcher
import java.util.regex.Pattern
internal class AppsAdapter( internal class AppsAdapter(
@ -46,7 +50,7 @@ internal class AppsAdapter(
private val fragmentManager: FragmentManager, private val fragmentManager: FragmentManager,
private val appsCount: TextView) : RecyclerView.Adapter<AppsAdapter.AppsViewHolder>() { private val appsCount: TextView) : RecyclerView.Adapter<AppsAdapter.AppsViewHolder>() {
private var oldList = mutableListOf<Packages>() private var oldList = mutableListOf<AppInfo>()
// private var appGravity: Int = Gravity.CENTER // private var appGravity: Int = Gravity.CENTER
companion object { companion object {
@ -60,12 +64,14 @@ internal class AppsAdapter(
val item = oldList[i] val item = oldList[i]
holder.view.apply { holder.view.apply {
childTextview.text = item.appName childTextview.text = item.appName
appIconTwo.visibility = View.VISIBLE appIconTwo.visibility = View.VISIBLE
MainScope().async { MainScope().async {
getDrawableIconForPackage(item.packageName, packageManager.getApplicationIcon(item.packageName)) { getDrawableIconForPackage(item.pkgName, packageManager.getApplicationIcon(item.pkgName!!)) {
appIconTwo.post { appIconTwo.setImageDrawable(it) } appIconTwo.post { appIconTwo.setImageDrawable(it) }
} } } }
childTextview.apply { childTextview.apply {
@ -77,13 +83,23 @@ internal class AppsAdapter(
holder.view.root.apply { holder.view.root.apply {
/* on click - open app */ /* on click - open app */
setOnClickListener { setOnClickListener {
context.startActivity(packageManager.getLaunchIntentForPackage(item.packageName)) WorkersDb.getRealm().apply {
writeBlocking {
var result = query<AppInfo>("pkgName == $0",item.pkgName).find()
if(result.size > 0) {
val app = result.first()
app.clickCount = app.clickCount + 1
app.lastUseDate = Math.max(app.lastUseDate, System.currentTimeMillis())
}
}
}
context.startActivity(packageManager.getLaunchIntentForPackage(item.pkgName!!))
} }
/* on long click - open app menu */ /* on long click - open app menu */
setOnLongClickListener { setOnLongClickListener {
AppMenu().apply { AppMenu().apply {
}.show(fragmentManager, item.packageName) }.show(fragmentManager, item.pkgName)
true true
} }
} }
@ -94,7 +110,7 @@ internal class AppsAdapter(
inner class AppsViewHolder(var view: AppsChildBinding) : RecyclerView.ViewHolder(view.root) inner class AppsViewHolder(var view: AppsChildBinding) : RecyclerView.ViewHolder(view.root)
/* update app list */ /* update app list */
fun updateData(newList: List<Packages>) { fun updateData(newList: List<AppInfo>) {
val diffUtilResult = DiffUtil.calculateDiff(AppsDiffUtil(oldList, newList)) val diffUtilResult = DiffUtil.calculateDiff(AppsDiffUtil(oldList, newList))
// //
diffUtilResult.dispatchUpdatesTo(this) diffUtilResult.dispatchUpdatesTo(this)
@ -114,14 +130,14 @@ data class Packages (
) )
internal class AppsDiffUtil( internal class AppsDiffUtil(
private val oldList: List<Packages>, private val newList: List<Packages> private val oldList: List<AppInfo>, private val newList: List<AppInfo>
) : DiffUtil.Callback() { ) : DiffUtil.Callback() {
override fun getOldListSize(): Int = oldList.size override fun getOldListSize(): Int = oldList.size
override fun getNewListSize(): Int = newList.size override fun getNewListSize(): Int = newList.size
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean = override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean =
oldList[oldItemPosition].packageName == newList[newItemPosition].packageName oldList[oldItemPosition].pkgName == newList[newItemPosition].pkgName
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean = override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean =
oldList[oldItemPosition] == newList[newItemPosition] oldList[oldItemPosition] == newList[newItemPosition]

View File

@ -33,6 +33,8 @@ import androidx.fragment.app.FragmentManager
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.textview.MaterialTextView import com.google.android.material.textview.MaterialTextView
import io.realm.kotlin.types.RealmObject
import io.realm.kotlin.types.annotations.PrimaryKey
import kotlinx.coroutines.MainScope import kotlinx.coroutines.MainScope
import kotlinx.coroutines.async import kotlinx.coroutines.async
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
@ -42,6 +44,9 @@ import rasel.lunar.launcher.databinding.AppsChildBinding
import rasel.lunar.launcher.databinding.ContactItemBinding import rasel.lunar.launcher.databinding.ContactItemBinding
import rasel.lunar.launcher.helpers.UniUtils.Companion.dpToPx import rasel.lunar.launcher.helpers.UniUtils.Companion.dpToPx
import rasel.lunar.launcher.utils.BLog import rasel.lunar.launcher.utils.BLog
import rasel.lunar.launcher.utils.JamoUtils
import rasel.lunar.launcher.workers.RecentCallGetter
import java.util.Date
internal class ContactAdapter ( internal class ContactAdapter (
@ -60,13 +65,14 @@ internal class ContactAdapter (
override fun onBindViewHolder(holder: ContactViewHolder, i: Int) { override fun onBindViewHolder(holder: ContactViewHolder, i: Int) {
val item = oldList[i] val item = oldList[i]
BLog.LOGE("name >>> ${item.name} :: ${item.touchCount} :: ${RecentCallGetter.dateFormat.format(
Date(item.lastedTouchDateTime)
)}")
holder.view.apply { holder.view.apply {
name.text = item.name name.text = item.name
number.text= item.phoneNumber number.text= item.phoneNumber
} }
holder.view.root.apply { holder.view.root.apply {
/* on click - open app */ /* on click - open app */
setOnClickListener { setOnClickListener {
@ -88,6 +94,8 @@ internal class ContactAdapter (
/* update app list */ /* update app list */
fun updateData(newList: List<SimpleContact>) { fun updateData(newList: List<SimpleContact>) {
synchronized(oldList) {
try {
val diffUtilResult = DiffUtil.calculateDiff(ContactDiffUtil(oldList, newList)) val diffUtilResult = DiffUtil.calculateDiff(ContactDiffUtil(oldList, newList))
diffUtilResult.dispatchUpdatesTo(this) diffUtilResult.dispatchUpdatesTo(this)
oldList.clear() oldList.clear()
@ -95,6 +103,10 @@ internal class ContactAdapter (
newList.size.let { newList.size.let {
appsSize = it appsSize = it
} }
}catch (e : IndexOutOfBoundsException) {
}
}
} }
/* update text gravity (alignment) */ /* update text gravity (alignment) */
@ -112,7 +124,25 @@ internal class ContactAdapter (
} }
} }
data class SimpleContact(val id : String,val name : String ,val phoneNumber : String) class SimpleContact : RealmObject {
@PrimaryKey
var id : String? = ""
var name : String? = ""
var chosung : String? = ""
var phoneNumber : String? = ""
var touchCount = 0
var lastedTouchDateTime = 0L
constructor(id: String, name: String, phoneNumber: String) {
this.id = id
this.name = name
this.phoneNumber = phoneNumber
chosung = JamoUtils.split(name).joinToString("")
}
constructor()
}
internal class ContactDiffUtil( internal class ContactDiffUtil(
private val oldList: List<SimpleContact>, private val newList: List<SimpleContact> private val oldList: List<SimpleContact>, private val newList: List<SimpleContact>

View File

@ -62,7 +62,9 @@ import rasel.lunar.launcher.CommadCallabck
import rasel.lunar.launcher.LauncherActivity.Companion.appWidgetHost import rasel.lunar.launcher.LauncherActivity.Companion.appWidgetHost
import rasel.lunar.launcher.LauncherActivity.Companion.appWidgetManager import rasel.lunar.launcher.LauncherActivity.Companion.appWidgetManager
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
import rasel.lunar.launcher.LauncherActivity.Companion.refreshCalls
import rasel.lunar.launcher.LauncherActivity.Companion.refreshFeeds import rasel.lunar.launcher.LauncherActivity.Companion.refreshFeeds
import rasel.lunar.launcher.LauncherActivity.Companion.refreshSms
import rasel.lunar.launcher.R import rasel.lunar.launcher.R
import rasel.lunar.launcher.databinding.FeedsBinding import rasel.lunar.launcher.databinding.FeedsBinding
import rasel.lunar.launcher.feeds.rss.RssAdapter import rasel.lunar.launcher.feeds.rss.RssAdapter
@ -313,6 +315,8 @@ internal class Feeds : Fragment() , CommadCallabck {
"req" -> { "req" -> {
refreshFeeds() refreshFeeds()
refreshCalls()
refreshSms()
consoleLog("excute refreshFeeds()") consoleLog("excute refreshFeeds()")
} }

View File

@ -30,6 +30,7 @@ import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.os.PatternMatcher
import android.provider.AlarmClock import android.provider.AlarmClock
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -64,6 +65,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONObject import org.json.JSONObject
@ -110,6 +112,7 @@ import java.nio.charset.Charset
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Calendar import java.util.Calendar
import java.util.Date import java.util.Date
import java.util.regex.Pattern
internal class LauncherHome : Fragment() { internal class LauncherHome : Fragment() {
@ -123,7 +126,7 @@ internal class LauncherHome : Fragment() {
companion object { companion object {
var home : LauncherHome? = null var home : LauncherHome? = null
var lastedFinishedPageUrl : String = "" var lastedFinishedPageUrl : String = ""
var recentCalls = arrayListOf<RecentCall>() // var recentCalls = arrayListOf<RecentCall>()
var callList = arrayListOf<RecentCall>() var callList = arrayListOf<RecentCall>()
var smsList = arrayListOf<RecentSms>() var smsList = arrayListOf<RecentSms>()
var listTags = arrayListOf<RssDataInterface>() var listTags = arrayListOf<RssDataInterface>()
@ -147,8 +150,7 @@ internal class LauncherHome : Fragment() {
} }
val callUpdate = Runnable { val callUpdate = Runnable {
binding.missedCalls.text = "최근 통화 [${recentCalls.size}]"
BLog.LOGE("observeForever missedCalls.size >>> ${recentCalls.size}")
chooseAdpater() chooseAdpater()
} }
@ -352,17 +354,33 @@ internal class LauncherHome : Fragment() {
var rQ = WorkersDb.getRealm().query<RssData>().query("pubDate > $0", beforeDay(Date(),3)) var rQ = WorkersDb.getRealm().query<RssData>().query("pubDate > $0", beforeDay(Date(),3))
if(keyword.length > 0) if(keyword.length > 0)
keyword.split("").forEach { keyword.split("").forEach {
if (Character.codePointAt(it, 0) in 0xAC00..0xD79D) { BLog.LOGE("queryInfos it >>> ${it}")
rQ = rQ.query("title CONTAINS $0 OR chosung CONTAINS $1 ", it, JamoUtils.splitOne(it)) if (it.length > 0) {
} else { if (JamoUtils.CHOSUNG.contains(it)) {
rQ = rQ.query("title CONTAINS $0 OR title CONTAINS $1", it.toUpperCase(), it.toLowerCase()) rQ = rQ.query(
"title CONTAINS $0 OR chosung CONTAINS $1 ",
it,
it
)
} else if(Pattern.matches("^[가-힣]*\$", it)){
rQ = rQ.query(
"title CONTAINS $0",
it
)
}else {
rQ = rQ.query(
"title CONTAINS $0 OR title CONTAINS $1",
it.toUpperCase(),
it.toLowerCase()
)
}
} }
} }
category?.let { category?.let {
rQ = rQ.query("category == $0", it) rQ = rQ.query("category == $0", it)
} }
BLog.LOGE("queryInfos rQ.description() >>>>> ${rQ.description()}")
//limit(1000) //limit(1000)
mRssDataResult = rQ.sort("pubDate ", Sort.DESCENDING).find() mRssDataResult = rQ.sort("pubDate ", Sort.DESCENDING).find()
BLog.LOGE("${this} ::::: queryInfos after query find >>>> ") BLog.LOGE("${this} ::::: queryInfos after query find >>>> ")
@ -573,21 +591,19 @@ internal class LauncherHome : Fragment() {
binding.smsList.visibility = View.INVISIBLE binding.smsList.visibility = View.INVISIBLE
binding.infoList.visibility = View.INVISIBLE binding.infoList.visibility = View.INVISIBLE
binding.notiList.visibility = View.INVISIBLE binding.notiList.visibility = View.INVISIBLE
var dateParam = beforeDay(Date(),7).toString()
if (binding.missedCalls.isSelected) { if (binding.missedCalls.isSelected) {
if (recentCalls.size > 0) { WorkersDb.getRealm().apply {
try { val result = query<RecentCall>().query("callDayTime >= $0", dateParam).sort("callDayTime", Sort.DESCENDING).find()
callList.clear() callList.clear()
callList.addAll(recentCalls) callList.addAll(copyFromRealm(result))
callList.sortByDescending { it.date } binding.missedCalls.text = "최근 통화 [${callList.size}]"
// Handler(Looper.getMainLooper()).post {
binding.mainList.visibility = View.VISIBLE binding.mainList.visibility = View.VISIBLE
mMissedCallsAdapter.updateData(callList) mMissedCallsAdapter.updateData(callList)
binding.recentSms.isSelected = false binding.recentSms.isSelected = false
binding.otherCheck.isSelected = false binding.otherCheck.isSelected = false
binding.notice.isSelected = false binding.notice.isSelected = false
} catch (e : Exception) {
}
} }
} else if(binding.recentSms.isSelected){ } else if(binding.recentSms.isSelected){
if (smsList.size > 0) { if (smsList.size > 0) {

View File

@ -0,0 +1,19 @@
package rasel.lunar.launcher.model
import io.realm.kotlin.types.RealmObject
import io.realm.kotlin.types.annotations.PrimaryKey
class AppInfo : RealmObject {
var appName : String? = null
var appNameChosung : String? = null
var koreanName : String? = null
var alphaCho : String? = null
@PrimaryKey
var pkgName : String? = null
var clickCount : Int = 0
var lastUseDate : Long = 0L
var category : String? = null
}

View File

@ -103,6 +103,9 @@ class Arca : RssDataInterface {
override fun category(): RssDataType { override fun category(): RssDataType {
return RssDataType.Arca return RssDataType.Arca
} }
override fun getCho(): String? {
return JamoUtils.split(title!!).joinToString("")
}
} }
@ -169,6 +172,9 @@ open class DcInside : RssDataInterface {
return RssDataType.DcInside return RssDataType.DcInside
} }
override fun getCho(): String? {
return JamoUtils.split(title!!).joinToString("")
}
} }
@ -205,7 +211,7 @@ class RssData : RealmObject, RssDataInterface {
} }
else -> title ?: "" else -> title ?: ""
}.apply { }.apply {
chosung = JamoUtils.split(this).joinToString { "" } chosung = JamoUtils.split(this).joinToString("")
} }
} }
@ -240,6 +246,9 @@ class RssData : RealmObject, RssDataInterface {
return mRssDataType!! return mRssDataType!!
} }
override fun getCho(): String? {
return chosung
}
} }
@ -319,6 +328,9 @@ open class Dotax(var pageLink : String,
override fun category(): RssDataType { override fun category(): RssDataType {
return RssDataType.Dotax return RssDataType.Dotax
} }
override fun getCho(): String? {
return JamoUtils.split(title!!).joinToString("")
}
} }
data class FmKorea(var apageLink : String, data class FmKorea(var apageLink : String,
@ -341,6 +353,7 @@ fun RssDataInterface.getRssData() : RssData {
originPage = this@getRssData.originPage() originPage = this@getRssData.originPage()
thumbnail = this@getRssData.thumbnailUrl() thumbnail = this@getRssData.thumbnailUrl()
pubDate = this@getRssData.pubDate() pubDate = this@getRssData.pubDate()
chosung = this@getRssData.getCho()
category = this@getRssData.category().name category = this@getRssData.category().name
} }
} }

View File

@ -2,6 +2,7 @@ package rasel.lunar.launcher.model
import rasel.lunar.launcher.todos.Image import rasel.lunar.launcher.todos.Image
import rasel.lunar.launcher.todos.Source import rasel.lunar.launcher.todos.Source
import rasel.lunar.launcher.utils.JamoUtils
class Child { class Child {
@ -275,7 +276,9 @@ class Data : RssDataInterface {
RssDataType.REDDIT_nsfw RssDataType.REDDIT_nsfw
} else RssDataType.REDDIT } else RssDataType.REDDIT
} }
override fun getCho(): String? {
return JamoUtils.split(title!!).joinToString("")
}
} }
class Gif { class Gif {

View File

@ -51,6 +51,6 @@ interface RssDataInterface {
fun description() : String fun description() : String
fun pubDate() : Long fun pubDate() : Long
fun category() : RssDataType fun category() : RssDataType
fun getCho() : String?
} }

View File

@ -1,5 +1,7 @@
package rasel.lunar.launcher.model package rasel.lunar.launcher.model
import rasel.lunar.launcher.utils.JamoUtils
open class RssItem : RssDataInterface { open class RssItem : RssDataInterface {
var model : String = "" var model : String = ""
var title : String = "" var title : String = ""
@ -51,6 +53,10 @@ open class RssItem : RssDataInterface {
} }
fun isValid() = (((pageLink.length ?:0) > 0) && ((title.length ?:0) > 0)&& ((image.length ?:0) > 0)) fun isValid() = (((pageLink.length ?:0) > 0) && ((title.length ?:0) > 0)&& ((image.length ?:0) > 0))
override fun getCho(): String? {
return JamoUtils.split(title!!).joinToString("")
}
} }
class MostItem : RssItem , RssDataInterface { class MostItem : RssItem , RssDataInterface {
@ -81,5 +87,7 @@ class MostItem : RssItem , RssDataInterface {
return RssDataType.Most return RssDataType.Most
} }
override fun getCho(): String? {
return JamoUtils.split(title!!).joinToString("")
}
} }

View File

@ -1,5 +1,7 @@
package rasel.lunar.launcher.model package rasel.lunar.launcher.model
import rasel.lunar.launcher.utils.JamoUtils
class RssTagItem : RssDataInterface { class RssTagItem : RssDataInterface {
var link : String = "" var link : String = ""
var tagTitle = "" var tagTitle = ""
@ -38,4 +40,7 @@ class RssTagItem : RssDataInterface {
}catch (e : Exception) {} }catch (e : Exception) {}
} }
} }
override fun getCho(): String? {
return JamoUtils.split(tagTitle!!).joinToString("")
}
} }

View File

@ -1,6 +1,7 @@
package rasel.lunar.launcher.model package rasel.lunar.launcher.model
import org.json.JSONObject import org.json.JSONObject
import rasel.lunar.launcher.utils.JamoUtils
import rasel.lunar.launcher.utils.afterDay import rasel.lunar.launcher.utils.afterDay
import rasel.lunar.launcher.utils.beforeDay import rasel.lunar.launcher.utils.beforeDay
import java.util.Date import java.util.Date
@ -1644,6 +1645,9 @@ open class VideoRenderer : RssDataInterface {
override fun category(): RssDataType { override fun category(): RssDataType {
return RssDataType.YOUTUBE return RssDataType.YOUTUBE
} }
override fun getCho(): String? {
return JamoUtils.split(title()).joinToString("")
}
} }
class ViewCountText { class ViewCountText {

View File

@ -7,6 +7,7 @@ import org.xmlpull.v1.XmlPullParserException
import rasel.lunar.launcher.model.RssDataInterface import rasel.lunar.launcher.model.RssDataInterface
import rasel.lunar.launcher.model.RssDataType import rasel.lunar.launcher.model.RssDataType
import rasel.lunar.launcher.utils.BLog import rasel.lunar.launcher.utils.BLog
import rasel.lunar.launcher.utils.JamoUtils
import rasel.lunar.launcher.utils.beforeDay import rasel.lunar.launcher.utils.beforeDay
import java.io.IOException import java.io.IOException
import java.io.InputStream import java.io.InputStream
@ -211,4 +212,7 @@ class RssFeed : RssDataInterface {
override fun category(): RssDataType { override fun category(): RssDataType {
return RssDataType.NewsFeed return RssDataType.NewsFeed
} }
override fun getCho(): String? {
return JamoUtils.split(title()).joinToString("")
}
} }

View File

@ -34,6 +34,7 @@ import com.squareup.picasso.Picasso
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
import rasel.lunar.launcher.R import rasel.lunar.launcher.R
import rasel.lunar.launcher.databinding.ListItemWithBinding import rasel.lunar.launcher.databinding.ListItemWithBinding
import rasel.lunar.launcher.model.RssData
import rasel.lunar.launcher.model.RssDataInterface import rasel.lunar.launcher.model.RssDataInterface
import rasel.lunar.launcher.model.RssDataType import rasel.lunar.launcher.model.RssDataType
import rasel.lunar.launcher.utils.BLog import rasel.lunar.launcher.utils.BLog
@ -147,7 +148,6 @@ internal class RssItemAdapter (
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: RssTag, position: Int) { override fun onBindViewHolder(holder: RssTag, position: Int) {
val rssData = rssDataItemLis[position] val rssData = rssDataItemLis[position]
if (rssData.pubDate() > 1000L) { if (rssData.pubDate() > 1000L) {
holder.view.date.text = dateFormat.format(Date(rssData.pubDate())) holder.view.date.text = dateFormat.format(Date(rssData.pubDate()))
} else { } else {

View File

@ -5,6 +5,7 @@ import rasel.lunar.launcher.model.RssDataInterface
import rasel.lunar.launcher.model.RssDataType import rasel.lunar.launcher.model.RssDataType
import rasel.lunar.launcher.model.YTBImage import rasel.lunar.launcher.model.YTBImage
import rasel.lunar.launcher.model.YTBSource import rasel.lunar.launcher.model.YTBSource
import rasel.lunar.launcher.utils.JamoUtils
import rasel.lunar.launcher.utils.afterDay import rasel.lunar.launcher.utils.afterDay
import rasel.lunar.launcher.utils.beforeDay import rasel.lunar.launcher.utils.beforeDay
import java.util.Date import java.util.Date
@ -1648,6 +1649,10 @@ open class VideoRenderer : RssDataInterface {
override fun category(): RssDataType { override fun category(): RssDataType {
return RssDataType.YOUTUBE return RssDataType.YOUTUBE
} }
override fun getCho(): String? {
return JamoUtils.split(title()).joinToString("")
}
} }
class ViewCountText { class ViewCountText {

View File

@ -0,0 +1,45 @@
package rasel.lunar.launcher.utils
object AlphabetToChosungMap {
val map = hashMapOf<String,String>(
Pair("a","o"),
Pair("b",""),
Pair("c","ㅋㅅ"),
Pair("d",""),
Pair("e","o"),
Pair("f",""),
Pair("g","ㄱㅈ"),
Pair("h",""),
Pair("i","o"),
Pair("j",""),
Pair("k",""),
Pair("l",""),
Pair("m",""),
Pair("n",""),
Pair("o","o"),
Pair("p",""),
Pair("q",""),
Pair("r",""),
Pair("s",""),
Pair("t",""),
Pair("u","o"),
Pair("v",""),
Pair("w","o"),
Pair("x","ㅋㅅㅈ"),
Pair("y",""),
Pair("z",""),
Pair("10","ㅅㅌ"),
Pair("0","ㅇㅈ"),
Pair("9","ㄱㄴ"),
Pair("8","ㅍㅇ"),
Pair("7","ㅊㅅ"),
Pair("6","ㅇㅅ"),
Pair("5","ㅇㅍ"),
Pair("4","ㅅㅍ"),
Pair("3","ㅅㅆ"),
Pair("2","ㅇㅌ"),
Pair("1",""),
)
fun getCho(string : String) = string.split("").filter { it.length > 0 && map.containsKey(it.toLowerCase()) }.map { map.get(it) }.joinToString("")
}

View File

@ -0,0 +1,238 @@
package rasel.lunar.launcher.utils
import java.util.Scanner
import java.util.regex.Matcher
object EnToKo {
var ignoreChars: String = "`1234567890-=[]\\;',./~!@#$%^&*()_+{}|:\"<>? "
/** * 영어를 한글로... */
fun engToKor(eng: String): String {
val sb = StringBuffer()
var initialCode = 0
var medialCode = 0
var finalCode = 0
var tempMedialCode: Int
var tempFinalCode: Int
var i = 0
while (i < eng.length) {
// 숫자특수문자 처리
if (ignoreChars.indexOf(eng.substring(i, i + 1)) > -1) {
sb.append(eng.substring(i, i + 1))
i++
continue
}
// 초성코드 추출
initialCode = getCode(CodeType.chosung, eng.substring(i, i + 1))
i++
// 다음문자로
// 중성코드 추출
tempMedialCode = getDoubleMedial(i, eng)
// 두 자로 이루어진 중성코드 추출
if (tempMedialCode != -1) {
medialCode = tempMedialCode
i += 2
} else {
// 없다면,
medialCode = getSingleMedial(i, eng)
// 한 자로 이루어진 중성코드 추출
i++
}
// 종성코드 추출
tempFinalCode = getDoubleFinal(i, eng)
// 두 자로 이루어진 종성코드 추출
if (tempFinalCode != -1) {
finalCode = tempFinalCode
// 그 다음의 중성 문자에 대한 코드를 추출한다.
tempMedialCode = getSingleMedial(i + 2, eng)
if (tempMedialCode != -1) {
// 코드 값이 있을 경우
finalCode = getSingleFinal(i, eng)
// 종성 코드 값을 저장한다.
} else {
i++
}
} else {
// 코드 값이 없을 경우 ,
tempMedialCode = getSingleMedial(i + 1, eng)
// 그 다음의 중성 문자에 대한 코드 추출.
if (tempMedialCode != -1) {
// 그 다음에 중성 문자가 존재할 경우,
finalCode = 0 // 종성 문자는 없음.
i--
} else {
finalCode = getSingleFinal(i, eng)
// 종성 문자 추출
if (finalCode == -1) {
finalCode = 0
i--
// 초성,중성 + 숫자,특수문자,
//기호가 나오는 경우 index를 줄임.
}
}
}
// 추출한 초성 문자 코드,
//중성 문자 코드, 종성 문자 코드를 합한 후 변환하여 스트링버퍼에 넘김
sb.append((0xAC00 + initialCode + medialCode + finalCode).toChar())
i++
}
return sb.toString()
}
/** * 해당 문자에 따른 코드를 추출한다. * * @param type * 초성 : chosung, 중성 : jungsung, 종성 : jongsung 구분 * @param char 해당 문자 */
private fun getCode(type: CodeType, c: String): Int {
// 초성
val init = "rRseEfaqQtTdwWczxvg"
// 중성
val mid = arrayOf(
"k",
"o",
"i",
"O",
"j",
"p",
"u",
"P",
"h",
"hk",
"ho",
"hl",
"y",
"n",
"nj",
"np",
"nl",
"b",
"m",
"ml",
"l"
)
// 종성
val fin = arrayOf(
"r",
"R",
"rt",
"s",
"sw",
"sg",
"e",
"f",
"fr",
"fa",
"fq",
"ft",
"fx",
"fv",
"fg",
"a",
"q",
"qt",
"t",
"T",
"d",
"w",
"c",
"z",
"x",
"v",
"g"
)
when (type) {
CodeType.chosung -> {
val index = init.indexOf(c)
if (index != -1) {
return index * 21 * 28
}
}
CodeType.jungsung -> {
var i = 0
while (i < mid.size) {
if (mid[i] == c) {
return i * 28
}
i++
}
}
CodeType.jongsung -> {
var i = 0
while (i < fin.size) {
if (fin[i] == c) {
return i + 1
}
i++
}
}
else -> println("잘못된 타입 입니다")
}
return -1
}
// 한 자로 된 중성값을 리턴한다
// 인덱스를 벗어낫다면 -1을 리턴
private fun getSingleMedial(i: Int, eng: String): Int {
return if ((i + 1) <= eng.length) {
getCode(CodeType.jungsung, eng.substring(i, i + 1))
} else {
-1
}
}
// 두 자로 된 중성을 체크하고, 있다면 값을 리턴한다.
// 없으면 리턴값은 -1
private fun getDoubleMedial(i: Int, eng: String): Int {
val result: Int
if ((i + 2) > eng.length) {
return -1
} else {
result = getCode(CodeType.jungsung, eng.substring(i, i + 2))
return if (result != -1) {
result
} else {
-1
}
}
}
// 한 자로된 종성값을 리턴한다
// 인덱스를 벗어낫다면 -1을 리턴
private fun getSingleFinal(i: Int, eng: String): Int {
return if ((i + 1) <= eng.length) {
getCode(CodeType.jongsung, eng.substring(i, i + 1))
} else {
-1
}
}
// 두 자로된 종성을 체크하고, 있다면 값을 리턴한다.
// 없으면 리턴값은 -1
private fun getDoubleFinal(i: Int, eng: String): Int {
return if ((i + 2) > eng.length) {
-1
} else {
getCode(CodeType.jongsung, eng.substring(i, i + 2))
}
}
// 코드타입 - 초성, 중성, 종성
internal enum class CodeType {
chosung, jungsung, jongsung
}
}

View File

@ -17,7 +17,8 @@ object JamoUtils {
"", "", "", "", "", "", "", "", "", "", "", "",
) )
fun split(target: String): List<String> { fun split(target: String?): List<String> {
if (target.isNullOrEmpty()) return arrayListOf()
return target.split("") return target.split("")
.filter(String::isNotEmpty) .filter(String::isNotEmpty)
.map(JamoUtils::splitOne) .map(JamoUtils::splitOne)

View File

@ -0,0 +1,63 @@
package rasel.lunar.launcher.workers
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
import android.os.Build
import androidx.work.WorkerParameters
import io.realm.kotlin.ext.query
import rasel.lunar.launcher.BuildConfig
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
import rasel.lunar.launcher.apps.AppDrawer.Companion.appName
import rasel.lunar.launcher.apps.AppDrawer.Companion.getCategory
import rasel.lunar.launcher.apps.normalize
import rasel.lunar.launcher.model.AppInfo
import rasel.lunar.launcher.utils.AlphabetToChosungMap
import rasel.lunar.launcher.utils.JamoUtils
class AppInfoGetter : BaseGetter {
companion object {
val TAG = "AppInfoGetter"
}
constructor(context: Context, workerParams: WorkerParameters) : super(context, workerParams) {
}
override fun realWork(): Result {
try {
var packageManager = lActivity?.packageManager
var packageInfoList: MutableList<ResolveInfo> = mutableListOf()
packageInfoList = (if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
packageManager?.queryIntentActivities(
Intent(Intent.ACTION_MAIN, null).addCategory(Intent.CATEGORY_LAUNCHER),
PackageManager.ResolveInfoFlags.of(0)
)
} else {
(packageManager?.queryIntentActivities(
Intent(Intent.ACTION_MAIN, null).addCategory(Intent.CATEGORY_LAUNCHER), 0
))
})?.apply {
removeIf { it.activityInfo.packageName.equals(BuildConfig.APPLICATION_ID) }
forEach {
val result = WorkersDb.getRealm().query<AppInfo>().query("pkgName == $0",it.activityInfo.packageName).find()
if (result.size < 1) {
val info = AppInfo()
info.appName = normalize(appName(it))
info.pkgName = it.activityInfo.packageName
info.category = getCategory(it.activityInfo.applicationInfo.category)
info.alphaCho = AlphabetToChosungMap.getCho(info.appName!!)
info.appNameChosung = JamoUtils.split(info.appName).joinToString("")
WorkersDb.update(info)
} else{
val info = WorkersDb.getRealm().copyFromRealm(result.first())
info.alphaCho = AlphabetToChosungMap.getCho(info.appName!!)
info.appNameChosung = JamoUtils.split(info.appName).joinToString("")
WorkersDb.update(info)
}
}
}!!
} catch (e : Exception) {e.printStackTrace()}
return Result.success()
}
}

View File

@ -19,12 +19,12 @@ class ClienGetter : BaseGetter {
} }
fun parseClien(div_clien : org.jsoup.nodes.Element) { fun parseClien(div_clien : org.jsoup.nodes.Element) {
BLog.LOGE("div_clien >>>> ${div_clien}") // BLog.LOGE("div_clien >>>> ${div_clien}")
//
BLog.LOGE("div_clien >>>> ${div_clien.getElementsByClass("subject_fixed").getT()}") // BLog.LOGE("div_clien >>>> ${div_clien.getElementsByClass("subject_fixed").getT()}")
BLog.LOGE("div_clien >>>> ${div_clien.getElementsByClass("shortname fixed").getT()}") // BLog.LOGE("div_clien >>>> ${div_clien.getElementsByClass("shortname fixed").getT()}")
BLog.LOGE("div_clien >>>> ${div_clien.getElementsByClass("list_subject").getHref()}") // BLog.LOGE("div_clien >>>> ${div_clien.getElementsByClass("list_subject").getHref()}")
BLog.LOGE("div_clien >>>> ${div_clien.getElementsByClass("timestamp").getT()}") // BLog.LOGE("div_clien >>>> ${div_clien.getElementsByClass("timestamp").getT()}")
val title = div_clien.getElementsByClass("subject_fixed").getT() val title = div_clien.getElementsByClass("subject_fixed").getT()
val desc = div_clien.getElementsByClass("shortname fixed").getT() val desc = div_clien.getElementsByClass("shortname fixed").getT()

View File

@ -0,0 +1,61 @@
package rasel.lunar.launcher.workers
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
import android.os.Build
import android.provider.ContactsContract
import android.util.Log
import androidx.work.WorkerParameters
import io.realm.kotlin.ext.query
import rasel.lunar.launcher.BuildConfig
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
import rasel.lunar.launcher.apps.AppDrawer.Companion.appName
import rasel.lunar.launcher.apps.AppDrawer.Companion.getCategory
import rasel.lunar.launcher.apps.SimpleContact
import rasel.lunar.launcher.apps.normalize
import rasel.lunar.launcher.model.AppInfo
import rasel.lunar.launcher.utils.AlphabetToChosungMap
class ContactInfoGetter : BaseGetter {
companion object {
val TAG = "ContactInfoGetter"
}
constructor(context: Context, workerParams: WorkerParameters) : super(context, workerParams) {
}
override fun realWork(): Result {
val phoneUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI
val projection = arrayOf(
ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER,
)
try {
val cursor = lActivity?.contentResolver?.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) {
if (WorkersDb.getRealm().query<SimpleContact>("id == $0", contactId).find().size == 0) {
WorkersDb.update(SimpleContact(contactId,name,number))
}
}
}
}
// 데이터 계열은 반드시 닫아줘야 한다.
cursor?.close()
} catch ( e : Exception) {
e.printStackTrace()
}
return Result.success()
}
}

View File

@ -5,30 +5,44 @@ import android.content.Context
import android.provider.CallLog import android.provider.CallLog
import androidx.work.WorkerParameters import androidx.work.WorkerParameters
import com.google.gson.Gson import com.google.gson.Gson
import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.ext.query
import io.realm.kotlin.types.RealmObject
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
import rasel.lunar.launcher.home.LauncherHome.Companion.recentCalls import rasel.lunar.launcher.apps.SimpleContact
import rasel.lunar.launcher.utils.BLog
import rasel.lunar.launcher.utils.beforeDay import rasel.lunar.launcher.utils.beforeDay
import rasel.lunar.launcher.utils.getContactId
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
class RecentCall { class RecentCall : RealmObject {
constructor(count: Int, name: String?, number: String, type: Int, typeString: String, date : String) {
constructor(count: Int, name: String?, number: String, type: Int, typeString: String, date : String, callDayTime : Long, duration : Long) {
this.count = count this.count = count
this.name = name ?: "unknown" this.name = name ?: "unknown"
this.number = number this.number = number
this.type = type this.type = type
this.typeString = typeString this.typeString = typeString
this.date = date this.date = date
this.uniqK = number.plus("_").plus(callDayTime)
this.callDayTime = callDayTime
this.duration = duration
} }
constructor()
var callDayTime = 0L
var uniqK : String? = ""
var count : Int = 1 var count : Int = 1
var name : String = "how" var name : String = "how"
var number : String = "" var number : String = ""
var type : Int = 0 var type : Int = 0
var typeString : String = "" var typeString : String = ""
var date : String = "" var date : String = ""
var duration = 0L
fun toJson() : String { fun toJson() : String {
return Gson().toJson(this) return Gson().toJson(this)
@ -37,14 +51,17 @@ class RecentCall {
} }
class RecentCallGetter : BaseGetter { class RecentCallGetter : BaseGetter {
companion object{
val TAG = "RecentCallGetter"
val dateFormat = SimpleDateFormat("yyy/MM/dd-HH:mm:ss")
}
constructor(context: Context, workerParams: WorkerParameters) : super(context, workerParams) { constructor(context: Context, workerParams: WorkerParameters) : super(context, workerParams) {
} }
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")
override fun realWork(): Result { override fun realWork(): Result {
var dateParam = beforeDay(Date(),7).toString() var dateParam = beforeDay(Date(),30).toString()
var managedCursor = lActivity?.contentResolver?.query( var managedCursor = lActivity?.contentResolver?.query(
CallLog.Calls.CONTENT_URI, arrayOf( CallLog.Calls.CONTENT_URI, arrayOf(
CallLog.Calls.NUMBER, CallLog.Calls.NUMBER,
@ -62,12 +79,11 @@ class RecentCallGetter : BaseGetter {
val date = managedCursor.getColumnIndex(CallLog.Calls.DATE) val date = managedCursor.getColumnIndex(CallLog.Calls.DATE)
val duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION) val duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION)
val name = managedCursor.getColumnIndex(CallLog.Calls.CACHED_NAME) val name = managedCursor.getColumnIndex(CallLog.Calls.CACHED_NAME)
recentCalls.clear()
while (managedCursor.moveToNext()) { while (managedCursor.moveToNext()) {
val phNumber = managedCursor.getString(number) // mobile number val phNumber = managedCursor.getString(number) // mobile number
val callType = managedCursor.getString(type) // call type val callType = managedCursor.getString(type) // call type
val callDate = managedCursor.getString(date) // call date val callDate = managedCursor.getString(date) // call date
val callDayTime: Date = Date(callDate.toLong()) val callDayTime = callDate.toLong()
val callDuration = managedCursor.getString(duration) val callDuration = managedCursor.getString(duration)
val callerName = managedCursor.getString(name) val callerName = managedCursor.getString(name)
@ -82,21 +98,40 @@ class RecentCallGetter : BaseGetter {
CallLog.Calls.BLOCKED_TYPE -> { dir = "BLOCKED_TYPE" } CallLog.Calls.BLOCKED_TYPE -> { dir = "BLOCKED_TYPE" }
CallLog.Calls.ANSWERED_EXTERNALLY_TYPE -> { dir = "ANSWERED_EXTERNALLY_TYPE" } CallLog.Calls.ANSWERED_EXTERNALLY_TYPE -> { dir = "ANSWERED_EXTERNALLY_TYPE" }
} }
recentCalls.add(RecentCall(
val call = RecentCall(
1, 1,
callerName, callerName,
phNumber, phNumber,
dircode, dircode,
dir, dir,
SimpleDateFormat("yyy/MM/dd-HH:mm:ss").format(callDayTime) dateFormat.format(Date(callDayTime)),
)) callDayTime,
callDuration.toLong()
)
call.uniqK?.let {
BLog.LOGE("${TAG} call.uniqK? >>> ${call.uniqK}")
WorkersDb.getRealm().writeBlocking {
if(query<RecentCall>().query("uniqK == $0", it).find().count() < 1) {
this.copyToRealm(call, UpdatePolicy.ALL)
var cId = getContactId(lActivity!!.contentResolver, call.number)
if (cId!=null && cId.length > 0) {
val result = query<SimpleContact>().query("id == $0", cId).find()
if(result.size > 0){
var contact = result.first()
contact.touchCount = contact.touchCount + 1
contact.lastedTouchDateTime = Math.max(contact.lastedTouchDateTime, callDayTime)
BLog.LOGE("${TAG} updatetouch info >>>> ${contact.touchCount}")
}
}
}
BLog.LOGE("${TAG} updatetouch info >>>> BE ")
}
BLog.LOGE("${TAG} updatetouch info >>>> E")
}
} }
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace()
} finally { } finally {
managedCursor.close() managedCursor.close()
} }

View File

@ -1,19 +1,23 @@
package rasel.lunar.launcher.workers package rasel.lunar.launcher.workers
import com.google.gson.Gson
import io.realm.kotlin.Realm import io.realm.kotlin.Realm
import io.realm.kotlin.RealmConfiguration import io.realm.kotlin.RealmConfiguration
import io.realm.kotlin.UpdatePolicy import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.types.BaseRealmObject import io.realm.kotlin.types.BaseRealmObject
import io.realm.kotlin.types.TypedRealmObject import io.realm.kotlin.types.TypedRealmObject
import rasel.lunar.launcher.apps.SimpleContact
import rasel.lunar.launcher.model.AppInfo
import rasel.lunar.launcher.model.NotificationItem import rasel.lunar.launcher.model.NotificationItem
import rasel.lunar.launcher.model.RssData import rasel.lunar.launcher.model.RssData
import rasel.lunar.launcher.model.RssDataInterface import rasel.lunar.launcher.model.RssDataInterface
import rasel.lunar.launcher.model.getRssData import rasel.lunar.launcher.model.getRssData
import rasel.lunar.launcher.utils.BLog
import kotlin.reflect.KClass import kotlin.reflect.KClass
object WorkersDb { object WorkersDb {
val clazz : Set<KClass<out BaseRealmObject>> = setOf(RssData::class, NotificationItem::class) val clazz : Set<KClass<out BaseRealmObject>> = setOf(RssData::class, NotificationItem::class, AppInfo::class,SimpleContact::class, RecentCall::class)
val schemaVersion : Long = 0L val schemaVersion : Long = 0L
private var pRealm : Realm? = null private var pRealm : Realm? = null
@ -76,7 +80,7 @@ object WorkersDb {
getRealm().apply { getRealm().apply {
this.writeBlocking { this.writeBlocking {
try { try {
this.copyToRealm(data, UpdatePolicy.ERROR) this.copyToRealm(data, UpdatePolicy.ALL)
} catch (e : Exception) { } catch (e : Exception) {
} }
@ -84,5 +88,38 @@ object WorkersDb {
} }
} }
fun update(info: AppInfo) {
getRealm().apply {
this.writeBlocking {
try {
this.copyToRealm(info, UpdatePolicy.ALL)
} catch (e : Exception) {
}
}
}
}
fun update(contact: SimpleContact) {
getRealm().apply {
this.writeBlocking {
try {
this.copyToRealm(contact, UpdatePolicy.ALL)
} catch (e : Exception) {
}
}
}
}
fun insertCall(contact: RecentCall) {
getRealm().apply {
this.writeBlocking {
try {
this.copyToRealm(contact, UpdatePolicy.ALL)
} catch (e : Exception) {
}
}
}
}
} }