...현 재생 중인 음악 표시 기능 추가 중.
This commit is contained in:
parent
4eaf93bca8
commit
f014521597
@ -32,6 +32,10 @@ import android.content.pm.PackageManager
|
|||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
|
import android.media.MediaMetadata
|
||||||
|
import android.media.session.MediaController
|
||||||
|
import android.media.session.MediaSessionManager
|
||||||
|
import android.media.session.PlaybackState
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.net.http.SslError
|
import android.net.http.SslError
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
@ -61,14 +65,13 @@ import androidx.appcompat.app.AppCompatActivity
|
|||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
|
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
|
||||||
import androidx.core.content.FileProvider
|
import androidx.core.content.FileProvider
|
||||||
|
import androidx.core.content.getSystemService
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||||
import androidx.core.view.ViewCompat
|
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.work.ExistingPeriodicWorkPolicy
|
import androidx.work.ExistingPeriodicWorkPolicy
|
||||||
@ -152,30 +155,29 @@ internal class LauncherActivity : AppCompatActivity() {
|
|||||||
val REDDIT_WORK_TAG = "RedditGetter"
|
val REDDIT_WORK_TAG = "RedditGetter"
|
||||||
val shortTimePeriod = 20L
|
val shortTimePeriod = 20L
|
||||||
val longTimePeriod = 60L
|
val longTimePeriod = 60L
|
||||||
|
val qDayPeriod = 60L * 8L
|
||||||
val midTimePeriod = 30L
|
val midTimePeriod = 30L
|
||||||
var isOpendFold = false
|
var isOpendFold = false
|
||||||
|
|
||||||
@JvmStatic var lActivity: LauncherActivity? = null
|
@JvmStatic var lActivity: LauncherActivity? = null
|
||||||
@JvmStatic var appWidgetManager: AppWidgetManager? = null
|
@JvmStatic var appWidgetManager: AppWidgetManager? = null
|
||||||
@JvmStatic var appWidgetHost: WidgetHost? = null
|
@JvmStatic var appWidgetHost: WidgetHost? = null
|
||||||
fun refreshSms() {
|
fun refreshDeviceData() {
|
||||||
Executors.newSingleThreadScheduledExecutor().schedule({
|
Executors.newSingleThreadScheduledExecutor().schedule({
|
||||||
mWorkManager?.cancelAllWorkByTag(SMS_WORK_TAG)
|
mWorkManager?.cancelAllWorkByTag(SMS_WORK_TAG)
|
||||||
mWorkManager?.enqueueUniquePeriodicWork(
|
mWorkManager?.enqueueUniquePeriodicWork(
|
||||||
SMS_WORK_TAG,
|
SMS_WORK_TAG,
|
||||||
ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
|
ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
|
||||||
PeriodicWorkRequestBuilder<RecentSmsGetter>(longTimePeriod, TimeUnit.MINUTES)
|
PeriodicWorkRequestBuilder<RecentSmsGetter>(qDayPeriod, TimeUnit.MINUTES)
|
||||||
.addTag(SMS_WORK_TAG)
|
.addTag(SMS_WORK_TAG)
|
||||||
.build())
|
.build())
|
||||||
}, 1, TimeUnit.SECONDS)
|
}, 1, TimeUnit.SECONDS)
|
||||||
}
|
|
||||||
fun refreshCalls() {
|
|
||||||
var delay = 1L
|
var delay = 1L
|
||||||
Executors.newSingleThreadScheduledExecutor().schedule({
|
Executors.newSingleThreadScheduledExecutor().schedule({
|
||||||
mWorkManager?.cancelAllWorkByTag(ContactInfoGetter.TAG)
|
mWorkManager?.cancelAllWorkByTag(ContactInfoGetter.TAG)
|
||||||
mWorkManager?.enqueueUniquePeriodicWork(
|
mWorkManager?.enqueueUniquePeriodicWork(
|
||||||
ContactInfoGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
|
ContactInfoGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
|
||||||
PeriodicWorkRequestBuilder<ContactInfoGetter>(12, TimeUnit.HOURS)
|
PeriodicWorkRequestBuilder<ContactInfoGetter>(qDayPeriod, TimeUnit.MINUTES)
|
||||||
.addTag(ContactInfoGetter.TAG)
|
.addTag(ContactInfoGetter.TAG)
|
||||||
.build())
|
.build())
|
||||||
}, delay, TimeUnit.SECONDS)
|
}, delay, TimeUnit.SECONDS)
|
||||||
@ -184,7 +186,7 @@ internal class LauncherActivity : AppCompatActivity() {
|
|||||||
mWorkManager?.cancelAllWorkByTag(AppInfoGetter.TAG)
|
mWorkManager?.cancelAllWorkByTag(AppInfoGetter.TAG)
|
||||||
mWorkManager?.enqueueUniquePeriodicWork(
|
mWorkManager?.enqueueUniquePeriodicWork(
|
||||||
AppInfoGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
|
AppInfoGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
|
||||||
PeriodicWorkRequestBuilder<AppInfoGetter>(12, TimeUnit.HOURS)
|
PeriodicWorkRequestBuilder<AppInfoGetter>(qDayPeriod, TimeUnit.MINUTES)
|
||||||
.addTag(AppInfoGetter.TAG)
|
.addTag(AppInfoGetter.TAG)
|
||||||
.build())
|
.build())
|
||||||
}, delay, TimeUnit.SECONDS)
|
}, delay, TimeUnit.SECONDS)
|
||||||
@ -332,12 +334,6 @@ internal class LauncherActivity : AppCompatActivity() {
|
|||||||
intent?.extras?.keySet()?.forEach {
|
intent?.extras?.keySet()?.forEach {
|
||||||
BLog.LOGE("onNewIntent intent >> ${it}")
|
BLog.LOGE("onNewIntent intent >> ${it}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// binding.viewPager.invalidate()
|
|
||||||
// binding.viewPager.post {
|
|
||||||
// binding.viewPager?.adapter?.notifyDataSetChanged()
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@ -441,8 +437,7 @@ internal class LauncherActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!needAsk) {
|
if (!needAsk) {
|
||||||
refreshSms()
|
refreshDeviceData()
|
||||||
refreshCalls()
|
|
||||||
refreshFeeds()
|
refreshFeeds()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -485,6 +480,33 @@ internal class LauncherActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var currentMediaController: MediaController? = null
|
||||||
|
|
||||||
|
private val mSessionsChangedListener = MediaSessionManager.OnActiveSessionsChangedListener { list: List<MediaController>? ->
|
||||||
|
var latestPlaybackState: PlaybackState? = null
|
||||||
|
var latestMediaController: MediaController? = null
|
||||||
|
|
||||||
|
list?.forEach { mediaController ->
|
||||||
|
val playbackState = mediaController.playbackState
|
||||||
|
if (playbackState != null) {
|
||||||
|
if (latestPlaybackState == null || playbackState.lastPositionUpdateTime > latestPlaybackState!!.lastPositionUpdateTime) {
|
||||||
|
if (playbackState.state == PlaybackState.STATE_PLAYING) {
|
||||||
|
BLog.LOGE("mSessionsChangedListener playbackState.state >>> ${playbackState.state}")
|
||||||
|
latestPlaybackState = playbackState
|
||||||
|
latestMediaController = mediaController
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currentMediaController = latestMediaController
|
||||||
|
BLog.LOGE("mSessionsChangedListener mediaController.metadata >>> ${mediaController.metadata?.describeContents()}")
|
||||||
|
BLog.LOGE("mSessionsChangedListener currentMediaController >>> ${currentMediaController?.packageName}")
|
||||||
|
// Now you have the MediaController that is currently playing.
|
||||||
|
// You can get the playback state using currentMediaController?.playbackState.
|
||||||
|
}
|
||||||
|
|
||||||
/* set up viewpager2 */
|
/* set up viewpager2 */
|
||||||
private fun setupView() {
|
private fun setupView() {
|
||||||
viewPager = binding.viewPager.apply {
|
viewPager = binding.viewPager.apply {
|
||||||
@ -574,14 +596,14 @@ internal class LauncherActivity : AppCompatActivity() {
|
|||||||
BLog.LOGE("EndCallReceiver >>> ${intent}")
|
BLog.LOGE("EndCallReceiver >>> ${intent}")
|
||||||
val phoneState = intent.getStringExtra(TelephonyManager.EXTRA_STATE) ?: return
|
val phoneState = intent.getStringExtra(TelephonyManager.EXTRA_STATE) ?: return
|
||||||
if (phoneState == TelephonyManager.EXTRA_STATE_IDLE) {
|
if (phoneState == TelephonyManager.EXTRA_STATE_IDLE) {
|
||||||
refreshCalls()
|
refreshDeviceData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class SMSReceiver : BroadcastReceiver() {
|
class SMSReceiver : BroadcastReceiver() {
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
BLog.LOGE("SMSReceiver >>> ${intent}")
|
BLog.LOGE("SMSReceiver >>> ${intent}")
|
||||||
refreshSms()
|
refreshDeviceData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -206,6 +206,7 @@ internal class AppDrawer : Fragment() {
|
|||||||
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
|
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
|
||||||
pakage?.let {
|
pakage?.let {
|
||||||
mapIntent.setPackage(pakage)
|
mapIntent.setPackage(pakage)
|
||||||
|
WorkersDb.updateAppUse(pakage)
|
||||||
}
|
}
|
||||||
startActivity(mapIntent)
|
startActivity(mapIntent)
|
||||||
}
|
}
|
||||||
@ -214,7 +215,8 @@ internal class AppDrawer : Fragment() {
|
|||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
binding.searchInput.setOnKeyListener { v, keyCode, event ->
|
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())
|
checkResult(binding.searchInput.text.toString())
|
||||||
true
|
true
|
||||||
}else {
|
}else {
|
||||||
@ -229,85 +231,85 @@ internal class AppDrawer : Fragment() {
|
|||||||
|
|
||||||
fun checkResult(keyword: String) {
|
fun checkResult(keyword: String) {
|
||||||
|
|
||||||
if(!isAdded || !isResumed || keyword.length < 1) return
|
// if(!isAdded || !isResumed || keyword.length < 1) return
|
||||||
var dialog : AlertDialog.Builder? = null
|
// var dialog : AlertDialog.Builder? = null
|
||||||
var filted = packageList.filter { it.appName.equals(keyword) }
|
// var filted = packageList.filter { it.appName.equals(keyword) }
|
||||||
BLog.LOGE("filted >> ${filted.size}")
|
// BLog.LOGE("filted >> ${filted.size}")
|
||||||
var filtedContact = contactList.filter { it.name.equals(keyword) }
|
// var filtedContact = contactList.filter { it.name.equals(keyword) }
|
||||||
BLog.LOGE("filtedContact >> ${filtedContact.size}")
|
// BLog.LOGE("filtedContact >> ${filtedContact.size}")
|
||||||
if (keyword.length > 0 && (packageList.size == 1 || filted.size > 0)) {
|
// if (keyword.length > 0 && (packageList.size == 1 || filted.size > 0)) {
|
||||||
dialog = AlertDialog.Builder(requireContext())
|
// dialog = AlertDialog.Builder(requireContext())
|
||||||
dialog?.setTitle("앱 실행 확인")
|
// dialog?.setTitle("앱 실행 확인")
|
||||||
if (packageList.size == 1) {
|
// if (packageList.size == 1) {
|
||||||
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].pkgName!!))
|
// startActivity(packageManager?.getLaunchIntentForPackage(packageList[0].pkgName!!))
|
||||||
s.dismiss()
|
// s.dismiss()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
} else if (filted.size > 0) {
|
// } else if (filted.size > 0) {
|
||||||
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].pkgName!!))
|
// 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].pkgName!!))
|
// startActivity(packageManager?.getLaunchIntentForPackage(filted[1].pkgName!!))
|
||||||
s.dismiss()
|
// s.dismiss()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
dialog?.setCancelable(false)
|
// dialog?.setCancelable(false)
|
||||||
dialog?.setNegativeButton("취소") { s, d ->
|
// dialog?.setNegativeButton("취소") { s, d ->
|
||||||
runonUi { s.dismiss() }
|
// runonUi { s.dismiss() }
|
||||||
}
|
// }
|
||||||
dialog?.setOnDismissListener { registCancelSearch() }
|
// dialog?.setOnDismissListener { registCancelSearch() }
|
||||||
dialog?.show()
|
// dialog?.show()
|
||||||
} else if (contactList.size == 1 || filtedContact.size > 0) {
|
// } else if (contactList.size == 1 || filtedContact.size > 0) {
|
||||||
dialog = AlertDialog.Builder(requireContext())
|
// dialog = AlertDialog.Builder(requireContext())
|
||||||
dialog?.setTitle("연락처 실행 확인")
|
// dialog?.setTitle("연락처 실행 확인")
|
||||||
dialog?.setCancelable(false)
|
// dialog?.setCancelable(false)
|
||||||
dialog?.setNegativeButton("취소") { s, d ->
|
// dialog?.setNegativeButton("취소") { s, d ->
|
||||||
runonUi { s.dismiss() }
|
// runonUi { s.dismiss() }
|
||||||
}
|
// }
|
||||||
if (contactList.size == 1) {
|
// if (contactList.size == 1) {
|
||||||
dialog?.setMessage("${keyword} 검색 결과 '${contactList[0].name}' 준비됨")
|
// dialog?.setMessage("${keyword} 검색 결과 '${contactList[0].name}' 준비됨")
|
||||||
dialog?.setPositiveButton("자세히 보기") { s, d ->
|
// dialog?.setPositiveButton("자세히 보기") { s, d ->
|
||||||
runonUi {
|
// runonUi {
|
||||||
ContactMenu().show(childFragmentManager, contactList[0].id.toString())
|
// ContactMenu().show(childFragmentManager, contactList[0].id.toString())
|
||||||
s.dismiss()
|
// s.dismiss()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
} else if(filtedContact.size > 0) {
|
// } else if(filtedContact.size > 0) {
|
||||||
dialog?.setMessage("${keyword} 검색 결과 '${filtedContact[0].name}' 준비됨")
|
// dialog?.setMessage("${keyword} 검색 결과 '${filtedContact[0].name}' 준비됨")
|
||||||
dialog?.setPositiveButton("'${filtedContact[0].name},\n${filtedContact[0].phoneNumber}'\n자세히 보기") { s, d ->
|
// dialog?.setPositiveButton("'${filtedContact[0].name},\n${filtedContact[0].phoneNumber}'\n자세히 보기") { s, d ->
|
||||||
runonUi {
|
// runonUi {
|
||||||
ContactMenu().show(childFragmentManager, filtedContact[0].id.toString())
|
// ContactMenu().show(childFragmentManager, filtedContact[0].id.toString())
|
||||||
s.dismiss()
|
// s.dismiss()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
if (filtedContact.size > 1) {
|
// if (filtedContact.size > 1) {
|
||||||
dialog?.setNeutralButton("'${filtedContact[1].name},\n${filtedContact[1].phoneNumber}'\n자세히 보기") { s, d ->
|
// dialog?.setNeutralButton("'${filtedContact[1].name},\n${filtedContact[1].phoneNumber}'\n자세히 보기") { s, d ->
|
||||||
runonUi {
|
// runonUi {
|
||||||
ContactMenu().show(childFragmentManager, filtedContact[1].id.toString())
|
// ContactMenu().show(childFragmentManager, filtedContact[1].id.toString())
|
||||||
s.dismiss()
|
// s.dismiss()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
dialog?.setOnDismissListener { registCancelSearch() }
|
// dialog?.setOnDismissListener { registCancelSearch() }
|
||||||
dialog?.show()
|
// dialog?.show()
|
||||||
} else {
|
// } else {
|
||||||
lActivity?.openSearchMenus(keyword) {
|
lActivity?.openSearchMenus(keyword) {
|
||||||
registCancelSearch()
|
registCancelSearch()
|
||||||
}
|
}
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -39,16 +39,12 @@ import android.view.ViewGroup
|
|||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.widget.LinearLayoutCompat.LayoutParams
|
|
||||||
import androidx.appcompat.widget.PopupMenu
|
import androidx.appcompat.widget.PopupMenu
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.lifecycle.repeatOnLifecycle
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import androidx.work.ExistingPeriodicWorkPolicy
|
|
||||||
import androidx.work.PeriodicWorkRequestBuilder
|
|
||||||
import com.google.android.material.button.MaterialButtonToggleGroup
|
import com.google.android.material.button.MaterialButtonToggleGroup
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import io.realm.kotlin.ext.query
|
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.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.LauncherActivity.Companion.refreshDeviceData
|
||||||
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
|
||||||
@ -82,13 +77,11 @@ import rasel.lunar.launcher.model.MostItem
|
|||||||
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.RssDataType
|
import rasel.lunar.launcher.model.RssDataType
|
||||||
import rasel.lunar.launcher.model.RssItem
|
|
||||||
import rasel.lunar.launcher.model.RssTagItem
|
import rasel.lunar.launcher.model.RssTagItem
|
||||||
import rasel.lunar.launcher.model.dateFormat
|
import rasel.lunar.launcher.model.dateFormat
|
||||||
import rasel.lunar.launcher.model.getRssData
|
import rasel.lunar.launcher.model.getRssData
|
||||||
import rasel.lunar.launcher.utils.BLog
|
import rasel.lunar.launcher.utils.BLog
|
||||||
import rasel.lunar.launcher.utils.RssList.jGuruMain
|
import rasel.lunar.launcher.utils.RssList.jGuruMain
|
||||||
import rasel.lunar.launcher.workers.RecentCallGetter
|
|
||||||
import rasel.lunar.launcher.workers.WorkersDb
|
import rasel.lunar.launcher.workers.WorkersDb
|
||||||
import java.net.URLEncoder
|
import java.net.URLEncoder
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
@ -315,8 +308,7 @@ internal class Feeds : Fragment() , CommadCallabck {
|
|||||||
|
|
||||||
"req" -> {
|
"req" -> {
|
||||||
refreshFeeds()
|
refreshFeeds()
|
||||||
refreshCalls()
|
refreshDeviceData()
|
||||||
refreshSms()
|
|
||||||
consoleLog("excute refreshFeeds()")
|
consoleLog("excute refreshFeeds()")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,42 +19,36 @@
|
|||||||
package rasel.lunar.launcher.home
|
package rasel.lunar.launcher.home
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.BroadcastReceiver
|
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
import android.content.Context
|
import android.content.ContentUris
|
||||||
import android.content.DialogInterface
|
import android.content.DialogInterface
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
|
import android.graphics.Bitmap
|
||||||
import android.net.Uri
|
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.provider.MediaStore
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.View.OnScrollChangeListener
|
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import android.widget.RadioButton
|
import android.widget.RadioButton
|
||||||
import android.widget.RadioGroup
|
|
||||||
import android.widget.TableRow
|
import android.widget.TableRow
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.biometric.BiometricPrompt
|
import androidx.biometric.BiometricPrompt
|
||||||
import androidx.core.content.ContextCompat.RECEIVER_EXPORTED
|
import androidx.core.net.toUri
|
||||||
import androidx.core.content.ContextCompat.registerReceiver
|
|
||||||
import androidx.core.view.children
|
import androidx.core.view.children
|
||||||
import androidx.core.view.isVisible
|
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.FragmentManager
|
import androidx.fragment.app.FragmentManager
|
||||||
import androidx.recyclerview.widget.DividerItemDecoration
|
import androidx.recyclerview.widget.DividerItemDecoration
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
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.ext.query
|
||||||
import io.realm.kotlin.notifications.InitialResults
|
import io.realm.kotlin.notifications.InitialResults
|
||||||
import io.realm.kotlin.notifications.ResultsChange
|
import io.realm.kotlin.notifications.ResultsChange
|
||||||
@ -65,16 +59,12 @@ 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
|
||||||
import org.jsoup.Jsoup
|
|
||||||
import rasel.lunar.launcher.CommadCallabck
|
|
||||||
import rasel.lunar.launcher.LauncherActivity.Companion.CALL_WORK_TAG
|
import rasel.lunar.launcher.LauncherActivity.Companion.CALL_WORK_TAG
|
||||||
import rasel.lunar.launcher.LauncherActivity.Companion.SMS_WORK_TAG
|
import rasel.lunar.launcher.LauncherActivity.Companion.SMS_WORK_TAG
|
||||||
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
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.LauncherActivity.Companion.workmanager
|
||||||
import rasel.lunar.launcher.R
|
import rasel.lunar.launcher.R
|
||||||
import rasel.lunar.launcher.databinding.LauncherHomeBinding
|
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.canAuthenticate
|
||||||
import rasel.lunar.launcher.helpers.UniUtils.Companion.expandNotificationPanel
|
import rasel.lunar.launcher.helpers.UniUtils.Companion.expandNotificationPanel
|
||||||
import rasel.lunar.launcher.helpers.UniUtils.Companion.lockMethod
|
import rasel.lunar.launcher.helpers.UniUtils.Companion.lockMethod
|
||||||
import rasel.lunar.launcher.home.weather.WeatherExecutor
|
import rasel.lunar.launcher.model.CurrentPlayItem
|
||||||
import rasel.lunar.launcher.model.CiliMagnet
|
|
||||||
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.RssDataType
|
||||||
import rasel.lunar.launcher.qaccess.QuickAccess
|
import rasel.lunar.launcher.qaccess.QuickAccess
|
||||||
import rasel.lunar.launcher.settings.SettingsActivity
|
import rasel.lunar.launcher.settings.SettingsActivity
|
||||||
import rasel.lunar.launcher.todos.MissedCallsAdapter
|
import rasel.lunar.launcher.todos.MissedCallsAdapter
|
||||||
import rasel.lunar.launcher.model.RssDataInterface
|
|
||||||
import rasel.lunar.launcher.model.RssDataType
|
|
||||||
import rasel.lunar.launcher.todos.NotificationItemAdapter
|
import rasel.lunar.launcher.todos.NotificationItemAdapter
|
||||||
import rasel.lunar.launcher.todos.RssItemAdapter
|
import rasel.lunar.launcher.todos.RssItemAdapter
|
||||||
import rasel.lunar.launcher.todos.SmsLogsAdapter
|
import rasel.lunar.launcher.todos.SmsLogsAdapter
|
||||||
import rasel.lunar.launcher.utils.BLog
|
import rasel.lunar.launcher.utils.BLog
|
||||||
import rasel.lunar.launcher.utils.JamoUtils
|
import rasel.lunar.launcher.utils.JamoUtils
|
||||||
import rasel.lunar.launcher.utils.RssList.jGuruMain
|
|
||||||
import rasel.lunar.launcher.utils.SimpleFingerGestures
|
import rasel.lunar.launcher.utils.SimpleFingerGestures
|
||||||
import rasel.lunar.launcher.utils.beforeDay
|
import rasel.lunar.launcher.utils.beforeDay
|
||||||
import rasel.lunar.launcher.view.TableRadioGroup
|
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.RecentSms
|
||||||
import rasel.lunar.launcher.workers.WorkersDb
|
import rasel.lunar.launcher.workers.WorkersDb
|
||||||
import java.net.URLEncoder
|
import java.net.URLEncoder
|
||||||
import java.nio.charset.Charset
|
|
||||||
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
|
import java.util.regex.Pattern
|
||||||
@ -222,9 +208,34 @@ internal class LauncherHome : Fragment() {
|
|||||||
it.clear()
|
it.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
// nReceiver = NotificationReceiver()
|
GlobalScope.launch {
|
||||||
// val filter = IntentFilter()
|
WorkersDb.getRealm().apply {
|
||||||
// registerReceiver(requireContext(),nReceiver, filter,RECEIVER_EXPORTED)
|
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()")
|
BLog.LOGE("onCreateView()")
|
||||||
|
|
||||||
@ -605,7 +616,7 @@ internal class LauncherHome : Fragment() {
|
|||||||
} else if(binding.recentSms.isSelected){
|
} else if(binding.recentSms.isSelected){
|
||||||
WorkersDb.getRealm().apply {
|
WorkersDb.getRealm().apply {
|
||||||
val result = query<RecentSms>().query("rcvDate >= $0 OR pstDate >= $0 ", dateParam)
|
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) {
|
if (result.size > 0) {
|
||||||
try {
|
try {
|
||||||
BLog.LOGE("observeForever smsList.size >>> ${result.size}")
|
BLog.LOGE("observeForever smsList.size >>> ${result.size}")
|
||||||
@ -613,7 +624,8 @@ internal class LauncherHome : Fragment() {
|
|||||||
binding.smsList.visibility = View.VISIBLE
|
binding.smsList.visibility = View.VISIBLE
|
||||||
smsList.clear()
|
smsList.clear()
|
||||||
smsList.addAll(copyFromRealm(result))
|
smsList.addAll(copyFromRealm(result))
|
||||||
mSmsLogsAdapter.updateData(smsList)
|
mSmsLogsAdapter.
|
||||||
|
updateData(smsList)
|
||||||
binding.missedCalls.isSelected = false
|
binding.missedCalls.isSelected = false
|
||||||
binding.otherCheck.isSelected = false
|
binding.otherCheck.isSelected = false
|
||||||
binding.notice.isSelected = false
|
binding.notice.isSelected = false
|
||||||
|
|||||||
@ -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
|
||||||
|
}
|
||||||
@ -1,17 +1,22 @@
|
|||||||
package rasel.lunar.launcher.utils
|
package rasel.lunar.launcher.utils
|
||||||
|
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.ComponentName
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.media.MediaMetadata
|
||||||
|
import android.media.session.MediaSessionManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.service.notification.NotificationListenerService
|
import android.service.notification.NotificationListenerService
|
||||||
import android.service.notification.StatusBarNotification
|
import android.service.notification.StatusBarNotification
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.core.content.getSystemService
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import io.realm.kotlin.ext.query
|
import io.realm.kotlin.ext.query
|
||||||
|
import rasel.lunar.launcher.model.CurrentPlayItem
|
||||||
import rasel.lunar.launcher.model.NotificationItem
|
import rasel.lunar.launcher.model.NotificationItem
|
||||||
import rasel.lunar.launcher.workers.WorkersDb
|
import rasel.lunar.launcher.workers.WorkersDb
|
||||||
import java.security.AccessController.getContext
|
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")
|
// val i = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
|
||||||
// i.putExtra("notification_event", "onNotificationPosted :" + sbn.packageName + "\n")
|
// i.putExtra("notification_event", "onNotificationPosted :" + sbn.packageName + "\n")
|
||||||
// sendBroadcast(i)
|
// sendBroadcast(i)
|
||||||
|
|||||||
@ -4,10 +4,12 @@ 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.ext.query
|
||||||
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.apps.SimpleContact
|
||||||
import rasel.lunar.launcher.model.AppInfo
|
import rasel.lunar.launcher.model.AppInfo
|
||||||
|
import rasel.lunar.launcher.model.CurrentPlayItem
|
||||||
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
|
||||||
@ -17,7 +19,8 @@ import kotlin.reflect.KClass
|
|||||||
|
|
||||||
object WorkersDb {
|
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
|
val schemaVersion : Long = 0L
|
||||||
|
|
||||||
private var pRealm : Realm? = null
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -96,6 +96,37 @@
|
|||||||
app:layout_constraintTop_toBottomOf="@+id/time"
|
app:layout_constraintTop_toBottomOf="@+id/time"
|
||||||
app:layout_constraintVertical_bias="0.100" />
|
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
|
<LinearLayout
|
||||||
android:layout_margin="10dp"
|
android:layout_margin="10dp"
|
||||||
android:layout_marginTop="20dp"
|
android:layout_marginTop="20dp"
|
||||||
@ -107,7 +138,7 @@
|
|||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
android:layout_height="40dp"
|
android:layout_height="40dp"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/weather"
|
app:layout_constraintTop_toBottomOf="@+id/current_music"
|
||||||
>
|
>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user