...
This commit is contained in:
parent
e9dff17966
commit
2e9900201e
@ -62,6 +62,8 @@
|
|||||||
android:name=".LauncherActivity"
|
android:name=".LauncherActivity"
|
||||||
android:theme="@style/Theme.LunarLauncher.Starting"
|
android:theme="@style/Theme.LunarLauncher.Starting"
|
||||||
android:launchMode="singleInstance"
|
android:launchMode="singleInstance"
|
||||||
|
android:screenOrientation="portrait"
|
||||||
|
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|screenLayout|layoutDirection"
|
||||||
android:windowSoftInputMode="adjustResize"
|
android:windowSoftInputMode="adjustResize"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
@ -131,13 +133,13 @@
|
|||||||
<action android:name="android.service.notification.NotificationListenerService" />
|
<action android:name="android.service.notification.NotificationListenerService" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</service>
|
</service>
|
||||||
<receiver android:name=".home.EndCallReceiver"
|
<receiver android:name=".LauncherActivity$EndCallReceiver"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.PHONE_STATE" />
|
<action android:name="android.intent.action.PHONE_STATE" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
<receiver android:name=".home.SMSReceiver"
|
<receiver android:name=".LauncherActivity$SMSReceiver"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:permission="android.permission.BROADCAST_SMS">
|
android:permission="android.permission.BROADCAST_SMS">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
|||||||
@ -20,19 +20,31 @@ package rasel.lunar.launcher
|
|||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.appwidget.AppWidgetManager
|
import android.appwidget.AppWidgetManager
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
|
import android.graphics.Bitmap
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import android.net.http.SslError
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.provider.CallLog
|
import android.provider.CallLog
|
||||||
import android.provider.ContactsContract
|
import android.provider.ContactsContract
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
|
import android.telephony.TelephonyManager
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
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.SslErrorHandler
|
||||||
|
import android.webkit.WebSettings
|
||||||
|
import android.webkit.WebView
|
||||||
|
import android.webkit.WebViewClient
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.activity.OnBackPressedCallback
|
import androidx.activity.OnBackPressedCallback
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
@ -44,8 +56,13 @@ import androidx.core.view.WindowInsetsCompat
|
|||||||
import androidx.core.view.updatePadding
|
import androidx.core.view.updatePadding
|
||||||
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.PeriodicWorkRequestBuilder
|
||||||
|
import androidx.work.WorkManager
|
||||||
import com.google.android.material.color.DynamicColors
|
import com.google.android.material.color.DynamicColors
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import org.jsoup.Jsoup
|
||||||
|
import org.jsoup.nodes.Document
|
||||||
import rasel.lunar.launcher.apps.AppDrawer
|
import rasel.lunar.launcher.apps.AppDrawer
|
||||||
import rasel.lunar.launcher.apps.DismissCalback
|
import rasel.lunar.launcher.apps.DismissCalback
|
||||||
import rasel.lunar.launcher.apps.SearchMenu
|
import rasel.lunar.launcher.apps.SearchMenu
|
||||||
@ -62,8 +79,20 @@ import rasel.lunar.launcher.helpers.Constants.Companion.widgetHostId
|
|||||||
import rasel.lunar.launcher.helpers.UniUtils.Companion.getColorResId
|
import rasel.lunar.launcher.helpers.UniUtils.Companion.getColorResId
|
||||||
import rasel.lunar.launcher.helpers.ViewPagerAdapter
|
import rasel.lunar.launcher.helpers.ViewPagerAdapter
|
||||||
import rasel.lunar.launcher.home.LauncherHome
|
import rasel.lunar.launcher.home.LauncherHome
|
||||||
|
import rasel.lunar.launcher.home.LauncherHome.Companion.lastedFinishedPageUrl
|
||||||
|
import rasel.lunar.launcher.home.LauncherHome.Companion.listItem
|
||||||
|
import rasel.lunar.launcher.home.LauncherHome.Companion.listTags
|
||||||
|
import rasel.lunar.launcher.home.RssItem
|
||||||
|
import rasel.lunar.launcher.home.RssTagItem
|
||||||
import rasel.lunar.launcher.utils.BLog
|
import rasel.lunar.launcher.utils.BLog
|
||||||
|
import rasel.lunar.launcher.utils.MissedCallGetter
|
||||||
|
import rasel.lunar.launcher.utils.NewsFeedsGetter
|
||||||
|
import rasel.lunar.launcher.utils.RecentSmsGetter
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
import java.util.Locale
|
||||||
|
import java.util.concurrent.Executors
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
|
||||||
internal class LauncherActivity : AppCompatActivity() {
|
internal class LauncherActivity : AppCompatActivity() {
|
||||||
@ -74,15 +103,69 @@ internal class LauncherActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val TEST_PAG = "https://jav.guru/"
|
val TEST_PAG = "https://jav.guru/"
|
||||||
|
private var mWorkManager: WorkManager? = null
|
||||||
val TEST_PAG2 = "https://torrentsee246.com/topic/index?category1=129&category2=132"
|
val TEST_PAG2 = "https://torrentsee246.com/topic/index?category1=129&category2=132"
|
||||||
|
|
||||||
|
val SMS_WORK_TAG = "RecentSmsGetter"
|
||||||
|
val CALL_WORK_TAG = "MissedCallGetter"
|
||||||
|
val FEDDS_WORK_TAG = "NewsFeedsGetter"
|
||||||
|
|
||||||
@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() {
|
||||||
|
Executors.newSingleThreadScheduledExecutor().schedule({
|
||||||
|
mWorkManager?.cancelAllWorkByTag(SMS_WORK_TAG)
|
||||||
|
mWorkManager?.enqueueUniquePeriodicWork(
|
||||||
|
SMS_WORK_TAG,
|
||||||
|
ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
|
||||||
|
PeriodicWorkRequestBuilder<RecentSmsGetter>(30, TimeUnit.MINUTES)
|
||||||
|
.addTag(SMS_WORK_TAG)
|
||||||
|
.build())
|
||||||
|
}, 2, TimeUnit.SECONDS)
|
||||||
|
}
|
||||||
|
fun refreshCalls() {
|
||||||
|
Executors.newSingleThreadScheduledExecutor().schedule({
|
||||||
|
mWorkManager?.cancelAllWorkByTag(CALL_WORK_TAG)
|
||||||
|
mWorkManager?.enqueueUniquePeriodicWork(
|
||||||
|
CALL_WORK_TAG,
|
||||||
|
ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
|
||||||
|
PeriodicWorkRequestBuilder<MissedCallGetter>(30, TimeUnit.MINUTES)
|
||||||
|
.addTag(CALL_WORK_TAG)
|
||||||
|
.build())
|
||||||
|
}, 2, TimeUnit.SECONDS)
|
||||||
|
}
|
||||||
|
fun refreshFeeds() {
|
||||||
|
Executors.newSingleThreadScheduledExecutor().schedule({
|
||||||
|
mWorkManager?.cancelAllWorkByTag(FEDDS_WORK_TAG)
|
||||||
|
mWorkManager?.enqueueUniquePeriodicWork(
|
||||||
|
FEDDS_WORK_TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
|
||||||
|
PeriodicWorkRequestBuilder<NewsFeedsGetter>(30, TimeUnit.MINUTES)
|
||||||
|
.addTag(FEDDS_WORK_TAG)
|
||||||
|
.build())
|
||||||
|
}, 2, TimeUnit.SECONDS)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun workmanager() : WorkManager? {
|
||||||
|
if (mWorkManager == null && lActivity != null) {
|
||||||
|
mWorkManager = WorkManager.getInstance(lActivity!!)
|
||||||
|
}
|
||||||
|
return mWorkManager
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNewIntent(intent: Intent?) {
|
||||||
|
super.onNewIntent(intent)
|
||||||
|
binding.viewPager.invalidate()
|
||||||
|
binding.viewPager.post {
|
||||||
|
binding.viewPager?.adapter?.notifyDataSetChanged()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
installSplashScreen()
|
installSplashScreen()
|
||||||
|
mWorkManager = WorkManager.getInstance(this)
|
||||||
DynamicColors.applyToActivityIfAvailable(this)
|
DynamicColors.applyToActivityIfAvailable(this)
|
||||||
|
|
||||||
settingsPrefs = getSharedPreferences(PREFS_SETTINGS, 0)
|
settingsPrefs = getSharedPreferences(PREFS_SETTINGS, 0)
|
||||||
@ -105,6 +188,9 @@ internal class LauncherActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
/* handle navigation back events */
|
/* handle navigation back events */
|
||||||
handleBackPress()
|
handleBackPress()
|
||||||
|
refreshSms()
|
||||||
|
refreshCalls()
|
||||||
|
refreshFeeds()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
@ -274,5 +360,175 @@ internal class LauncherActivity : AppCompatActivity() {
|
|||||||
SearchMenu().show(supportFragmentManager,keyword) {dismissCalback?.invoke()}
|
SearchMenu().show(supportFragmentManager,keyword) {dismissCalback?.invoke()}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class EndCallReceiver : BroadcastReceiver() {
|
||||||
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
|
BLog.LOGE("EndCallReceiver >>> ${intent}")
|
||||||
|
val phoneState = intent.getStringExtra(TelephonyManager.EXTRA_STATE) ?: return
|
||||||
|
if (phoneState == TelephonyManager.EXTRA_STATE_IDLE) {
|
||||||
|
refreshCalls()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class SMSReceiver : BroadcastReceiver() {
|
||||||
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
|
BLog.LOGE("SMSReceiver >>> ${intent}")
|
||||||
|
refreshSms()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun doWebPare(url : String, callBack : (()->Unit)?) {
|
||||||
|
BLog.LOGE("binding.otherCheck before ThreadRun")
|
||||||
|
binding.searcher01.webViewClient = object : WebViewClient() {
|
||||||
|
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
|
||||||
|
BLog.LOGE("binding.otherCheck searcher01 in onPageStarted ${url}")
|
||||||
|
super.onPageStarted(view, url, favicon)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onReceivedSslError(
|
||||||
|
view: WebView?,
|
||||||
|
handler: SslErrorHandler?,
|
||||||
|
error: SslError?
|
||||||
|
) {
|
||||||
|
handler?.proceed()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun onPageFinished(view: WebView?, url: String?) {
|
||||||
|
super.onPageFinished(view, url)
|
||||||
|
lastedFinishedPageUrl = url ?: ""
|
||||||
|
BLog.LOGE("binding.otherCheck searcher01 in onPageFinished ${url}")
|
||||||
|
|
||||||
|
if (url?.contains("youtube", false) == true) {
|
||||||
|
view?.evaluateJavascript(
|
||||||
|
"function getAll() {\n" +
|
||||||
|
" MyJavaScriptInterface.sendValueFromHtml(document.getElementsByTagName('html')[0].innerHTML)" +
|
||||||
|
" };getAll()"
|
||||||
|
) { result ->
|
||||||
|
(result as? String)?.let {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
view?.evaluateJavascript(
|
||||||
|
"function getAll() {\n" +
|
||||||
|
" MyJavaScriptInterface.sendValueFromHtml(document.getElementsByTagName('html')[0].innerHTML)" +
|
||||||
|
" };getAll()"
|
||||||
|
) { result ->
|
||||||
|
(result as? String)?.let {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callBack?.invoke()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WebView.setWebContentsDebuggingEnabled(false)
|
||||||
|
binding.searcher01.apply {
|
||||||
|
this.addJavascriptInterface(MyJavaScriptInterface(this),"MyJavaScriptInterface")
|
||||||
|
setBackgroundColor(Color.WHITE) // 백그라운드 색상 설정
|
||||||
|
setLayerType(View.LAYER_TYPE_SOFTWARE, null) // 랜더링 이슈 해결
|
||||||
|
try {
|
||||||
|
settings.apply {
|
||||||
|
javaScriptEnabled = true // 자바스크립트 사용 가능하도록 설정
|
||||||
|
loadWithOverviewMode = true // 전체 웹페이지를 화면에 맞게 로드
|
||||||
|
useWideViewPort = true // 화면에 맞게 페이지 확대/축소
|
||||||
|
domStorageEnabled = true // DOM 저장소 사용 가능하도록 설정
|
||||||
|
setSupportMultipleWindows(true)
|
||||||
|
javaScriptCanOpenWindowsAutomatically = true // 팝업창 차단 해제
|
||||||
|
cacheMode = WebSettings.LOAD_CACHE_ELSE_NETWORK
|
||||||
|
textZoom = 100 // system 에 의한 글꼴 변형 방지
|
||||||
|
defaultTextEncodingName = "UTF-8" // 인코딩 설정
|
||||||
|
allowContentAccess = true // 웹뷰를 통해 content url에 접근할지 여부
|
||||||
|
layoutAlgorithm = WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING // 웹페이지의 레이아웃을 화면에 맞게 자동으로 조정
|
||||||
|
}
|
||||||
|
} catch (ignore: NoSuchMethodError) {}
|
||||||
|
loadUrl(url) // 웹페이지 연결
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var maxDate : Long = Long.MIN_VALUE
|
||||||
|
var minDate : Long = Long.MAX_VALUE
|
||||||
|
val simpldateFormat = SimpleDateFormat("d MMM, yy", Locale.US)
|
||||||
|
fun jGuruMain(doc: Document) {
|
||||||
|
BLog.LOGE("do default parsing")
|
||||||
|
BLog.LOGE("SimpleDateFormat D MM yy => ${SimpleDateFormat("d MMM yy", Locale.US).format(Date())}")
|
||||||
|
val prevUrl = doc.getElementsByClass("prev").get(0).getElementsByAttribute("href").get(0).attr("href")
|
||||||
|
BLog.LOGE("doc.getElementsByClass(prev).get(0).html() ${prevUrl}")
|
||||||
|
doc.getElementsByClass("column").forEach {
|
||||||
|
var title = it.getElementsByAttribute("title").get(0).text()
|
||||||
|
var model = title.replace("[","").split("]")[0]
|
||||||
|
var pageLink = it.getElementsByClass("imgg").get(0).getElementsByAttribute("href").get(0).attr("href")
|
||||||
|
var imgg = it.getElementsByClass("imgg").get(0).getElementsByAttribute("src").get(0).attr("src")
|
||||||
|
var tags = it.getElementsByClass("tags").get(0).text()
|
||||||
|
var date = it.getElementsByClass("date").get(0).text()
|
||||||
|
var regDate = simpldateFormat.parse(date).time
|
||||||
|
|
||||||
|
minDate = Math.min(minDate,regDate)
|
||||||
|
|
||||||
|
maxDate = Math.max(maxDate,regDate)
|
||||||
|
|
||||||
|
listItem.add(RssItem(model = model, title = title, pageLink = pageLink, image = imgg, tags = tags, date = simpldateFormat.parse(date).time))
|
||||||
|
}.apply {
|
||||||
|
|
||||||
|
BLog.LOGE("listItem.size >>> ${listItem.size}")
|
||||||
|
if (prevUrl!=null && prevUrl.length > TEST_PAG.length && prevUrl.contains("/page/") && (maxDate - minDate) < (1000L * 60L * 60L * 24L * 3L)) {
|
||||||
|
BLog.LOGE("listItem.size >>> ${listItem.size} do next ")
|
||||||
|
BLog.LOGE("saving data :: ${listItem.size}items ${simpldateFormat.format(Date(minDate))} ~ ${simpldateFormat.format(Date(maxDate))}")
|
||||||
|
binding.searcher01.postDelayed({binding.searcher01.loadUrl(prevUrl)}, 5000L)
|
||||||
|
} else {
|
||||||
|
listItem.sortByDescending { it.date }
|
||||||
|
BLog.LOGE("Stored data :: ${listItem.size}items ${simpldateFormat.format(Date(minDate))} ~ ${simpldateFormat.format(Date(maxDate))}")
|
||||||
|
Toast.makeText(this@LauncherActivity,
|
||||||
|
"Stored data :: ${listItem.size} items :: [${simpldateFormat.format(Date(minDate))} ~ ${simpldateFormat.format(Date(maxDate))}]", Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun jGuruTag(doc: Document) {
|
||||||
|
listTags.clear()
|
||||||
|
doc.getElementsByTag("ul").forEach {
|
||||||
|
it.children().forEach {
|
||||||
|
if (it.tag().name.contains("li")) {
|
||||||
|
listTags.add(
|
||||||
|
RssTagItem(
|
||||||
|
tagTitle = it.getElementsByTag("a").get(0).text(),
|
||||||
|
link = it.getElementsByTag("a").get(0).attr("href")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.apply {
|
||||||
|
listTags.sortByDescending { it.count }
|
||||||
|
Toast.makeText(this@LauncherActivity,
|
||||||
|
"Stored data :: ${listTags.size}tags", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class MyJavaScriptInterface(val webView: WebView) {
|
||||||
|
|
||||||
|
|
||||||
|
@JavascriptInterface
|
||||||
|
fun sendValueFromHtml(result: String) {
|
||||||
|
|
||||||
|
if (lastedFinishedPageUrl.contains(TEST_PAG)) {
|
||||||
|
var htmlString = result.replace("\\u003","<")
|
||||||
|
val doc: Document = Jsoup.parse(htmlString)
|
||||||
|
if (lastedFinishedPageUrl?.contains("page") == true || lastedFinishedPageUrl?.equals(
|
||||||
|
TEST_PAG
|
||||||
|
) == true
|
||||||
|
) {
|
||||||
|
jGuruMain(doc)
|
||||||
|
} else if (lastedFinishedPageUrl?.contains("/tags/") == true) {
|
||||||
|
jGuruTag(doc)
|
||||||
|
}
|
||||||
|
} else if (lastedFinishedPageUrl?.contains("youtube") == true) {
|
||||||
|
// val doc: Document = Jsoup.parse(result)
|
||||||
|
// ytChannel(doc)
|
||||||
|
}
|
||||||
|
BLog.LOGE("binding.otherCheck after ThreadRun")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,41 +22,36 @@ import android.R.attr.*
|
|||||||
import android.app.Activity.RESULT_CANCELED
|
import android.app.Activity.RESULT_CANCELED
|
||||||
import android.app.Activity.RESULT_OK
|
import android.app.Activity.RESULT_OK
|
||||||
import android.appwidget.AppWidgetManager
|
import android.appwidget.AppWidgetManager
|
||||||
|
import android.content.DialogInterface
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.os.*
|
import android.os.*
|
||||||
import android.view.*
|
import android.view.*
|
||||||
|
import android.widget.EditText
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.widget.LinearLayoutCompat.LayoutParams
|
import androidx.appcompat.widget.LinearLayoutCompat.LayoutParams
|
||||||
import androidx.appcompat.widget.PopupMenu
|
import androidx.appcompat.widget.PopupMenu
|
||||||
import androidx.core.app.JobIntentService.enqueueWork
|
|
||||||
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 com.google.android.material.button.MaterialButtonToggleGroup
|
import com.google.android.material.button.MaterialButtonToggleGroup
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
|
import rasel.lunar.launcher.LauncherActivity.Companion.TEST_PAG
|
||||||
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.R
|
import rasel.lunar.launcher.R
|
||||||
import rasel.lunar.launcher.databinding.FeedsBinding
|
import rasel.lunar.launcher.databinding.FeedsBinding
|
||||||
import rasel.lunar.launcher.feeds.rss.Rss
|
|
||||||
import rasel.lunar.launcher.feeds.rss.RssAdapter
|
import rasel.lunar.launcher.feeds.rss.RssAdapter
|
||||||
import rasel.lunar.launcher.feeds.rss.RssService
|
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_RSS_URL
|
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_RSS_URL2
|
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_WIDGET_HEIGHTS
|
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_WIDGET_HEIGHTS
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_WIDGET_IDS
|
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_WIDGET_IDS
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_SETTINGS
|
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_WIDGETS
|
import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_WIDGETS
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.RSS_ITEMS
|
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.RSS_RECEIVER
|
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.SEPARATOR
|
import rasel.lunar.launcher.helpers.Constants.Companion.SEPARATOR
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.requestCreateWidget
|
import rasel.lunar.launcher.helpers.Constants.Companion.requestCreateWidget
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.requestPickWidget
|
import rasel.lunar.launcher.helpers.Constants.Companion.requestPickWidget
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.rssJobId
|
import rasel.lunar.launcher.home.LauncherHome.Companion.listItem
|
||||||
import rasel.lunar.launcher.helpers.UniUtils.Companion.isNetworkAvailable
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
@ -64,18 +59,18 @@ internal class Feeds : Fragment() {
|
|||||||
|
|
||||||
private lateinit var binding: FeedsBinding
|
private lateinit var binding: FeedsBinding
|
||||||
private val requestCodeString = "requestCode"
|
private val requestCodeString = "requestCode"
|
||||||
|
var mRssAdapter : RssAdapter? = null
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||||
binding = FeedsBinding.inflate(inflater, container, false)
|
binding = FeedsBinding.inflate(inflater, container, false)
|
||||||
|
mRssAdapter = RssAdapter(listItem, requireContext())
|
||||||
|
binding.feedsRss.rss.adapter = mRssAdapter
|
||||||
updateWidgets()
|
updateWidgets()
|
||||||
|
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
binding.feedsRss.rss.adapter = RssAdapter(arrayListOf(), requireContext())
|
|
||||||
expandCollapse()
|
expandCollapse()
|
||||||
systemInfo()
|
systemInfo()
|
||||||
}
|
}
|
||||||
@ -88,6 +83,8 @@ internal class Feeds : Fragment() {
|
|||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
super.onPause()
|
super.onPause()
|
||||||
unregisterForContextMenu(binding.widgetContainer)
|
unregisterForContextMenu(binding.widgetContainer)
|
||||||
|
if (binding.expandRss.isChecked)
|
||||||
|
binding.expandRss.isChecked = false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenu.ContextMenuInfo?) {
|
override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenu.ContextMenuInfo?) {
|
||||||
@ -125,65 +122,118 @@ internal class Feeds : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* start rss service if network is active and rss url is not empty */
|
/* start rss service if network is active and rss url is not empty */
|
||||||
private fun startService() {
|
private fun startService() {
|
||||||
binding.feedsRss.apply {
|
binding.feedsRss.rss.visibility = View.GONE
|
||||||
if(rss.adapter != null) {
|
binding.feedsRss.loading.visibility = View.VISIBLE
|
||||||
(rss.adapter as RssAdapter).items.clear()
|
binding.feedsRss.refresh.visibility = View.VISIBLE
|
||||||
}
|
val builder: AlertDialog.Builder = AlertDialog.Builder(requireContext())
|
||||||
}
|
builder.setTitle("Title")
|
||||||
val rssUrl = lActivity!!.getSharedPreferences(PREFS_SETTINGS, 0)
|
val viewInflated: View = LayoutInflater.from(context)
|
||||||
.getString(KEY_RSS_URL, "")
|
.inflate(R.layout.text_inpu_password, view as ViewGroup?, false)
|
||||||
when {
|
val input = viewInflated.findViewById<View>(R.id.input) as EditText
|
||||||
isNetworkAvailable && !rssUrl.isNullOrEmpty() -> {
|
builder.setView(viewInflated)
|
||||||
Intent(lActivity!!, RssService::class.java)
|
builder.setPositiveButton(android.R.string.ok,
|
||||||
.putExtra(RSS_RECEIVER, resultReceiver).let {
|
DialogInterface.OnClickListener { dialog, which ->
|
||||||
enqueueWork(lActivity!!, RssService::class.java, rssJobId, it)
|
dialog.dismiss()
|
||||||
|
when(input.text.toString()) {
|
||||||
|
"jJguru","vVioPup*383v" -> {
|
||||||
|
mRssAdapter?.updateData(listItem)
|
||||||
|
binding.feedsRss.apply {
|
||||||
|
loading.visibility = View.VISIBLE
|
||||||
|
if (listItem.size > 0) {
|
||||||
|
rss.visibility = View.VISIBLE
|
||||||
|
loading.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
refresh.visibility = View.VISIBLE
|
||||||
|
rss.visibility = View.GONE
|
||||||
|
refresh.setOnClickListener {
|
||||||
|
lActivity?.doWebPare(TEST_PAG) {
|
||||||
|
if (listItem.size > 0) {
|
||||||
|
mRssAdapter?.updateData(listItem)
|
||||||
|
rss?.post {
|
||||||
|
loading.visibility = View.GONE
|
||||||
|
refresh.visibility = View.GONE
|
||||||
|
rss.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
"jJTag"-> {
|
||||||
else -> resumeService()
|
// lActivity?.doWebPare(TEST_PAG.plus("tags"))
|
||||||
}
|
|
||||||
val rssUrl2 = lActivity!!.getSharedPreferences(PREFS_SETTINGS, 0)
|
|
||||||
.getString(KEY_RSS_URL2, "")
|
|
||||||
when {
|
|
||||||
isNetworkAvailable && !rssUrl2.isNullOrEmpty() -> {
|
|
||||||
Intent(lActivity!!, RssService::class.java)
|
|
||||||
.putExtra(RSS_RECEIVER, resultReceiver).let {
|
|
||||||
enqueueWork(lActivity!!, RssService::class.java, rssJobId, it)
|
|
||||||
}
|
}
|
||||||
}
|
else -> {
|
||||||
else -> resumeService()
|
binding.expandRss.isChecked = false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
builder.setNegativeButton(android.R.string.cancel,
|
||||||
|
DialogInterface.OnClickListener { dialog, which -> dialog.cancel() })
|
||||||
|
|
||||||
|
builder.show()
|
||||||
|
// binding.feedsRss.apply {
|
||||||
|
// if(rss.adapter != null) {
|
||||||
|
// (rss.adapter as RssAdapter).items.clear()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// val rssUrl = lActivity!!.getSharedPreferences(PREFS_SETTINGS, 0)
|
||||||
|
// .getString(KEY_RSS_URL, "")
|
||||||
|
// when {
|
||||||
|
// isNetworkAvailable && !rssUrl.isNullOrEmpty() -> {
|
||||||
|
//// Intent(lActivity!!, RssService::class.java)
|
||||||
|
//// .putExtra(RSS_RECEIVER, resultReceiver).let {
|
||||||
|
//// enqueueWork(lActivity!!, RssService::class.java, rssJobId, it)
|
||||||
|
//// }
|
||||||
|
// }
|
||||||
|
// else -> resumeService()
|
||||||
|
// }
|
||||||
|
// val rssUrl2 = lActivity!!.getSharedPreferences(PREFS_SETTINGS, 0)
|
||||||
|
// .getString(KEY_RSS_URL2, "")
|
||||||
|
// when {
|
||||||
|
// isNetworkAvailable && !rssUrl2.isNullOrEmpty() -> {
|
||||||
|
// Intent(lActivity!!, RssService::class.java)
|
||||||
|
// .putExtra(RSS_RECEIVER, resultReceiver).let {
|
||||||
|
// enqueueWork(lActivity!!, RssService::class.java, rssJobId, it)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else -> resumeService()
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* retry to start rss service */
|
/* retry to start rss service */
|
||||||
private fun resumeService() {
|
private fun resumeService() {
|
||||||
binding.feedsRss.apply {
|
binding.feedsRss.apply {
|
||||||
rss.visibility = View.GONE
|
rss.visibility = View.GONE
|
||||||
loading.visibility = View.GONE
|
loading.visibility = View.GONE
|
||||||
refresh.visibility = View.VISIBLE
|
refresh.visibility = View.VISIBLE
|
||||||
refresh.setOnClickListener { startService() }
|
refresh.setOnClickListener {
|
||||||
|
mRssAdapter?.notifyDataSetChanged()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* rss service's result receiver */
|
/* rss service's result receiver */
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
private val resultReceiver: ResultReceiver = object : ResultReceiver(Handler(Looper.getMainLooper())) {
|
private val resultReceiver: ResultReceiver = object : ResultReceiver(Handler(Looper.getMainLooper())) {
|
||||||
override fun onReceiveResult(resultCode: Int, resultData: Bundle) {
|
// override fun onReceiveResult(resultCode: Int, resultData: Bundle) {
|
||||||
when (val items = resultData.getSerializable(RSS_ITEMS) as List<Rss>?) {
|
// when (val items = resultData.getSerializable(RSS_ITEMS) as List<Rss>?) {
|
||||||
null -> resumeService()
|
// null -> resumeService()
|
||||||
else -> {
|
// else -> {
|
||||||
binding.feedsRss.apply {
|
// binding.feedsRss.apply {
|
||||||
if(rss.adapter != null) {
|
// if(rss.adapter != null) {
|
||||||
(rss.adapter as RssAdapter).items.addAll(items)
|
// (rss.adapter as RssAdapter).items.addAll(items)
|
||||||
}
|
// }
|
||||||
refresh.visibility = View.GONE
|
// refresh.visibility = View.GONE
|
||||||
loading.visibility = View.GONE
|
// loading.visibility = View.GONE
|
||||||
rss.visibility = View.VISIBLE
|
// rss.visibility = View.VISIBLE
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun systemInfo() {
|
private fun systemInfo() {
|
||||||
|
|||||||
@ -225,7 +225,7 @@ internal class SystemStats {
|
|||||||
currentFreq = curFreq.toDouble() / 1000
|
currentFreq = curFreq.toDouble() / 1000
|
||||||
readerCurFreq.close()
|
readerCurFreq.close()
|
||||||
currentFReq = currentFreq.toInt()
|
currentFReq = currentFreq.toInt()
|
||||||
println("$currentFReq----------------------------------------------------")
|
// println("$currentFReq----------------------------------------------------")
|
||||||
} catch (ex: java.lang.Exception) {
|
} catch (ex: java.lang.Exception) {
|
||||||
ex.printStackTrace()
|
ex.printStackTrace()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,63 +23,103 @@ import android.view.ViewGroup
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
import android.view.Gravity
|
import android.view.Gravity
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import android.view.View
|
||||||
import androidx.browser.customtabs.CustomTabsIntent
|
import androidx.browser.customtabs.CustomTabsIntent
|
||||||
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
|
import com.squareup.picasso.Picasso
|
||||||
|
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
||||||
import rasel.lunar.launcher.databinding.ListItemBinding
|
import rasel.lunar.launcher.databinding.ListItemBinding
|
||||||
|
import rasel.lunar.launcher.databinding.ListItemWithBinding
|
||||||
import rasel.lunar.launcher.helpers.UniUtils.Companion.getColorResId
|
import rasel.lunar.launcher.helpers.UniUtils.Companion.getColorResId
|
||||||
|
import rasel.lunar.launcher.home.RssItem
|
||||||
|
import rasel.lunar.launcher.todos.RssDataItem
|
||||||
|
import rasel.lunar.launcher.todos.RssItemDiffUtil
|
||||||
|
import java.net.URLEncoder
|
||||||
|
import java.nio.charset.Charset
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
|
|
||||||
internal class RssAdapter(var items: ArrayList<Rss> = arrayListOf(), private val context: Context) :
|
internal class RssAdapter(var items: ArrayList<RssItem> = arrayListOf(), private val context: Context) :
|
||||||
RecyclerView.Adapter<RssAdapter.RssViewHolder>() {
|
RecyclerView.Adapter<RssAdapter.RssViewHolder>() {
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RssViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RssViewHolder {
|
||||||
val binding = ListItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
val binding = ListItemWithBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||||
return RssViewHolder(binding)
|
return RssViewHolder(binding)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int = items.size
|
override fun getItemCount(): Int = items.size
|
||||||
|
val dateFormat = SimpleDateFormat("hh:mm / yy - MM - dd")
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
override fun onBindViewHolder(holder: RssViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: RssViewHolder, position: Int) {
|
||||||
|
val item = items[position]
|
||||||
/* customize the first item */
|
/* customize the first item */
|
||||||
if (position == 0) {
|
// if (position == 0) {
|
||||||
holder.view.itemText.apply {
|
holder.view.title.apply {
|
||||||
text = "\u22B6 " + items[position].title + " \u22B7"
|
text = item.title
|
||||||
gravity = Gravity.CENTER
|
}
|
||||||
setTextColor(ContextCompat.getColor(context,
|
holder.view.date.text = dateFormat.format(Date(item.date))
|
||||||
getColorResId(context, com.google.android.material.R.attr.colorPrimary)))
|
holder.view.desc.text = item.tags.plus("\n").plus(item.model)
|
||||||
setTypeface(null, Typeface.BOLD)
|
holder.view.circlePreview.visibility = View.GONE
|
||||||
textSize = 20f
|
/* reset customization for rest */
|
||||||
}
|
// } else {
|
||||||
/* reset customization for rest */
|
// holder.view.desc.apply {
|
||||||
} else {
|
// text = items[position].title
|
||||||
holder.view.itemText.apply {
|
//// gravity = holder.gravity
|
||||||
text = items[position].title
|
//// setTextColor(holder.color)
|
||||||
gravity = holder.gravity
|
//// typeface = holder.typeface
|
||||||
setTextColor(holder.color)
|
//// setTextSize(TypedValue.COMPLEX_UNIT_PX, holder.size)
|
||||||
typeface = holder.typeface
|
// }
|
||||||
setTextSize(TypedValue.COMPLEX_UNIT_PX, holder.size)
|
// }
|
||||||
}
|
Picasso.get().load(item.image).into(holder.view.circlePreview)
|
||||||
|
holder.view.root.setOnClickListener {
|
||||||
|
holder.view.circlePreview.visibility = View.VISIBLE
|
||||||
|
holder.view.circlePreview.postDelayed({
|
||||||
|
holder.view.circlePreview.visibility = View.GONE
|
||||||
|
},500L)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* on click - open in browser */
|
/* on click - open in browser */
|
||||||
holder.view.itemText.setOnClickListener {
|
holder.view.root.setOnLongClickListener {
|
||||||
val customTabsIntent = CustomTabsIntent.Builder().setUrlBarHidingEnabled(true).build()
|
openOpera("https://cili.site/search?q=${URLEncoder.encode(item.model, Charset.defaultCharset().name())}")
|
||||||
customTabsIntent.launchUrl(context, Uri.parse(items[position].link))
|
openOpera(item.pageLink)
|
||||||
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class RssViewHolder(var view: ListItemBinding) : RecyclerView.ViewHolder(view.root) {
|
fun openOpera(schemeString : String) {
|
||||||
/* store previous styles for resetting */
|
val gmmIntentUri = Uri.parse(schemeString)
|
||||||
var gravity: Int = view.itemText.gravity
|
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
|
||||||
var color: ColorStateList = view.itemText.textColors
|
mapIntent.setPackage("com.opera.browser")
|
||||||
var typeface: Typeface = view.itemText.typeface
|
lActivity?.startActivity(mapIntent)
|
||||||
var size: Float = view.itemText.textSize
|
}
|
||||||
|
|
||||||
|
fun updateData(newList: List<RssItem>) {
|
||||||
|
DiffUtil.calculateDiff(RssItemDiffUtil(items, newList)).dispatchUpdatesTo(this)
|
||||||
|
}
|
||||||
|
inner class RssViewHolder(var view: ListItemWithBinding) : RecyclerView.ViewHolder(view.root) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
internal class RssItemDiffUtil(
|
||||||
|
private val oldList: List<RssItem>, private val newList: List<RssItem>
|
||||||
|
) : DiffUtil.Callback() {
|
||||||
|
|
||||||
|
override fun getOldListSize(): Int = oldList.size
|
||||||
|
override fun getNewListSize(): Int = newList.size
|
||||||
|
|
||||||
|
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean =
|
||||||
|
oldList[oldItemPosition].pageLink == newList[newItemPosition].pageLink
|
||||||
|
|
||||||
|
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean =
|
||||||
|
oldList[oldItemPosition].pageLink == newList[newItemPosition].pageLink
|
||||||
|
}
|
||||||
@ -48,6 +48,7 @@ import androidx.core.content.ContextCompat.RECEIVER_EXPORTED
|
|||||||
import androidx.core.content.ContextCompat.registerReceiver
|
import androidx.core.content.ContextCompat.registerReceiver
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.FragmentManager
|
import androidx.fragment.app.FragmentManager
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.work.ExistingPeriodicWorkPolicy
|
import androidx.work.ExistingPeriodicWorkPolicy
|
||||||
import androidx.work.PeriodicWorkRequestBuilder
|
import androidx.work.PeriodicWorkRequestBuilder
|
||||||
import androidx.work.WorkManager
|
import androidx.work.WorkManager
|
||||||
@ -59,8 +60,12 @@ import org.jsoup.Jsoup
|
|||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
import org.xmlpull.v1.XmlPullParser
|
import org.xmlpull.v1.XmlPullParser
|
||||||
import org.xmlpull.v1.XmlPullParserFactory
|
import org.xmlpull.v1.XmlPullParserFactory
|
||||||
|
import rasel.lunar.launcher.LauncherActivity.Companion.CALL_WORK_TAG
|
||||||
|
import rasel.lunar.launcher.LauncherActivity.Companion.FEDDS_WORK_TAG
|
||||||
|
import rasel.lunar.launcher.LauncherActivity.Companion.SMS_WORK_TAG
|
||||||
import rasel.lunar.launcher.LauncherActivity.Companion.TEST_PAG
|
import rasel.lunar.launcher.LauncherActivity.Companion.TEST_PAG
|
||||||
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
||||||
|
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
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.BOTTOM_SHEET_TAG
|
import rasel.lunar.launcher.helpers.Constants.Companion.BOTTOM_SHEET_TAG
|
||||||
@ -74,8 +79,6 @@ 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.LauncherHome.Companion.refreshCalls
|
|
||||||
import rasel.lunar.launcher.home.LauncherHome.Companion.refreshSms
|
|
||||||
import rasel.lunar.launcher.home.weather.WeatherExecutor
|
import rasel.lunar.launcher.home.weather.WeatherExecutor
|
||||||
import rasel.lunar.launcher.qaccess.QuickAccess
|
import rasel.lunar.launcher.qaccess.QuickAccess
|
||||||
import rasel.lunar.launcher.settings.SettingsActivity
|
import rasel.lunar.launcher.settings.SettingsActivity
|
||||||
@ -90,10 +93,12 @@ import rasel.lunar.launcher.todos.SmsLogsAdapter
|
|||||||
import rasel.lunar.launcher.todos.TwoColumnBrowseResultsRenderer
|
import rasel.lunar.launcher.todos.TwoColumnBrowseResultsRenderer
|
||||||
import rasel.lunar.launcher.utils.BLog
|
import rasel.lunar.launcher.utils.BLog
|
||||||
import rasel.lunar.launcher.utils.MissedCallGetter
|
import rasel.lunar.launcher.utils.MissedCallGetter
|
||||||
|
import rasel.lunar.launcher.utils.NewsFeedsGetter
|
||||||
import rasel.lunar.launcher.utils.RecentSmsGetter
|
import rasel.lunar.launcher.utils.RecentSmsGetter
|
||||||
import rasel.lunar.launcher.utils.RecentSmsLog
|
import rasel.lunar.launcher.utils.RecentSmsLog
|
||||||
import rasel.lunar.launcher.utils.RssList
|
import rasel.lunar.launcher.utils.RssList
|
||||||
import rasel.lunar.launcher.utils.SimpleFingerGestures
|
import rasel.lunar.launcher.utils.SimpleFingerGestures
|
||||||
|
import rasel.lunar.launcher.utils.beforeDay
|
||||||
import java.io.ByteArrayInputStream
|
import java.io.ByteArrayInputStream
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
@ -113,10 +118,8 @@ internal class LauncherHome : Fragment() {
|
|||||||
private lateinit var batteryReceiver: BatteryReceiver
|
private lateinit var batteryReceiver: BatteryReceiver
|
||||||
private var shouldResume = true
|
private var shouldResume = true
|
||||||
companion object {
|
companion object {
|
||||||
val SMS_WORK_TAG = "RecentSmsGetter"
|
|
||||||
val CALL_WORK_TAG = "MissedCallGetter"
|
|
||||||
var lastedFinishedPageUrl : String = ""
|
var lastedFinishedPageUrl : String = ""
|
||||||
private var mWorkManager: WorkManager? = null
|
|
||||||
|
|
||||||
var missedCalls = hashMapOf<String, MissedCall>()
|
var missedCalls = hashMapOf<String, MissedCall>()
|
||||||
var callList = arrayListOf<MissedCall>()
|
var callList = arrayListOf<MissedCall>()
|
||||||
@ -124,44 +127,44 @@ internal class LauncherHome : Fragment() {
|
|||||||
var listTags = arrayListOf<RssTagItem>()
|
var listTags = arrayListOf<RssTagItem>()
|
||||||
var listItem = arrayListOf<RssItem>()
|
var listItem = arrayListOf<RssItem>()
|
||||||
var rssSet = hashMapOf<String,RssDataItem>()
|
var rssSet = hashMapOf<String,RssDataItem>()
|
||||||
var rssUrls = arrayListOf<String>()
|
|
||||||
var feddsUrls = arrayListOf<String>()
|
|
||||||
var rssList = arrayListOf<RssDataItem>()
|
var rssList = arrayListOf<RssDataItem>()
|
||||||
|
|
||||||
fun refreshSms() {
|
|
||||||
Executors.newSingleThreadScheduledExecutor().schedule({
|
|
||||||
mWorkManager?.cancelAllWorkByTag(SMS_WORK_TAG)
|
|
||||||
mWorkManager?.enqueue(PeriodicWorkRequestBuilder<RecentSmsGetter>(30, TimeUnit.MINUTES).addTag(SMS_WORK_TAG).build())
|
|
||||||
}, 2, TimeUnit.SECONDS)
|
|
||||||
}
|
|
||||||
fun refreshCalls() {
|
|
||||||
Executors.newSingleThreadScheduledExecutor().schedule({
|
|
||||||
mWorkManager?.cancelAllWorkByTag(CALL_WORK_TAG)
|
|
||||||
mWorkManager?.enqueueUniquePeriodicWork(CALL_WORK_TAG,ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,PeriodicWorkRequestBuilder<MissedCallGetter>(30, TimeUnit.MINUTES).addTag("MissedCallGetter").build())
|
|
||||||
}, 2, TimeUnit.SECONDS)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private var nReceiver: NotificationReceiver? = null
|
private var nReceiver: NotificationReceiver? = null
|
||||||
|
|
||||||
class NotificationReceiver : BroadcastReceiver() {
|
class NotificationReceiver : BroadcastReceiver() {
|
||||||
override fun onReceive(context: Context?, intent: Intent) {
|
override fun onReceive(context: Context?, intent: Intent) {
|
||||||
// val temp = """
|
BLog.LOGE("NotificationReceiver >>>> ${intent.extras?.keySet()}")
|
||||||
// ${intent.getStringExtra("notification_event")}
|
|
||||||
//// ${txtView.getText()}
|
|
||||||
// """.trimIndent()
|
|
||||||
// txtView.setText(temp)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun workmanager() : WorkManager? {
|
|
||||||
if (mWorkManager == null) {
|
val UPDATE_DELAY = 500L
|
||||||
mWorkManager = WorkManager.getInstance(requireContext())
|
val commandHandler = Handler(Looper.getMainLooper())
|
||||||
}
|
|
||||||
return mWorkManager
|
val smsUpdate = Runnable {
|
||||||
}
|
BLog.LOGE("observeForever smsList.size >>> ${smsList.size}")
|
||||||
|
binding.recentSms.text = "최근 문자 [${smsList.size}]"
|
||||||
|
chooseAdpater()
|
||||||
|
}
|
||||||
|
|
||||||
|
val callUpdate = Runnable {
|
||||||
|
binding.missedCalls.text = "최근 통화 [${missedCalls.size}]"
|
||||||
|
BLog.LOGE("observeForever missedCalls.size >>> ${missedCalls.size}")
|
||||||
|
chooseAdpater()
|
||||||
|
}
|
||||||
|
|
||||||
|
val infoUpdate = Runnable {
|
||||||
|
binding.otherCheck.text = "최근 정보[${rssSet.size}]"
|
||||||
|
BLog.LOGE("observeForever rssSet.size >>> ${rssSet.size}")
|
||||||
|
chooseAdpater()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||||
mWorkManager = WorkManager.getInstance(requireContext())
|
|
||||||
binding = LauncherHomeBinding.inflate(inflater, container, false)
|
binding = LauncherHomeBinding.inflate(inflater, container, false)
|
||||||
fragManager = lActivity!!.supportFragmentManager
|
fragManager = lActivity!!.supportFragmentManager
|
||||||
settingsPrefs = requireContext().getSharedPreferences(PREFS_SETTINGS, 0)
|
settingsPrefs = requireContext().getSharedPreferences(PREFS_SETTINGS, 0)
|
||||||
@ -169,35 +172,45 @@ internal class LauncherHome : Fragment() {
|
|||||||
mMissedCallsAdapter = MissedCallsAdapter(callList, requireContext())
|
mMissedCallsAdapter = MissedCallsAdapter(callList, requireContext())
|
||||||
mSmsLogsAdapter = SmsLogsAdapter(smsList, requireContext())
|
mSmsLogsAdapter = SmsLogsAdapter(smsList, requireContext())
|
||||||
mRssAdapter = RssItemAdapter(rssList, requireContext())
|
mRssAdapter = RssItemAdapter(rssList, requireContext())
|
||||||
binding.favAppsGroup.visibility = View.GONE
|
binding.mainList.adapter = mMissedCallsAdapter
|
||||||
binding.mainList.layoutManager = LinearLayoutManagerWrapper(requireContext())
|
binding.smsList.adapter = mSmsLogsAdapter
|
||||||
|
binding.infoList.adapter = mRssAdapter
|
||||||
|
binding.missedCalls.isChecked = true
|
||||||
|
binding.smsList.visibility = View.GONE
|
||||||
|
binding.infoList.visibility = View.GONE
|
||||||
|
|
||||||
|
binding.favAppsGroup.visibility = View.GONE
|
||||||
|
binding.mainList.layoutManager = LinearLayoutManager(requireContext())
|
||||||
|
binding.smsList.layoutManager = LinearLayoutManager(requireContext())
|
||||||
|
binding.infoList.layoutManager = LinearLayoutManager(requireContext())
|
||||||
|
|
||||||
workmanager()?.getWorkInfosByTagLiveData(SMS_WORK_TAG)?.observeForever {
|
workmanager()?.getWorkInfosByTagLiveData(SMS_WORK_TAG)?.observeForever {
|
||||||
binding.recentSms.text = "최근 문자 [${smsList.size}]"
|
commandHandler.removeCallbacks(smsUpdate)
|
||||||
if (binding.recentSms.isChecked) chooseAdpater()
|
commandHandler.postDelayed(smsUpdate,UPDATE_DELAY)
|
||||||
else if (binding.missedCalls.isChecked && missedCalls.size == 0) {
|
|
||||||
binding.recentSms.isChecked = true
|
|
||||||
chooseAdpater()
|
|
||||||
}
|
|
||||||
BLog.LOGE("smsList.size >>> ${smsList.size}")
|
|
||||||
it.clear()
|
it.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
workmanager()?.getWorkInfosByTagLiveData(CALL_WORK_TAG)?.observeForever {
|
workmanager()?.getWorkInfosByTagLiveData(CALL_WORK_TAG)?.observeForever {
|
||||||
binding.missedCalls.text = "최근 통화 [${missedCalls.size}]"
|
commandHandler.removeCallbacks(callUpdate)
|
||||||
if (binding.recentSms.isChecked && missedCalls.size > 0) binding.missedCalls.isChecked = true
|
commandHandler.postDelayed(callUpdate,UPDATE_DELAY)
|
||||||
if (binding.missedCalls.isChecked) chooseAdpater()
|
|
||||||
it.clear()
|
it.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
workmanager()?.getWorkInfosByTagLiveData(FEDDS_WORK_TAG)?.observeForever {
|
||||||
|
commandHandler.removeCallbacks(infoUpdate)
|
||||||
|
commandHandler.postDelayed(infoUpdate,UPDATE_DELAY)
|
||||||
|
it.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
nReceiver = NotificationReceiver()
|
nReceiver = NotificationReceiver()
|
||||||
val filter = IntentFilter()
|
val filter = IntentFilter()
|
||||||
// filter.addAction("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
|
// filter.addAction("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
|
||||||
registerReceiver(requireContext(),nReceiver, filter,RECEIVER_EXPORTED)
|
registerReceiver(requireContext(),nReceiver, filter,RECEIVER_EXPORTED)
|
||||||
|
|
||||||
BLog.LOGE("onCreateView()")
|
BLog.LOGE("onCreateView()")
|
||||||
refreshSms()
|
|
||||||
refreshCalls()
|
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,178 +251,42 @@ internal class LauncherHome : Fragment() {
|
|||||||
chooseAdpater()
|
chooseAdpater()
|
||||||
}
|
}
|
||||||
binding.otherCheck.setOnClickListener {
|
binding.otherCheck.setOnClickListener {
|
||||||
if(rssSet.size < 10) {
|
binding.otherCheck.isChecked = true
|
||||||
rssSet.clear()
|
chooseAdpater()
|
||||||
feddsUrls.clear()
|
|
||||||
feddsUrls.addAll(RssList.newsFeeds)
|
|
||||||
rssUrls.clear()
|
|
||||||
rssUrls.addAll(RssList.youtubeUrls)
|
|
||||||
|
|
||||||
|
|
||||||
binding.otherCheck.isChecked = true
|
|
||||||
rssList.clear()
|
|
||||||
rssList.add(object : RssDataItem {
|
|
||||||
override fun title(): String {
|
|
||||||
return "waiting for data"
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun thumbnailUrl(): String {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun originPage(): String {
|
|
||||||
return "waiting for data"
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun description(): String {
|
|
||||||
return "waiting for data"
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun pubDate(): Long {
|
|
||||||
return 0L
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun category(): RssDataType {
|
|
||||||
return RssDataType.NO_DATA
|
|
||||||
}
|
|
||||||
})
|
|
||||||
doWebPare(RssList.youtubeUrls.removeFirst())
|
|
||||||
getFeeds(feddsUrls.removeFirst())
|
|
||||||
}
|
|
||||||
binding.mainList.adapter = mRssAdapter
|
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.otherCheck.setOnLongClickListener {
|
binding.otherCheck.setOnLongClickListener {
|
||||||
listItem.clear()
|
listItem.clear()
|
||||||
doWebPare(TEST_PAG)
|
lActivity?.doWebPare(TEST_PAG, null)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
binding.summaryChoose.setOnCheckedChangeListener { group, checkedId ->
|
// binding.summaryChoose.setOnCheckedChangeListener { group, checkedId ->
|
||||||
chooseAdpater()
|
// chooseAdpater()
|
||||||
}
|
// }
|
||||||
// val i = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_SERVICE_EXAMPLE")
|
//// val i = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_SERVICE_EXAMPLE")
|
||||||
// i.putExtra("command", "list")
|
//// i.putExtra("command", "list")
|
||||||
// lActivity?.sendBroadcast(i)
|
//// lActivity?.sendBroadcast(i)
|
||||||
// BLog.LOGE("intent >>> ${i.action}")
|
//// BLog.LOGE("intent >>> ${i.action}")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getFeeds(url : String) {
|
|
||||||
Executors.newSingleThreadScheduledExecutor().schedule( {
|
|
||||||
RssFeedsParser.getFeeds(url).apply {
|
|
||||||
}.filter { it.pubDate() >= (System.currentTimeMillis() - 1000L * 60L * 60L * 24 * 3)
|
|
||||||
}.forEach {
|
|
||||||
BLog.LOGE("getFeeds it >> ${Gson().toJson(it)}")
|
|
||||||
rssSet.put(it.originPage(), it)
|
|
||||||
}.apply {
|
|
||||||
if (feddsUrls.size > 0) {
|
|
||||||
getFeeds(feddsUrls.removeFirst())
|
|
||||||
}
|
|
||||||
if(rssUrls.size < 1 && feddsUrls.size < 1) {
|
|
||||||
rssList.clear()
|
|
||||||
rssSet.forEach { t, u ->
|
|
||||||
rssList.add(u)
|
|
||||||
}
|
|
||||||
rssList.sortByDescending { it.pubDate() }
|
|
||||||
Handler(Looper.getMainLooper()).post {
|
|
||||||
mRssAdapter.updateData(rssList)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},1,TimeUnit.SECONDS)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun doWebPare(url : String) {
|
|
||||||
if (url.contains("youtube")) {
|
|
||||||
Executors.newSingleThreadScheduledExecutor().schedule( {
|
|
||||||
Jsoup.connect(url).get()?.apply {
|
|
||||||
ytChannel(this)
|
|
||||||
}
|
|
||||||
},1,TimeUnit.SECONDS)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
BLog.LOGE("binding.otherCheck before ThreadRun")
|
|
||||||
binding.searcher01.webViewClient = object : WebViewClient() {
|
|
||||||
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
|
|
||||||
BLog.LOGE("binding.otherCheck searcher01 in onPageStarted ${url}")
|
|
||||||
super.onPageStarted(view, url, favicon)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onReceivedSslError(
|
|
||||||
view: WebView?,
|
|
||||||
handler: SslErrorHandler?,
|
|
||||||
error: SslError?
|
|
||||||
) {
|
|
||||||
handler?.proceed()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
override fun onPageFinished(view: WebView?, url: String?) {
|
|
||||||
super.onPageFinished(view, url)
|
|
||||||
lastedFinishedPageUrl = url ?: ""
|
|
||||||
BLog.LOGE("binding.otherCheck searcher01 in onPageFinished ${url}")
|
|
||||||
|
|
||||||
if (url?.contains("youtube", false) == true) {
|
|
||||||
view?.evaluateJavascript(
|
|
||||||
"function getAll() {\n" +
|
|
||||||
" MyJavaScriptInterface.sendValueFromHtml(document.getElementsByTagName('html')[0].innerHTML)" +
|
|
||||||
" };getAll()"
|
|
||||||
) { result ->
|
|
||||||
(result as? String)?.let {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
view?.evaluateJavascript(
|
|
||||||
"function getAll() {\n" +
|
|
||||||
" MyJavaScriptInterface.sendValueFromHtml(document.getElementsByTagName('html')[0].innerHTML)" +
|
|
||||||
" };getAll()"
|
|
||||||
) { result ->
|
|
||||||
(result as? String)?.let {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WebView.setWebContentsDebuggingEnabled(false)
|
|
||||||
binding.searcher01.apply {
|
|
||||||
this.addJavascriptInterface(MyJavaScriptInterface(this),"MyJavaScriptInterface")
|
|
||||||
setBackgroundColor(Color.WHITE) // 백그라운드 색상 설정
|
|
||||||
setLayerType(View.LAYER_TYPE_SOFTWARE, null) // 랜더링 이슈 해결
|
|
||||||
try {
|
|
||||||
settings.apply {
|
|
||||||
javaScriptEnabled = true // 자바스크립트 사용 가능하도록 설정
|
|
||||||
loadWithOverviewMode = true // 전체 웹페이지를 화면에 맞게 로드
|
|
||||||
useWideViewPort = true // 화면에 맞게 페이지 확대/축소
|
|
||||||
domStorageEnabled = true // DOM 저장소 사용 가능하도록 설정
|
|
||||||
setSupportMultipleWindows(true)
|
|
||||||
javaScriptCanOpenWindowsAutomatically = true // 팝업창 차단 해제
|
|
||||||
cacheMode = WebSettings.LOAD_CACHE_ELSE_NETWORK
|
|
||||||
textZoom = 100 // system 에 의한 글꼴 변형 방지
|
|
||||||
defaultTextEncodingName = "UTF-8" // 인코딩 설정
|
|
||||||
allowContentAccess = true // 웹뷰를 통해 content url에 접근할지 여부
|
|
||||||
layoutAlgorithm = WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING // 웹페이지의 레이아웃을 화면에 맞게 자동으로 조정
|
|
||||||
}
|
|
||||||
} catch (ignore: NoSuchMethodError) {}
|
|
||||||
loadUrl(url) // 웹페이지 연결
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun chooseAdpater () {
|
fun chooseAdpater () {
|
||||||
|
binding.mainList.visibility = View.GONE
|
||||||
|
binding.smsList.visibility = View.GONE
|
||||||
|
binding.infoList.visibility = View.GONE
|
||||||
if (binding.missedCalls.isChecked) {
|
if (binding.missedCalls.isChecked) {
|
||||||
if (missedCalls.size > 0 && isAdded && isResumed && isVisible) {
|
if (missedCalls.size > 0 && isAdded && isResumed && isVisible) {
|
||||||
try {
|
try {
|
||||||
callList.clear()
|
callList.clear()
|
||||||
if(binding.mainList.adapter is MissedCallsAdapter){
|
|
||||||
}else {
|
|
||||||
binding.mainList.adapter = mMissedCallsAdapter
|
|
||||||
}
|
|
||||||
missedCalls.forEach { t, u ->
|
missedCalls.forEach { t, u ->
|
||||||
callList.add(u)
|
callList.add(u)
|
||||||
}.apply {
|
}.apply {
|
||||||
callList.sortByDescending { it.date }
|
callList.sortByDescending { it.date }
|
||||||
Handler(Looper.getMainLooper()).post {mMissedCallsAdapter.updateData(callList)}
|
Handler(Looper.getMainLooper()).post {
|
||||||
|
mMissedCallsAdapter.updateData(callList)
|
||||||
|
binding.mainList.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (e : Exception) {
|
} catch (e : Exception) {
|
||||||
}
|
}
|
||||||
@ -417,17 +294,32 @@ internal class LauncherHome : Fragment() {
|
|||||||
} else if(binding.recentSms.isChecked){
|
} else if(binding.recentSms.isChecked){
|
||||||
if (smsList.size > 0 && isAdded && isResumed && isVisible) {
|
if (smsList.size > 0 && isAdded && isResumed && isVisible) {
|
||||||
try {
|
try {
|
||||||
if(binding.mainList.adapter is SmsLogsAdapter){
|
|
||||||
|
|
||||||
}else {
|
|
||||||
binding.mainList.adapter = mSmsLogsAdapter
|
|
||||||
}
|
|
||||||
smsList.sortByDescending { it.rcvDate }
|
smsList.sortByDescending { it.rcvDate }
|
||||||
Handler(Looper.getMainLooper()).post {mSmsLogsAdapter.updateData(smsList)}
|
binding.smsList.visibility = View.VISIBLE
|
||||||
|
Handler(Looper.getMainLooper()).post {
|
||||||
|
mSmsLogsAdapter.updateData(smsList)
|
||||||
|
binding.smsList.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
} catch (e : Exception) {
|
} catch (e : Exception) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if(binding.otherCheck.isChecked) {
|
||||||
|
try {
|
||||||
|
rssList.clear()
|
||||||
|
rssSet.forEach { k,v ->
|
||||||
|
if(v.pubDate() > beforeDay(Date(),3)) {
|
||||||
|
rssList.add(v)
|
||||||
|
} else {
|
||||||
|
rssSet.remove(k,v)
|
||||||
|
}
|
||||||
|
}.apply {
|
||||||
|
Handler(Looper.getMainLooper()).post {
|
||||||
|
mRssAdapter.updateData(rssList)
|
||||||
|
binding.infoList.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch (e : Exception){}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
@ -448,7 +340,6 @@ internal class LauncherHome : Fragment() {
|
|||||||
}
|
}
|
||||||
/* show weather */
|
/* show weather */
|
||||||
WeatherExecutor(settingsPrefs).generateWeatherString(binding.weather)
|
WeatherExecutor(settingsPrefs).generateWeatherString(binding.weather)
|
||||||
chooseAdpater()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -599,90 +490,7 @@ internal class LauncherHome : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
var maxDate : Long = Long.MIN_VALUE
|
|
||||||
var minDate : Long = Long.MAX_VALUE
|
|
||||||
val simpldateFormat = SimpleDateFormat("d MMM, yy",Locale.US)
|
|
||||||
fun jGuruMain(doc:Document) {
|
|
||||||
BLog.LOGE("do default parsing")
|
|
||||||
BLog.LOGE("SimpleDateFormat D MM yy => ${SimpleDateFormat("d MMM yy",Locale.US).format(Date())}")
|
|
||||||
val prevUrl = doc.getElementsByClass("prev").get(0).getElementsByAttribute("href").get(0).attr("href")
|
|
||||||
BLog.LOGE("doc.getElementsByClass(prev).get(0).html() ${prevUrl}")
|
|
||||||
doc.getElementsByClass("column").forEach {
|
|
||||||
var title = it.getElementsByAttribute("title").get(0).text()
|
|
||||||
var model = title.replace("[","").split("]")[0]
|
|
||||||
var pageLink = it.getElementsByClass("imgg").get(0).getElementsByAttribute("href").get(0).attr("href")
|
|
||||||
var imgg = it.getElementsByClass("imgg").get(0).getElementsByAttribute("src").get(0).attr("src")
|
|
||||||
var tags = it.getElementsByClass("tags").get(0).text()
|
|
||||||
var date = it.getElementsByClass("date").get(0).text()
|
|
||||||
var regDate = simpldateFormat.parse(date).time
|
|
||||||
|
|
||||||
minDate = Math.min(minDate,regDate)
|
|
||||||
|
|
||||||
maxDate = Math.max(maxDate,regDate)
|
|
||||||
|
|
||||||
listItem.add(RssItem(model = model, title = title, pageLink = pageLink, image = imgg, tags = tags, date = simpldateFormat.parse(date).time))
|
|
||||||
}.apply {
|
|
||||||
|
|
||||||
BLog.LOGE("listItem.size >>> ${listItem.size}")
|
|
||||||
if (prevUrl!=null && prevUrl.length > TEST_PAG.length && prevUrl.contains("/page/") && (maxDate - minDate) < (1000L * 60L * 60L * 24L * 3L)) {
|
|
||||||
BLog.LOGE("listItem.size >>> ${listItem.size} do next ")
|
|
||||||
BLog.LOGE("saving data :: ${listItem.size}items ${simpldateFormat.format(Date(minDate))} ~ ${simpldateFormat.format(Date(maxDate))}")
|
|
||||||
binding.searcher01.postDelayed({binding.searcher01.loadUrl(prevUrl)}, 5000L)
|
|
||||||
} else {
|
|
||||||
listItem.sortByDescending { it.date }
|
|
||||||
BLog.LOGE("Stored data :: ${listItem.size}items ${simpldateFormat.format(Date(minDate))} ~ ${simpldateFormat.format(Date(maxDate))}")
|
|
||||||
Toast.makeText(requireContext(),
|
|
||||||
"Stored data :: ${listItem.size} items :: [${simpldateFormat.format(Date(minDate))} ~ ${simpldateFormat.format(Date(maxDate))}]", Toast.LENGTH_LONG).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun jGuruTag(doc: Document) {
|
|
||||||
listTags.clear()
|
|
||||||
doc.getElementsByTag("ul").forEach {
|
|
||||||
it.children().forEach {
|
|
||||||
if (it.tag().name.contains("li")) {
|
|
||||||
listTags.add(
|
|
||||||
RssTagItem(
|
|
||||||
tagTitle = it.getElementsByTag("a").get(0).text(),
|
|
||||||
link = it.getElementsByTag("a").get(0).attr("href")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.apply {
|
|
||||||
listTags.sortByDescending { it.count }
|
|
||||||
Toast.makeText(requireContext(),
|
|
||||||
"Stored data :: ${listTags.size}tags", Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inner class MyJavaScriptInterface(val webView: WebView) {
|
|
||||||
|
|
||||||
|
|
||||||
@JavascriptInterface
|
|
||||||
fun sendValueFromHtml(result: String) {
|
|
||||||
|
|
||||||
if (lastedFinishedPageUrl.contains(TEST_PAG)) {
|
|
||||||
var htmlString = result.replace("\\u003","<")
|
|
||||||
val doc: Document = Jsoup.parse(htmlString)
|
|
||||||
if (lastedFinishedPageUrl?.contains("page") == true || lastedFinishedPageUrl?.equals(
|
|
||||||
TEST_PAG
|
|
||||||
) == true
|
|
||||||
) {
|
|
||||||
jGuruMain(doc)
|
|
||||||
} else if (lastedFinishedPageUrl?.contains("/tags/") == true) {
|
|
||||||
jGuruTag(doc)
|
|
||||||
}
|
|
||||||
} else if (lastedFinishedPageUrl?.contains("youtube") == true) {
|
|
||||||
val doc: Document = Jsoup.parse(result)
|
|
||||||
ytChannel(doc)
|
|
||||||
}
|
|
||||||
BLog.LOGE("binding.otherCheck after ThreadRun")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun jsonObjLog(pkey : String ,key : String, jsonObject: JSONObject) {
|
fun jsonObjLog(pkey : String ,key : String, jsonObject: JSONObject) {
|
||||||
if (jsonObject?.has(key) == true && jsonObject?.get(key) is String) {
|
if (jsonObject?.has(key) == true && jsonObject?.get(key) is String) {
|
||||||
@ -717,91 +525,7 @@ internal class LauncherHome : Fragment() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun ytChannel(doc: Document) {
|
|
||||||
BLog.LOGE("ytChannel >>>>> doc${doc.title()}")
|
|
||||||
try {
|
|
||||||
doc.getElementsByTag("script").forEach {
|
|
||||||
// BLog.LOGE("ytChannel >>>>> doc ${doc.title()} find script ${it}")
|
|
||||||
if(it.html().contains("var ytInitialData", false)) {/**/
|
|
||||||
BLog.LOGE("ytChannel >>>>> doc${doc.title()} find ytInitialData ${it} ")
|
|
||||||
var ytInitialData = it.html().split("var ytInitialData = ")[1].split("</script>")[0].toString()
|
|
||||||
// ytInitialData = ytInitialData.replace("\\x22", "\"")
|
|
||||||
// .replace("\\x7b", "{")
|
|
||||||
// .replace("\\x7d", "}")
|
|
||||||
// .replace("\\x5b", "[")
|
|
||||||
// .replace("\\x5d", "]")
|
|
||||||
BLog.LOGE("ytChannel >>>>> doc${doc.title()} find ytInitialData ${ytInitialData} ")
|
|
||||||
var tempJSONObject : JSONObject? = null
|
|
||||||
JSONObject(ytInitialData).apply{
|
|
||||||
tempJSONObject = this
|
|
||||||
val root = Gson().fromJson(tempJSONObject.toString(), Root::class.java)
|
|
||||||
BLog.LOGE("ytChannel >>>>> doc root ${Gson().toJson(root)} apply ")
|
|
||||||
(if (root?.contents?.singleColumnBrowseResultsRenderer?.tabs?.size ?: 0 > 0) {
|
|
||||||
|
|
||||||
BLog.LOGE("ytChannel >>>>> doc singleColumnBrowseResultsRenderer apply ")
|
|
||||||
root?.contents?.singleColumnBrowseResultsRenderer?.tabs?.forEach {
|
|
||||||
it.tabRenderer?.content?.sectionListRenderer?.contents?.forEach {
|
|
||||||
BLog.LOGE("ytChannel >>>>> doc sectionListRenderer?.contents ${Gson().toJson(it)} apply ")
|
|
||||||
it.shelfRenderer?.content?.verticalListRenderer?.items?.forEach {
|
|
||||||
BLog.LOGE("ytChannel >>>>> doc verticalListRenderer?.items ${Gson().toJson(it)} apply ")
|
|
||||||
(it.compactVideoRenderer as? RssDataItem)?.let {
|
|
||||||
if(it.pubDate() >= (System.currentTimeMillis() - 1000L * 60L * 60L * 24 * 3)) {
|
|
||||||
rssSet.put(it.originPage(), it)
|
|
||||||
BLog.LOGE("ytChannel >>>>> doc RssDataItem ${Gson().toJson(it)} apply ")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
BLog.LOGE("ytChannel >>>>> doc twoColumnBrowseResultsRenderer apply ")
|
|
||||||
root?.contents?.twoColumnBrowseResultsRenderer?.tabs?.forEach {
|
|
||||||
it.tabRenderer?.content?.sectionListRenderer?.contents?.forEach {
|
|
||||||
BLog.LOGE("ytChannel >>>>> doc sectionListRenderer?.contents ${Gson().toJson(it)} apply ")
|
|
||||||
it.itemSectionRenderer?.contents?.forEach {
|
|
||||||
BLog.LOGE("ytChannel >>>>> doc itemSectionRenderer?.items ${Gson().toJson(it)} apply ")
|
|
||||||
it.shelfRenderer?.content?.horizontalListRenderer?.items?.forEach {
|
|
||||||
(it.gridVideoRenderer as? RssDataItem)?.let {
|
|
||||||
if(it.pubDate() >= (System.currentTimeMillis() - 1000L * 60L * 60L * 24 * 3)) {
|
|
||||||
rssSet.put(it.originPage(), it)
|
|
||||||
BLog.LOGE("ytChannel >>>>> doc RssDataItem ${Gson().toJson(it)} apply ")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).apply {
|
|
||||||
BLog.LOGE("ytChannel >>>>> doc${doc.title()} apply ")
|
|
||||||
// rssList.clear()
|
|
||||||
// rssSet.forEach { k,v ->
|
|
||||||
// rssList.add(element = v)
|
|
||||||
// }.apply {
|
|
||||||
|
|
||||||
if(rssUrls.size > 0) {
|
|
||||||
try {
|
|
||||||
val dddd = rssUrls.removeFirst()
|
|
||||||
doWebPare(dddd)
|
|
||||||
} catch (e : Exception) { }
|
|
||||||
}
|
|
||||||
rssList.clear()
|
|
||||||
rssSet.forEach { k,v ->
|
|
||||||
rssList.add(element = v)
|
|
||||||
}
|
|
||||||
if(rssUrls.size < 1 && feddsUrls.size < 1) {
|
|
||||||
rssList.sortByDescending { it.pubDate() }
|
|
||||||
Handler(Looper.getMainLooper()).post {
|
|
||||||
mRssAdapter.updateData(rssList)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch(e: Exception) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -907,21 +631,6 @@ class MissedCall {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class EndCallReceiver : BroadcastReceiver() {
|
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
|
||||||
BLog.LOGE("EndCallReceiver >>> ${intent}")
|
|
||||||
val phoneState = intent.getStringExtra(TelephonyManager.EXTRA_STATE) ?: return
|
|
||||||
if (phoneState == TelephonyManager.EXTRA_STATE_IDLE) {
|
|
||||||
refreshCalls()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
class SMSReceiver : BroadcastReceiver() {
|
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
|
||||||
BLog.LOGE("SMSReceiver >>> ${intent}")
|
|
||||||
refreshSms()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class RssTagItem {
|
class RssTagItem {
|
||||||
|
|||||||
@ -25,6 +25,7 @@ import android.content.Context
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.text.Html
|
import android.text.Html
|
||||||
|
import android.view.Gravity
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@ -61,24 +62,47 @@ internal class RssItemAdapter (
|
|||||||
}
|
}
|
||||||
|
|
||||||
val dateFormat = SimpleDateFormat("hh:mm / yy - MM - dd")
|
val dateFormat = SimpleDateFormat("hh:mm / yy - MM - dd")
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
override fun onBindViewHolder(holder: RssTag, position: Int) {
|
override fun onBindViewHolder(holder: RssTag, position: Int) {
|
||||||
val todo = smsList[position]
|
val todo = smsList[position]
|
||||||
BLog.LOGE("rssitem >>>> ${Gson().toJson(todo)}")
|
|
||||||
holder.view.title.text = "${todo.title()}"
|
holder.view.title.text = "${todo.title()}"
|
||||||
holder.view.desc.text = Html.fromHtml("${todo.description()}")
|
|
||||||
holder.view.date.text = "${dateFormat.format(Date(todo.pubDate()))}"
|
holder.view.date.text = "${dateFormat.format(Date(todo.pubDate()))}"
|
||||||
if(todo.thumbnailUrl()?.length ?: 0 > 6) {
|
holder.view.desc.visibility = View.GONE
|
||||||
Picasso.get().load(todo.thumbnailUrl().toUri()).into(holder.view.circlePreview)
|
holder.view.circlePreview.visibility = View.GONE
|
||||||
holder.view.circlePreview.visibility = View.VISIBLE
|
when(todo.category()) {
|
||||||
} else {
|
RssDataType.YOUTUBE -> {
|
||||||
holder.view.circlePreview.visibility = View.GONE
|
if(todo.thumbnailUrl()?.length ?: 0 > 6) {
|
||||||
|
Picasso.get().load(todo.thumbnailUrl().toUri()).into(holder.view.circlePreview)
|
||||||
|
holder.view.circlePreview.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
holder.view.title.gravity = Gravity.CENTER_VERTICAL.plus(Gravity.RIGHT)
|
||||||
|
holder.view.desc.gravity = Gravity.CENTER_VERTICAL.plus(Gravity.RIGHT)
|
||||||
|
holder.view.date.gravity = Gravity.CENTER_VERTICAL.plus(Gravity.RIGHT)
|
||||||
|
holder.view.desc.visibility = View.VISIBLE
|
||||||
|
holder.view.desc.text = if(todo.description().contains("게시자")) todo.description().split("게시자")[0] else todo.description()
|
||||||
|
holder.view.root.setOnClickListener { openYouTube(todo.originPage()) }
|
||||||
|
}
|
||||||
|
RssDataType.NewsFeed -> {
|
||||||
|
holder.view.title.gravity = Gravity.CENTER_VERTICAL.plus(Gravity.LEFT)
|
||||||
|
holder.view.desc.gravity = Gravity.CENTER_VERTICAL.plus(Gravity.LEFT)
|
||||||
|
holder.view.date.gravity = Gravity.CENTER_VERTICAL.plus(Gravity.RIGHT)
|
||||||
|
holder.view.root.setOnClickListener { openNews(todo.originPage()) }
|
||||||
|
}
|
||||||
|
RssDataType.NO_DATA -> {}
|
||||||
}
|
}
|
||||||
|
|
||||||
holder.view.root.setOnLongClickListener {
|
holder.view.root.setOnLongClickListener {
|
||||||
val clipBoard =
|
when(todo.category()) {
|
||||||
lActivity!!.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
RssDataType.YOUTUBE -> {}
|
||||||
clipBoard.setPrimaryClip(ClipData.newPlainText("", todo.thumbnailUrl()))
|
RssDataType.NewsFeed -> {
|
||||||
|
openNews(todo.originPage())
|
||||||
|
}
|
||||||
|
RssDataType.NO_DATA -> {}
|
||||||
|
}
|
||||||
|
// val clipBoard =
|
||||||
|
// lActivity!!.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||||
|
// clipBoard.setPrimaryClip(ClipData.newPlainText("", todo.thumbnailUrl()))
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +111,20 @@ internal class RssItemAdapter (
|
|||||||
fun updateData(newList: List<RssDataItem>) {
|
fun updateData(newList: List<RssDataItem>) {
|
||||||
DiffUtil.calculateDiff(RssItemDiffUtil(smsList, newList)).dispatchUpdatesTo(this)
|
DiffUtil.calculateDiff(RssItemDiffUtil(smsList, newList)).dispatchUpdatesTo(this)
|
||||||
}
|
}
|
||||||
|
fun openNews(schemeString : String) {
|
||||||
|
val gmmIntentUri = Uri.parse(schemeString)
|
||||||
|
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
|
||||||
|
mapIntent.setPackage("com.android.chrome")
|
||||||
|
lActivity?.startActivity(mapIntent)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun openYouTube(schemeString : String) {
|
||||||
|
val gmmIntentUri = Uri.parse(schemeString)
|
||||||
|
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
|
||||||
|
mapIntent.setPackage("com.google.android.youtube")
|
||||||
|
lActivity?.startActivity(mapIntent)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RssTag(var view: ListItemWithBinding) : RecyclerView.ViewHolder(view.root)
|
class RssTag(var view: ListItemWithBinding) : RecyclerView.ViewHolder(view.root)
|
||||||
|
|||||||
@ -503,13 +503,13 @@ class GridChannelRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class GridVideoRenderer : VideoRenderer() {
|
class GridVideoRenderer : VideoRenderer() {
|
||||||
// var videoId: String? = null
|
// var videoId: String? = null
|
||||||
// var thumbnail: Thumbnail? = null
|
// var thumbnail: Thumbnail? = null
|
||||||
// var title: Title? = null
|
// var title: Title? = null
|
||||||
// var publishedTimeText: PublishedTimeText? = null
|
// var publishedTimeText: PublishedTimeText? = null
|
||||||
// var navigationEndpoint: NavigationEndpoint? = null
|
// var navigationEndpoint: NavigationEndpoint? = null
|
||||||
var badges: ArrayList<Badge>? = null
|
var badges: ArrayList<Badge>? = null
|
||||||
// var ownerBadges: ArrayList<OwnerBadge>? = null
|
// var ownerBadges: ArrayList<OwnerBadge>? = null
|
||||||
// var trackingParams: String? = null
|
// var trackingParams: String? = null
|
||||||
// var menu: Menu? = null
|
// var menu: Menu? = null
|
||||||
// var thumbnailOverlays: ArrayList<ThumbnailOverlay>? = null
|
// var thumbnailOverlays: ArrayList<ThumbnailOverlay>? = null
|
||||||
@ -1117,11 +1117,11 @@ class RichThumbnail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Root {
|
class Root {
|
||||||
// var responseContext: ResponseContext? = null
|
// var responseContext: ResponseContext? = null
|
||||||
var contents: Content14? = null
|
var contents: Content14? = null
|
||||||
var header: Header? = null
|
var header: Header? = null
|
||||||
var metadata: Metadata? = null
|
var metadata: Metadata? = null
|
||||||
// var trackingParams: String? = null
|
// var trackingParams: String? = null
|
||||||
// var topbar: Topbar? = null
|
// var topbar: Topbar? = null
|
||||||
var microformat: Microformat? = null
|
var microformat: Microformat? = null
|
||||||
// var onResponseReceivedActions: ArrayList<OnResponseReceivedAction>? = null
|
// var onResponseReceivedActions: ArrayList<OnResponseReceivedAction>? = null
|
||||||
@ -1584,7 +1584,7 @@ open class VideoRenderer : RssDataItem {
|
|||||||
var thumbnailOverlays: ArrayList<ThumbnailOverlay>? = null
|
var thumbnailOverlays: ArrayList<ThumbnailOverlay>? = null
|
||||||
var avatar: Avatar? = null
|
var avatar: Avatar? = null
|
||||||
override fun title(): String {
|
override fun title(): String {
|
||||||
return shortBylineText?.runs?.get(0)?.text ?: title?.runs?.get(0)?.text ?: title?.accessibility?.label ?: ""
|
return shortBylineText?.runs?.get(0)?.text ?: title?.runs?.get(0)?.text ?: title?.accessibility?.label ?: title?.accessibility?.accessibilityData?.label ?: ""
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun thumbnailUrl(): String {
|
override fun thumbnailUrl(): String {
|
||||||
@ -1602,43 +1602,40 @@ open class VideoRenderer : RssDataItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun description(): String {
|
override fun description(): String {
|
||||||
return ""
|
return title?.accessibility?.accessibilityData?.label ?: ""
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun pubDate(): Long {
|
override fun pubDate(): Long {
|
||||||
var date = Date()
|
var date = Date()
|
||||||
var dateTime = date.time
|
var dateTime = date.time
|
||||||
var before = 0
|
var before = 0
|
||||||
try {
|
try {
|
||||||
var targetDate = publishedTimeText?.simpleText ?: publishedTimeText?.runs?.first()?.text ?: ""
|
var targetDate = publishedTimeText?.simpleText ?: publishedTimeText?.runs?.first()?.text ?: ""
|
||||||
if (targetDate?.length ?: 0 > 1) {
|
if (targetDate?.length ?: 0 > 1) {
|
||||||
BLog.LOGE("targetDate >>>> ${targetDate}")
|
var dateDesc = targetDate
|
||||||
var dateDesc = targetDate
|
dateDesc = dateDesc!!.split(" 전")[0].trim()
|
||||||
// dateDesc = dateDesc!!.replace("스트리밍 시간:","").trim()
|
val dayString = dateDesc.replace("[^0-9]".toRegex(), "")
|
||||||
dateDesc = dateDesc!!.split(" 전")[0].trim()
|
before = dayString.toInt()
|
||||||
val dayString = dateDesc.replace("[^0-9]".toRegex(), "")
|
if (dateDesc.contains("년")) {
|
||||||
before = dayString.toInt()
|
before = 365 * before
|
||||||
BLog.LOGE("targetDate >>>> ${before}")
|
dateTime = beforeDay(date, before)
|
||||||
if (dateDesc.contains("년")) {
|
} else if (dateDesc.contains("월")) {
|
||||||
before = 365 * before
|
before = 30 * before
|
||||||
dateTime = beforeDay(date, before)
|
dateTime = beforeDay(date, before)
|
||||||
} else if (dateDesc.contains("월")) {
|
} else if (dateDesc.contains("주")) {
|
||||||
before = 30 * before
|
before = 7 * before
|
||||||
dateTime = beforeDay(date, before)
|
dateTime = beforeDay(date, before)
|
||||||
} else if (dateDesc.contains("주")) {
|
} else if (dateDesc.contains("일")) {
|
||||||
before = 7 * before
|
dateTime = beforeDay(date, before)
|
||||||
dateTime = beforeDay(date, before)
|
} else if (dateDesc.contains("시간")) {
|
||||||
} else if (dateDesc.contains("일")) {
|
dateTime = dateTime.minus(before.times(1000L * 60L * 60L))
|
||||||
dateTime = beforeDay(date, before)
|
} else if (dateDesc.contains("분")) {
|
||||||
} else if (dateDesc.contains("시간")) {
|
dateTime = dateTime.minus(before.times(1000L * 60L))
|
||||||
dateTime = dateTime.minus(before.times(1000L * 60L * 60L))
|
|
||||||
} else if (dateDesc.contains("분")) {
|
|
||||||
dateTime = dateTime.minus(before.times(1000L * 60L))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}catch (e : Exception) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}catch (e : Exception) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return dateTime
|
return dateTime
|
||||||
@ -1739,13 +1736,13 @@ class YtConfigData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class YoutubeData {
|
class YoutubeData {
|
||||||
// var responseContext: ResponseContext? = null
|
// var responseContext: ResponseContext? = null
|
||||||
var contents: JSONObject? = null
|
var contents: JSONObject? = null
|
||||||
var header: JSONObject? = null
|
var header: JSONObject? = null
|
||||||
var metadata: JSONObject? = null
|
var metadata: JSONObject? = null
|
||||||
// var trackingParams: String? = null
|
// var trackingParams: String? = null
|
||||||
// var topbar: Topbar? = null
|
// var topbar: Topbar? = null
|
||||||
var microformat: JSONObject? = null
|
var microformat: JSONObject? = null
|
||||||
// var onResponseReceivedActions: ArrayList<OnResponseReceivedAction>? = null
|
// var onResponseReceivedActions: ArrayList<OnResponseReceivedAction>? = null
|
||||||
// var frameworkUpdates: FrameworkUpdates? = null
|
// var frameworkUpdates: FrameworkUpdates? = null
|
||||||
|
|
||||||
|
|||||||
@ -7,14 +7,24 @@ import android.database.Cursor
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.provider.CallLog
|
import android.provider.CallLog
|
||||||
import android.provider.ContactsContract.PhoneLookup
|
import android.provider.ContactsContract.PhoneLookup
|
||||||
|
import android.provider.Settings.Global
|
||||||
import android.provider.Telephony
|
import android.provider.Telephony
|
||||||
import androidx.work.Worker
|
import androidx.work.Worker
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
import kotlinx.coroutines.async
|
||||||
|
import org.json.JSONObject
|
||||||
|
import org.jsoup.Jsoup
|
||||||
|
import org.jsoup.nodes.Document
|
||||||
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
||||||
import rasel.lunar.launcher.home.LauncherHome.Companion.missedCalls
|
import rasel.lunar.launcher.home.LauncherHome.Companion.missedCalls
|
||||||
|
import rasel.lunar.launcher.home.LauncherHome.Companion.rssSet
|
||||||
import rasel.lunar.launcher.home.LauncherHome.Companion.smsList
|
import rasel.lunar.launcher.home.LauncherHome.Companion.smsList
|
||||||
import rasel.lunar.launcher.home.MissedCall
|
import rasel.lunar.launcher.home.MissedCall
|
||||||
|
import rasel.lunar.launcher.todos.Root
|
||||||
|
import rasel.lunar.launcher.todos.RssDataItem
|
||||||
|
import rasel.lunar.launcher.todos.RssFeedsParser
|
||||||
import java.io.BufferedReader
|
import java.io.BufferedReader
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
@ -22,6 +32,8 @@ import java.io.InputStreamReader
|
|||||||
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.concurrent.Executors
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
|
||||||
class MissedCallGetter : Worker {
|
class MissedCallGetter : Worker {
|
||||||
@ -468,83 +480,101 @@ fun getContactId(contentResolver: ContentResolver, phoneNumber: String?): String
|
|||||||
|
|
||||||
|
|
||||||
class NewsFeedsGetter : Worker {
|
class NewsFeedsGetter : Worker {
|
||||||
|
var feddsUrls = arrayListOf<String>()
|
||||||
|
var rssUrls = arrayListOf<String>()
|
||||||
constructor(context: Context, workerParams: WorkerParameters) : super(context, workerParams) {
|
constructor(context: Context, workerParams: WorkerParameters) : super(context, workerParams) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@SuppressLint("RestrictedApi")
|
@SuppressLint("RestrictedApi")
|
||||||
override fun doWork(): Result {
|
override fun doWork(): Result {
|
||||||
BLog.LOGE("phNumber == onStart")
|
feddsUrls.clear()
|
||||||
var dateParam = beforeDay(Date(),3).toString()
|
feddsUrls.addAll(RssList.newsFeeds)
|
||||||
val managedCursor = lActivity?.contentResolver?.query(
|
rssUrls.clear()
|
||||||
Telephony.Sms.CONTENT_URI, arrayOf(
|
rssUrls.addAll(RssList.youtubeUrls)
|
||||||
Telephony.Sms.THREAD_ID,
|
var limitDateTime = beforeDay(Date(),3)
|
||||||
Telephony.Sms.ADDRESS,
|
BLog.LOGE("getFeeds it >> NewsFeedsGetter doWork Start")
|
||||||
Telephony.Sms.TYPE,
|
for(url in feddsUrls) {
|
||||||
Telephony.Sms.DATE,
|
GlobalScope.async {
|
||||||
Telephony.Sms.DATE_SENT,
|
for (it in RssFeedsParser.getFeeds(url)) {
|
||||||
Telephony.Sms.BODY,
|
if (it.pubDate() >= limitDateTime) {
|
||||||
Telephony.Sms.PERSON,
|
rssSet.put(it.originPage(), it)
|
||||||
), Telephony.Sms.DATE + "> ${dateParam}", null, Telephony.Sms.DEFAULT_SORT_ORDER)
|
|
||||||
if (managedCursor != null && managedCursor.isClosed == false) {
|
|
||||||
try {
|
|
||||||
smsList.clear()
|
|
||||||
val tid = managedCursor.getColumnIndex(Telephony.Sms.THREAD_ID)
|
|
||||||
val address = managedCursor.getColumnIndex(Telephony.Sms.ADDRESS)
|
|
||||||
val type = managedCursor.getColumnIndex(Telephony.Sms.TYPE)
|
|
||||||
val date = managedCursor.getColumnIndex(Telephony.Sms.DATE)
|
|
||||||
val sendDate = managedCursor.getColumnIndex(Telephony.Sms.DATE_SENT)
|
|
||||||
val bodyIdx = managedCursor.getColumnIndex(Telephony.Sms.BODY)
|
|
||||||
val name = managedCursor.getColumnIndex(Telephony.Sms.PERSON)
|
|
||||||
while (managedCursor.moveToNext()) {
|
|
||||||
val id = managedCursor.getString(tid) // mobile number
|
|
||||||
val phNumber = managedCursor.getString(address) // mobile number
|
|
||||||
val callType = managedCursor.getString(type) // call type
|
|
||||||
val reciveDate = managedCursor.getString(date) // call date
|
|
||||||
val sendedDate = managedCursor.getString(sendDate) // call date
|
|
||||||
val smsBody = managedCursor.getString(bodyIdx).replace("\n"," ")
|
|
||||||
val callerName = managedCursor.getString(name)
|
|
||||||
|
|
||||||
var dir: String = ""
|
|
||||||
val dircode = callType.toInt()
|
|
||||||
when (dircode) {
|
|
||||||
Telephony.Sms.MESSAGE_TYPE_ALL -> {dir = "MESSAGE_TYPE_ALL"}
|
|
||||||
Telephony.Sms.MESSAGE_TYPE_INBOX -> {dir = "MESSAGE_TYPE_INBOX"}
|
|
||||||
Telephony.Sms.MESSAGE_TYPE_SENT -> {dir = "MESSAGE_TYPE_SENT"}
|
|
||||||
Telephony.Sms.MESSAGE_TYPE_DRAFT -> {dir = "MESSAGE_TYPE_DRAFT"}
|
|
||||||
Telephony.Sms.MESSAGE_TYPE_OUTBOX -> {dir = "MESSAGE_TYPE_OUTBOX"}
|
|
||||||
Telephony.Sms.MESSAGE_TYPE_FAILED -> {dir = "MESSAGE_TYPE_FAILED"}
|
|
||||||
Telephony.Sms.MESSAGE_TYPE_QUEUED -> {dir = "MESSAGE_TYPE_QUEUED"}
|
|
||||||
}
|
}
|
||||||
var log = RecentSmsLog(
|
|
||||||
phNumber,
|
|
||||||
dir,
|
|
||||||
reciveDate,
|
|
||||||
sendedDate,
|
|
||||||
smsBody,
|
|
||||||
callerName ?: ""
|
|
||||||
)
|
|
||||||
log.id = id
|
|
||||||
log.isMms = false
|
|
||||||
// BLog.LOGE("RecentSmsGetter resultData put ${phNumber +"_"+ reciveDate} >>> ${log.toJson()}")
|
|
||||||
log.sender = getContactName(applicationContext.contentResolver,phNumber) ?: ""
|
|
||||||
smsList.add(log)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
managedCursor.close()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (lActivity?.contentResolver != null) {
|
BLog.LOGE("getFeeds it >> NewsFeedsGetter doWork before Yt")
|
||||||
TestQueryHelper(lActivity?.contentResolver!!).query()
|
for (url in rssUrls) {
|
||||||
|
GlobalScope.async {
|
||||||
|
ytChannel(Jsoup.connect(url).get())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BLog.LOGE("getFeeds it >> NewsFeedsGetter Result")
|
||||||
return Result.success()
|
return Result.success()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun ytChannel(doc: Document) {
|
||||||
|
BLog.LOGE("ytChannel >>>>> doc${doc.title()}")
|
||||||
|
try {
|
||||||
|
doc.getElementsByTag("script").forEach {
|
||||||
|
if(it.html().contains("var ytInitialData", false)) {/**/
|
||||||
|
var ytInitialData = it.html().split("var ytInitialData = ")[1].split("</script>")[0].toString()
|
||||||
|
var tempJSONObject : JSONObject? = null
|
||||||
|
JSONObject(ytInitialData).apply{
|
||||||
|
tempJSONObject = this
|
||||||
|
val root = Gson().fromJson(tempJSONObject.toString(), Root::class.java)
|
||||||
|
(if (root?.contents?.singleColumnBrowseResultsRenderer?.tabs?.size ?: 0 > 0) {
|
||||||
|
BLog.LOGE("ytChannel >>>>> doc singleColumnBrowseResultsRenderer apply ")
|
||||||
|
root?.contents?.singleColumnBrowseResultsRenderer?.tabs?.forEach {
|
||||||
|
it.tabRenderer?.content?.sectionListRenderer?.contents?.forEach {
|
||||||
|
// BLog.LOGE("ytChannel >>>>> doc sectionListRenderer?.contents ${Gson().toJson(it)} apply ")
|
||||||
|
it.shelfRenderer?.content?.verticalListRenderer?.items?.forEach {
|
||||||
|
// BLog.LOGE("ytChannel >>>>> doc verticalListRenderer?.items ${Gson().toJson(it)} apply ")
|
||||||
|
(it.compactVideoRenderer as? RssDataItem)?.let {
|
||||||
|
if(it.pubDate() >= (System.currentTimeMillis() - 1000L * 60L * 60L * 24 * 3)) {
|
||||||
|
rssSet.put(it.originPage(), it)
|
||||||
|
BLog.LOGE("ytChannel >>>>> doc RssDataItem ${Gson().toJson(it)} apply ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
BLog.LOGE("ytChannel >>>>> doc twoColumnBrowseResultsRenderer apply ")
|
||||||
|
root?.contents?.twoColumnBrowseResultsRenderer?.tabs?.forEach {
|
||||||
|
it.tabRenderer?.content?.sectionListRenderer?.contents?.forEach {
|
||||||
|
// BLog.LOGE("ytChannel >>>>> doc sectionListRenderer?.contents ${Gson().toJson(it)} apply ")
|
||||||
|
it.itemSectionRenderer?.contents?.forEach {
|
||||||
|
// BLog.LOGE("ytChannel >>>>> doc itemSectionRenderer?.items ${Gson().toJson(it)} apply ")
|
||||||
|
it.shelfRenderer?.content?.horizontalListRenderer?.items?.forEach {
|
||||||
|
// BLog.LOGE("it.gridVideoRenderer >>>>> ${Gson().toJson(it)}")
|
||||||
|
// BLog.LOGE("it.gridVideoRenderer >>>>> ${Gson().toJson(it.gridVideoRenderer)}")
|
||||||
|
// BLog.LOGE("it.gridVideoRenderer?.title ${Gson().toJson(it.gridVideoRenderer?.title)}")
|
||||||
|
// BLog.LOGE("it.gridVideoRenderer?.thumbnail ${Gson().toJson(it.gridVideoRenderer?.thumbnail)}")
|
||||||
|
// BLog.LOGE("it.gridVideoRenderer?.navigationEndpoint ${Gson().toJson(it.gridVideoRenderer?.navigationEndpoint)}")
|
||||||
|
// BLog.LOGE("it.gridVideoRenderer?.longBylineText ${Gson().toJson(it.gridVideoRenderer?.longBylineText)}")
|
||||||
|
// BLog.LOGE("it.gridVideoRenderer?.descriptionSnippet ${Gson().toJson(it.gridVideoRenderer?.descriptionSnippet)}")
|
||||||
|
// BLog.LOGE("it.gridVideoRenderer?.lengthText ${Gson().toJson(it.gridVideoRenderer?.lengthText)}")
|
||||||
|
(it.gridVideoRenderer as? RssDataItem)?.let {
|
||||||
|
if(it.pubDate() >= (System.currentTimeMillis() - 1000L * 60L * 60L * 24 * 3)) {
|
||||||
|
rssSet.put(it.originPage(), it)
|
||||||
|
BLog.LOGE("ytChannel >>>>> doc RssDataItem ${Gson().toJson(it)} apply ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).apply {
|
||||||
|
BLog.LOGE("ytChannel >>>>> doc${doc.title()} apply ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(e: Exception) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,19 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<FrameLayout
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:id="@+id/mainFragmentsContainer"
|
android:id="@+id/mainFragmentsContainer"
|
||||||
android:fitsSystemWindows="true">
|
android:fitsSystemWindows="true">
|
||||||
|
|
||||||
|
<WebView
|
||||||
|
android:layout_margin="30dp"
|
||||||
|
android:id="@+id/searcher_01"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:alpha="0"
|
||||||
|
android:layout_height="match_parent"/>
|
||||||
|
|
||||||
<androidx.viewpager2.widget.ViewPager2
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
|||||||
@ -5,17 +5,6 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
<WebView
|
|
||||||
android:layout_margin="30dp"
|
|
||||||
android:id="@+id/searcher_01"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:alpha="0.01"
|
|
||||||
android:layout_height="0dp"/>
|
|
||||||
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
@ -140,6 +129,31 @@
|
|||||||
app:layout_constraintTop_toBottomOf="@+id/summaryChoose"
|
app:layout_constraintTop_toBottomOf="@+id/summaryChoose"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
/>
|
/>
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/smsList"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:overScrollMode="never"
|
||||||
|
android:padding="20dp"
|
||||||
|
android:scrollbars="none"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/summaryChoose"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/infoList"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:overScrollMode="never"
|
||||||
|
android:padding="20dp"
|
||||||
|
android:scrollbars="none"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/summaryChoose"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
/>
|
||||||
|
|
||||||
<androidx.appcompat.widget.LinearLayoutCompat
|
<androidx.appcompat.widget.LinearLayoutCompat
|
||||||
android:id="@+id/favAppsGroup"
|
android:id="@+id/favAppsGroup"
|
||||||
|
|||||||
@ -5,29 +5,35 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
<!--rasel.lunar.launcher.view.CircleImageView-->
|
<!--rasel.lunar.launcher.view.CircleImageView-->
|
||||||
<rasel.lunar.launcher.view.CircleImageView
|
<ImageView
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
android:id="@+id/circle_preview"
|
android:id="@+id/circle_preview"
|
||||||
android:scaleType="fitCenter"
|
android:scaleType="fitCenter"
|
||||||
android:adjustViewBounds="true"
|
android:adjustViewBounds="true"
|
||||||
android:layout_width="90dp"
|
android:layout_width="120dp"
|
||||||
android:layout_height="90dp"/>
|
android:layout_height="120dp"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/title"
|
android:id="@+id/title"
|
||||||
android:layout_width="@dimen/zero"
|
android:layout_width="@dimen/zero"
|
||||||
android:layout_height="30dp"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center_vertical|right"
|
android:textSize="24sp"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:includeFontPadding="false"
|
||||||
|
android:ellipsize="middle"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintLeft_toRightOf="@id/circle_preview"
|
app:layout_constraintLeft_toRightOf="@id/circle_preview"
|
||||||
app:layout_constraintRight_toRightOf="parent"/>
|
app:layout_constraintRight_toRightOf="parent"/>
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/desc"
|
android:id="@+id/desc"
|
||||||
android:layout_width="@dimen/zero"
|
android:layout_width="@dimen/zero"
|
||||||
android:layout_height="43dp"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center_vertical|right"
|
android:textSize="16sp"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:includeFontPadding="false"
|
||||||
|
android:ellipsize="middle"
|
||||||
app:layout_constraintTop_toBottomOf="@id/title"
|
app:layout_constraintTop_toBottomOf="@id/title"
|
||||||
app:layout_constraintBottom_toTopOf="@id/date"
|
app:layout_constraintBottom_toTopOf="@id/date"
|
||||||
app:layout_constraintLeft_toRightOf="@id/circle_preview"
|
app:layout_constraintLeft_toRightOf="@id/circle_preview"
|
||||||
@ -35,8 +41,10 @@
|
|||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/date"
|
android:id="@+id/date"
|
||||||
android:layout_width="@dimen/zero"
|
android:layout_width="@dimen/zero"
|
||||||
android:layout_height="30dp"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center_vertical|right"
|
android:textSize="16sp"
|
||||||
|
android:lines="1"
|
||||||
|
android:includeFontPadding="false"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintLeft_toRightOf="@id/circle_preview"
|
app:layout_constraintLeft_toRightOf="@id/circle_preview"
|
||||||
app:layout_constraintRight_toRightOf="parent"/>
|
app:layout_constraintRight_toRightOf="parent"/>
|
||||||
|
|||||||
27
app/src/main/res/layout/text_inpu_password.xml
Normal file
27
app/src/main/res/layout/text_inpu_password.xml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/colorInputLayout"
|
||||||
|
android:layout_width="@dimen/oneNinetySix"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/argb"
|
||||||
|
app:boxBackgroundColor="?attr/colorSurface"
|
||||||
|
app:endIconMode="clear_text"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/input"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:imeOptions="actionDone"
|
||||||
|
android:inputType="textPassword" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
Loading…
x
Reference in New Issue
Block a user