Compare commits

...

3 Commits

Author SHA1 Message Date
lunaticbum
ddc1755c6f ... 2024-09-12 17:27:34 +09:00
lunaticbum
470e304918 Merge branch 'main' of https://dev.lunaticbum.kr/lun_admin/lun_launcher
# Conflicts:
#	app/src/main/kotlin/rasel/lunar/launcher/LauncherActivity.kt
2024-09-12 17:27:25 +09:00
lunaticbum
f014521597 ...현 재생 중인 음악 표시 기능 추가 중. 2024-09-12 17:26:13 +09:00
8 changed files with 236 additions and 115 deletions

View File

@ -154,6 +154,7 @@ internal class LauncherActivity : AppCompatActivity() {
val longTimePeriod = 600L
val midTimePeriod = 300L
var isOpendFold = false
val qDayPeriod = 60L * 8L
@JvmStatic var lActivity: LauncherActivity? = null
@JvmStatic var appWidgetManager: AppWidgetManager? = null

View File

@ -206,6 +206,7 @@ internal class AppDrawer : Fragment() {
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
pakage?.let {
mapIntent.setPackage(pakage)
WorkersDb.updateAppUse(pakage)
}
startActivity(mapIntent)
}
@ -214,7 +215,8 @@ internal class AppDrawer : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.searchInput.setOnKeyListener { v, keyCode, event ->
if (keyCode == 66 && contactList.size < 1 && packageList.size < 1 && event.action == KeyEvent.ACTION_UP) {
//contactList.size < 1 && packageList.size < 1 &&
if (keyCode == 66 && event.action == KeyEvent.ACTION_UP) {
checkResult(binding.searchInput.text.toString())
true
}else {
@ -229,85 +231,85 @@ internal class AppDrawer : Fragment() {
fun checkResult(keyword: String) {
if(!isAdded || !isResumed || keyword.length < 1) return
var dialog : AlertDialog.Builder? = null
var filted = packageList.filter { it.appName.equals(keyword) }
BLog.LOGE("filted >> ${filted.size}")
var filtedContact = contactList.filter { it.name.equals(keyword) }
BLog.LOGE("filtedContact >> ${filtedContact.size}")
if (keyword.length > 0 && (packageList.size == 1 || filted.size > 0)) {
dialog = AlertDialog.Builder(requireContext())
dialog?.setTitle("앱 실행 확인")
if (packageList.size == 1) {
dialog?.setMessage("${keyword} 검색 결과 '${packageList[0].appName}' 준비됨")
dialog?.setPositiveButton("실행") { s, d ->
runonUi {
startActivity(packageManager?.getLaunchIntentForPackage(packageList[0].pkgName!!))
s.dismiss()
}
}
} else if (filted.size > 0) {
dialog?.setMessage("${keyword} 검색 결과 '${filted[0].appName}' 준비됨")
dialog?.setPositiveButton("${filted[0].appName} 실행") { s, d ->
runonUi {
startActivity(packageManager?.getLaunchIntentForPackage(filted[0].pkgName!!))
s.dismiss()
}
}
if(filted.size > 1) {
dialog?.setNeutralButton("${filted[1].appName} 실행") { s, d ->
runonUi {
startActivity(packageManager?.getLaunchIntentForPackage(filted[1].pkgName!!))
s.dismiss()
}
}
}
}
dialog?.setCancelable(false)
dialog?.setNegativeButton("취소") { s, d ->
runonUi { s.dismiss() }
}
dialog?.setOnDismissListener { registCancelSearch() }
dialog?.show()
} else if (contactList.size == 1 || filtedContact.size > 0) {
dialog = AlertDialog.Builder(requireContext())
dialog?.setTitle("연락처 실행 확인")
dialog?.setCancelable(false)
dialog?.setNegativeButton("취소") { s, d ->
runonUi { s.dismiss() }
}
if (contactList.size == 1) {
dialog?.setMessage("${keyword} 검색 결과 '${contactList[0].name}' 준비됨")
dialog?.setPositiveButton("자세히 보기") { s, d ->
runonUi {
ContactMenu().show(childFragmentManager, contactList[0].id.toString())
s.dismiss()
}
}
} else if(filtedContact.size > 0) {
dialog?.setMessage("${keyword} 검색 결과 '${filtedContact[0].name}' 준비됨")
dialog?.setPositiveButton("'${filtedContact[0].name},\n${filtedContact[0].phoneNumber}'\n자세히 보기") { s, d ->
runonUi {
ContactMenu().show(childFragmentManager, filtedContact[0].id.toString())
s.dismiss()
}
}
if (filtedContact.size > 1) {
dialog?.setNeutralButton("'${filtedContact[1].name},\n${filtedContact[1].phoneNumber}'\n자세히 보기") { s, d ->
runonUi {
ContactMenu().show(childFragmentManager, filtedContact[1].id.toString())
s.dismiss()
}
}
}
}
dialog?.setOnDismissListener { registCancelSearch() }
dialog?.show()
} else {
// if(!isAdded || !isResumed || keyword.length < 1) return
// var dialog : AlertDialog.Builder? = null
// var filted = packageList.filter { it.appName.equals(keyword) }
// BLog.LOGE("filted >> ${filted.size}")
// var filtedContact = contactList.filter { it.name.equals(keyword) }
// BLog.LOGE("filtedContact >> ${filtedContact.size}")
// if (keyword.length > 0 && (packageList.size == 1 || filted.size > 0)) {
// dialog = AlertDialog.Builder(requireContext())
// dialog?.setTitle("앱 실행 확인")
// if (packageList.size == 1) {
// dialog?.setMessage("${keyword} 검색 결과 '${packageList[0].appName}' 준비됨")
// dialog?.setPositiveButton("실행") { s, d ->
// runonUi {
// startActivity(packageManager?.getLaunchIntentForPackage(packageList[0].pkgName!!))
// s.dismiss()
// }
// }
// } else if (filted.size > 0) {
// dialog?.setMessage("${keyword} 검색 결과 '${filted[0].appName}' 준비됨")
// dialog?.setPositiveButton("${filted[0].appName} 실행") { s, d ->
// runonUi {
// startActivity(packageManager?.getLaunchIntentForPackage(filted[0].pkgName!!))
// s.dismiss()
// }
// }
// if(filted.size > 1) {
// dialog?.setNeutralButton("${filted[1].appName} 실행") { s, d ->
// runonUi {
// startActivity(packageManager?.getLaunchIntentForPackage(filted[1].pkgName!!))
// s.dismiss()
// }
// }
// }
// }
// dialog?.setCancelable(false)
// dialog?.setNegativeButton("취소") { s, d ->
// runonUi { s.dismiss() }
// }
// dialog?.setOnDismissListener { registCancelSearch() }
// dialog?.show()
// } else if (contactList.size == 1 || filtedContact.size > 0) {
// dialog = AlertDialog.Builder(requireContext())
// dialog?.setTitle("연락처 실행 확인")
// dialog?.setCancelable(false)
// dialog?.setNegativeButton("취소") { s, d ->
// runonUi { s.dismiss() }
// }
// if (contactList.size == 1) {
// dialog?.setMessage("${keyword} 검색 결과 '${contactList[0].name}' 준비됨")
// dialog?.setPositiveButton("자세히 보기") { s, d ->
// runonUi {
// ContactMenu().show(childFragmentManager, contactList[0].id.toString())
// s.dismiss()
// }
// }
// } else if(filtedContact.size > 0) {
// dialog?.setMessage("${keyword} 검색 결과 '${filtedContact[0].name}' 준비됨")
// dialog?.setPositiveButton("'${filtedContact[0].name},\n${filtedContact[0].phoneNumber}'\n자세히 보기") { s, d ->
// runonUi {
// ContactMenu().show(childFragmentManager, filtedContact[0].id.toString())
// s.dismiss()
// }
// }
// if (filtedContact.size > 1) {
// dialog?.setNeutralButton("'${filtedContact[1].name},\n${filtedContact[1].phoneNumber}'\n자세히 보기") { s, d ->
// runonUi {
// ContactMenu().show(childFragmentManager, filtedContact[1].id.toString())
// s.dismiss()
// }
// }
// }
// }
// dialog?.setOnDismissListener { registCancelSearch() }
// dialog?.show()
// } else {
lActivity?.openSearchMenus(keyword) {
registCancelSearch()
}
}
// }
}

View File

@ -39,16 +39,12 @@ import android.view.ViewGroup
import android.widget.EditText
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.LinearLayoutCompat.LayoutParams
import androidx.appcompat.widget.PopupMenu
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.PeriodicWorkRequestBuilder
import com.google.android.material.button.MaterialButtonToggleGroup
import com.google.gson.Gson
import io.realm.kotlin.ext.query
@ -62,9 +58,8 @@ import rasel.lunar.launcher.CommadCallabck
import rasel.lunar.launcher.LauncherActivity.Companion.appWidgetHost
import rasel.lunar.launcher.LauncherActivity.Companion.appWidgetManager
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.refreshSms
import rasel.lunar.launcher.LauncherActivity.Companion.refreshDeviceData
import rasel.lunar.launcher.R
import rasel.lunar.launcher.databinding.FeedsBinding
import rasel.lunar.launcher.feeds.rss.RssAdapter
@ -82,13 +77,11 @@ import rasel.lunar.launcher.model.MostItem
import rasel.lunar.launcher.model.RssData
import rasel.lunar.launcher.model.RssDataInterface
import rasel.lunar.launcher.model.RssDataType
import rasel.lunar.launcher.model.RssItem
import rasel.lunar.launcher.model.RssTagItem
import rasel.lunar.launcher.model.dateFormat
import rasel.lunar.launcher.model.getRssData
import rasel.lunar.launcher.utils.BLog
import rasel.lunar.launcher.utils.RssList.jGuruMain
import rasel.lunar.launcher.workers.RecentCallGetter
import rasel.lunar.launcher.workers.WorkersDb
import java.net.URLEncoder
import java.nio.charset.Charset
@ -315,8 +308,7 @@ internal class Feeds : Fragment() , CommadCallabck {
"req" -> {
refreshFeeds()
refreshCalls()
refreshSms()
refreshDeviceData()
consoleLog("excute refreshFeeds()")
}

View File

@ -19,42 +19,36 @@
package rasel.lunar.launcher.home
import android.annotation.SuppressLint
import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.ContentUris
import android.content.DialogInterface
import android.content.Intent
import android.content.IntentFilter
import android.content.SharedPreferences
import android.graphics.Bitmap
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.PatternMatcher
import android.provider.AlarmClock
import android.provider.MediaStore
import android.view.LayoutInflater
import android.view.View
import android.view.View.OnScrollChangeListener
import android.view.ViewGroup
import android.widget.EditText
import android.widget.RadioButton
import android.widget.RadioGroup
import android.widget.TableRow
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.biometric.BiometricPrompt
import androidx.core.content.ContextCompat.RECEIVER_EXPORTED
import androidx.core.content.ContextCompat.registerReceiver
import androidx.core.net.toUri
import androidx.core.view.children
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.OnScrollListener
import com.google.gson.Gson
import io.realm.kotlin.ext.query
import io.realm.kotlin.notifications.InitialResults
import io.realm.kotlin.notifications.ResultsChange
@ -65,16 +59,12 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import org.json.JSONArray
import org.json.JSONObject
import org.jsoup.Jsoup
import rasel.lunar.launcher.CommadCallabck
import rasel.lunar.launcher.LauncherActivity.Companion.CALL_WORK_TAG
import rasel.lunar.launcher.LauncherActivity.Companion.SMS_WORK_TAG
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
import rasel.lunar.launcher.LauncherActivity.Companion.refreshFeeds
import rasel.lunar.launcher.LauncherActivity.Companion.workmanager
import rasel.lunar.launcher.R
import rasel.lunar.launcher.databinding.LauncherHomeBinding
@ -86,21 +76,19 @@ import rasel.lunar.launcher.helpers.UniUtils.Companion.biometricPromptInfo
import rasel.lunar.launcher.helpers.UniUtils.Companion.canAuthenticate
import rasel.lunar.launcher.helpers.UniUtils.Companion.expandNotificationPanel
import rasel.lunar.launcher.helpers.UniUtils.Companion.lockMethod
import rasel.lunar.launcher.home.weather.WeatherExecutor
import rasel.lunar.launcher.model.CiliMagnet
import rasel.lunar.launcher.model.CurrentPlayItem
import rasel.lunar.launcher.model.NotificationItem
import rasel.lunar.launcher.model.RssData
import rasel.lunar.launcher.model.RssDataInterface
import rasel.lunar.launcher.model.RssDataType
import rasel.lunar.launcher.qaccess.QuickAccess
import rasel.lunar.launcher.settings.SettingsActivity
import rasel.lunar.launcher.todos.MissedCallsAdapter
import rasel.lunar.launcher.model.RssDataInterface
import rasel.lunar.launcher.model.RssDataType
import rasel.lunar.launcher.todos.NotificationItemAdapter
import rasel.lunar.launcher.todos.RssItemAdapter
import rasel.lunar.launcher.todos.SmsLogsAdapter
import rasel.lunar.launcher.utils.BLog
import rasel.lunar.launcher.utils.JamoUtils
import rasel.lunar.launcher.utils.RssList.jGuruMain
import rasel.lunar.launcher.utils.SimpleFingerGestures
import rasel.lunar.launcher.utils.beforeDay
import rasel.lunar.launcher.view.TableRadioGroup
@ -108,8 +96,6 @@ import rasel.lunar.launcher.workers.RecentCall
import rasel.lunar.launcher.workers.RecentSms
import rasel.lunar.launcher.workers.WorkersDb
import java.net.URLEncoder
import java.nio.charset.Charset
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.regex.Pattern
@ -222,9 +208,34 @@ internal class LauncherHome : Fragment() {
it.clear()
}
// nReceiver = NotificationReceiver()
// val filter = IntentFilter()
// registerReceiver(requireContext(),nReceiver, filter,RECEIVER_EXPORTED)
GlobalScope.launch {
WorkersDb.getRealm().apply {
query<CurrentPlayItem>().find().asFlow().collect { changes: ResultsChange<CurrentPlayItem> ->
binding.currentMusic?.postDelayed({
if (changes.list.size > 0) {
changes.list?.first()?.let {
binding.currentMusic.visibility = View.VISIBLE
binding.artist.text = it.artists
binding.title.text = it.title
val albumArtUri = it.albumArt?.toUri()
var bitmap: Bitmap? = null
try {
bitmap = MediaStore.Images.Media.getBitmap(
requireContext().contentResolver,
albumArtUri
)
binding.albumArt.setImageBitmap(bitmap)
} catch (exception: java.lang.Exception) {
// log error
}
}
} else {
binding.currentMusic.visibility = View.GONE
}}, 150L)
}
}
}
BLog.LOGE("onCreateView()")
@ -605,7 +616,7 @@ internal class LauncherHome : Fragment() {
} else if(binding.recentSms.isSelected){
WorkersDb.getRealm().apply {
val result = query<RecentSms>().query("rcvDate >= $0 OR pstDate >= $0 ", dateParam)
.sort(Pair("pstDate",Sort.DESCENDING),Pair("rcvDate", Sort.DESCENDING)).find()
.sort("rcvDate",Sort.DESCENDING).find()
if (result.size > 0) {
try {
BLog.LOGE("observeForever smsList.size >>> ${result.size}")
@ -613,7 +624,8 @@ internal class LauncherHome : Fragment() {
binding.smsList.visibility = View.VISIBLE
smsList.clear()
smsList.addAll(copyFromRealm(result))
mSmsLogsAdapter.updateData(smsList)
mSmsLogsAdapter.
updateData(smsList)
binding.missedCalls.isSelected = false
binding.otherCheck.isSelected = false
binding.notice.isSelected = false

View File

@ -0,0 +1,13 @@
package rasel.lunar.launcher.model
import io.realm.kotlin.types.RealmObject
import io.realm.kotlin.types.annotations.PrimaryKey
class CurrentPlayItem : RealmObject {
@PrimaryKey
var uniqId = "RPrimaryKey"
var title : String? = ""
var artists : String? = ""
var albumArt : String? = ""
var state : Int = 0
}

View File

@ -1,17 +1,22 @@
package rasel.lunar.launcher.utils
import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
import android.media.MediaMetadata
import android.media.session.MediaSessionManager
import android.os.Build
import android.service.notification.NotificationListenerService
import android.service.notification.StatusBarNotification
import androidx.annotation.RequiresApi
import androidx.core.content.getSystemService
import com.google.gson.Gson
import io.realm.kotlin.ext.query
import rasel.lunar.launcher.model.CurrentPlayItem
import rasel.lunar.launcher.model.NotificationItem
import rasel.lunar.launcher.workers.WorkersDb
import java.security.AccessController.getContext
@ -56,6 +61,56 @@ class NLService : NotificationListenerService() {
}
}
}
val m = getSystemService<MediaSessionManager>()!!
val component = ComponentName(this, NLService::class.java)
val sessions = m.getActiveSessions(component)
BLog.LOGE("Sessions", "count: ${sessions.size}")
if (sbn.packageName.contains("youtube")) {
sessions.forEach { session ->
WorkersDb.getRealm().writeBlocking {
if (session.playbackState?.isActive == true) {
val result = query<CurrentPlayItem>().find()
var current : CurrentPlayItem? = null
if (result.size > 0) {
current = result.first()
} else {
current = CurrentPlayItem()
copyToRealm(current)
}
BLog.LOGE(
"Sessions",
"$session -- " + (session.playbackState?.state)
)
BLog.LOGE(
"Sessions",
"$session -- " + (session?.metadata?.keySet()?.joinToString())
)
BLog.LOGE(
"Sessions",
"$session -- " + (session?.metadata?.getString(MediaMetadata.METADATA_KEY_ARTIST))
)
if (session?.metadata?.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ART) == true) {
BLog.LOGE(
"Sessions",
"$session -- " + (session?.metadata?.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART))
)
}
BLog.LOGE(
"Sessions",
"$session -- " + (session?.metadata?.getString(MediaMetadata.METADATA_KEY_TITLE))
)
current.title = session?.metadata?.getString(MediaMetadata.METADATA_KEY_TITLE)
current.artists = session?.metadata?.getString(MediaMetadata.METADATA_KEY_ARTIST)
// current.albumArt = session?.metadata?.getBitmap(MediaMetadata.METADATA_KEY_ALBUM)
} else {
delete(query<CurrentPlayItem>().find())
}
}
}
}
// val i = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
// i.putExtra("notification_event", "onNotificationPosted :" + sbn.packageName + "\n")
// sendBroadcast(i)

View File

@ -4,10 +4,12 @@ import com.google.gson.Gson
import io.realm.kotlin.Realm
import io.realm.kotlin.RealmConfiguration
import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.ext.query
import io.realm.kotlin.types.BaseRealmObject
import io.realm.kotlin.types.TypedRealmObject
import rasel.lunar.launcher.apps.SimpleContact
import rasel.lunar.launcher.model.AppInfo
import rasel.lunar.launcher.model.CurrentPlayItem
import rasel.lunar.launcher.model.NotificationItem
import rasel.lunar.launcher.model.RssData
import rasel.lunar.launcher.model.RssDataInterface
@ -17,7 +19,8 @@ import kotlin.reflect.KClass
object WorkersDb {
val clazz : Set<KClass<out BaseRealmObject>> = setOf(RssData::class, NotificationItem::class, AppInfo::class,SimpleContact::class, RecentCall::class, RecentSms::class)
val clazz : Set<KClass<out BaseRealmObject>> = setOf(RssData::class, NotificationItem::class, AppInfo::class,SimpleContact::class, RecentCall::class, RecentSms::class, CurrentPlayItem::class)
val schemaVersion : Long = 0L
private var pRealm : Realm? = null
@ -122,4 +125,16 @@ object WorkersDb {
}
}
}
fun updateAppUse(pkg : String) {
getRealm().writeBlocking {
val result = query<AppInfo>().query("pkgName == $0",pkg).find()
if(result.size > 0) {
val appInfo = result.first()
appInfo.clickCount = appInfo.clickCount + 1
appInfo.lastUseDate = System.currentTimeMillis()
}
}
}
}

View File

@ -96,6 +96,37 @@
app:layout_constraintTop_toBottomOf="@+id/time"
app:layout_constraintVertical_bias="0.100" />
<RelativeLayout
android:id="@+id/current_music"
app:layout_constraintTop_toBottomOf="@id/weather"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_alignParentLeft="true"
android:id="@+id/album_art"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:layout_width="40dp"
android:layout_height="40dp"/>
<TextView
android:layout_alignLeft="@id/album_art"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:id="@+id/artist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:layout_alignLeft="@id/album_art"
android:layout_alignParentRight="true"
android:layout_below="@id/artist"
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
<LinearLayout
android:layout_margin="10dp"
android:layout_marginTop="20dp"
@ -107,7 +138,7 @@
android:orientation="horizontal"
app:layout_constraintRight_toRightOf="parent"
android:layout_height="40dp"
app:layout_constraintTop_toBottomOf="@+id/weather"
app:layout_constraintTop_toBottomOf="@+id/current_music"
>
<TextView