This commit is contained in:
JUNGGWAN KIM 2024-10-11 09:34:14 +09:00
commit 45552eacf8
40 changed files with 1447 additions and 1282 deletions

View File

@ -96,6 +96,9 @@ dependencies {
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.6.4")
implementation("com.squareup.retrofit2:converter-scalars:2.6.4")
// implementation ("me.everything:providers-android:1.0.1")
// implementation ("me.everything:providers-core:1.0.1")
// implementation ("androidx.window:window:1.0.0")
// implementation("io.github.vaneproject:hanguleditor:1.0.0")
}

View File

@ -26,7 +26,8 @@
<uses-permission android:name="android.permission.RECEIVE_MMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<!-- Always include this permission -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

View File

@ -33,7 +33,6 @@ import android.content.pm.PackageManager
import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.Color
import android.location.Location
import android.net.Uri
import android.net.http.SslError
import android.os.Build
@ -92,6 +91,7 @@ import rasel.lunar.launcher.helpers.Constants.Companion.KEY_STATUS_BAR
import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_FIRST_LAUNCH
import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_SETTINGS
import rasel.lunar.launcher.helpers.Constants.Companion.widgetHostId
import rasel.lunar.launcher.helpers.PrefHelper
import rasel.lunar.launcher.helpers.ViewPagerAdapter
import rasel.lunar.launcher.home.LauncherHome
import rasel.lunar.launcher.home.LauncherHome.Companion.lastedFinishedPageUrl
@ -109,21 +109,28 @@ import rasel.lunar.launcher.utils.beforeDay
import rasel.lunar.launcher.utils.make0H
import rasel.lunar.launcher.workers.AppInfoGetter
import rasel.lunar.launcher.workers.ArcaGetter
import rasel.lunar.launcher.workers.CalendarGetter
import rasel.lunar.launcher.workers.ClienGetter
import rasel.lunar.launcher.workers.ContactInfoGetter
import rasel.lunar.launcher.workers.DCGetter
import rasel.lunar.launcher.workers.DotaxGetter
import rasel.lunar.launcher.workers.DotaxGetter.Companion.COMIC2_WORK_TAG
import rasel.lunar.launcher.workers.FmKoreaGetter
import rasel.lunar.launcher.workers.FmKoreaGetter.Companion.COMIC_WORK_TAG
import rasel.lunar.launcher.workers.LocationGetter
import rasel.lunar.launcher.workers.NewsFeedsGetter
import rasel.lunar.launcher.workers.NewsFeedsGetter.Companion.FEDDS_WORK_TAG
import rasel.lunar.launcher.workers.OpenWeatherGetter
import rasel.lunar.launcher.workers.RecentCallGetter
import rasel.lunar.launcher.workers.RecentSmsGetter
import rasel.lunar.launcher.workers.RecentSmsGetter.Companion.SMS_WORK_TAG
import rasel.lunar.launcher.workers.RedditGetter
import rasel.lunar.launcher.workers.RedditGetter.Companion.REDDIT_WORK_TAG
import rasel.lunar.launcher.workers.RuliWebGetter
import rasel.lunar.launcher.workers.TheQooGetter
import rasel.lunar.launcher.workers.WorkersDb
import rasel.lunar.launcher.workers.YoutubeGetter
import rasel.lunar.launcher.workers.YoutubeGetter.Companion.YT_WORK_TAG
import java.io.File
import java.io.IOException
import java.text.SimpleDateFormat
@ -142,18 +149,8 @@ internal class LauncherActivity : AppCompatActivity() {
lateinit var viewPager: ViewPager2
companion object {
private var mWorkManager: WorkManager? = null
val SMS_WORK_TAG = "RecentSmsGetter"
val CALL_WORK_TAG = "MissedCallGetter"
val FEDDS_WORK_TAG = "NewsFeedsGetter"
val YT_WORK_TAG = "YoutubeGetter"
val COMIC_WORK_TAG = "ComicGetter"
val COMIC2_WORK_TAG = "ComicGetter2"
val REDDIT_WORK_TAG = "RedditGetter"
val shortTimePeriod = 20L
val longTimePeriod = 60L
val midTimePeriod = 30L
var isOpendFold = false
val qDayPeriod = 60L * 8L
@ -167,7 +164,7 @@ internal class LauncherActivity : AppCompatActivity() {
mWorkManager?.enqueueUniquePeriodicWork(
SMS_WORK_TAG,
ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<RecentSmsGetter>(longTimePeriod, TimeUnit.MINUTES)
PeriodicWorkRequestBuilder<RecentSmsGetter>(PrefHelper.longTimePeriod, TimeUnit.MINUTES)
.addTag(SMS_WORK_TAG)
.build())
}, 500, TimeUnit.MILLISECONDS)
@ -176,7 +173,7 @@ internal class LauncherActivity : AppCompatActivity() {
mWorkManager?.enqueueUniquePeriodicWork(
RecentCallGetter.TAG,
ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<RecentCallGetter>(longTimePeriod, TimeUnit.MINUTES)
PeriodicWorkRequestBuilder<RecentCallGetter>(PrefHelper.longTimePeriod, TimeUnit.MINUTES)
.addTag(RecentCallGetter.TAG)
.build())
}, 500, TimeUnit.MILLISECONDS)
@ -205,9 +202,15 @@ internal class LauncherActivity : AppCompatActivity() {
}, 5, TimeUnit.SECONDS)
}
fun doGetWheaterByLocationInfo() {
fun runWeatherGetter() {
Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.enqueue(OneTimeWorkRequest.from(OpenWeatherGetter::class.java))
}, 200L, TimeUnit.MILLISECONDS)
}
fun getCal() {
Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.enqueue(OneTimeWorkRequest.from(CalendarGetter::class.java))
}, 5, TimeUnit.SECONDS)
}
@ -217,7 +220,7 @@ internal class LauncherActivity : AppCompatActivity() {
mWorkManager?.cancelAllWorkByTag(FEDDS_WORK_TAG)
mWorkManager?.enqueueUniquePeriodicWork(
FEDDS_WORK_TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<NewsFeedsGetter>(shortTimePeriod, TimeUnit.MINUTES)
PeriodicWorkRequestBuilder<NewsFeedsGetter>(PrefHelper.shortTimePeriod, TimeUnit.MINUTES)
.addTag(FEDDS_WORK_TAG)
.build())
}, delay, TimeUnit.SECONDS)
@ -226,7 +229,7 @@ internal class LauncherActivity : AppCompatActivity() {
mWorkManager?.cancelAllWorkByTag(YT_WORK_TAG)
mWorkManager?.enqueueUniquePeriodicWork(
YT_WORK_TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<YoutubeGetter>(longTimePeriod, TimeUnit.MINUTES)
PeriodicWorkRequestBuilder<YoutubeGetter>(PrefHelper.longTimePeriod, TimeUnit.MINUTES)
.addTag(YT_WORK_TAG)
.build())
}, delay, TimeUnit.SECONDS)
@ -235,7 +238,7 @@ internal class LauncherActivity : AppCompatActivity() {
mWorkManager?.cancelAllWorkByTag(REDDIT_WORK_TAG)
mWorkManager?.enqueueUniquePeriodicWork(
REDDIT_WORK_TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<RedditGetter>(midTimePeriod, TimeUnit.MINUTES)
PeriodicWorkRequestBuilder<RedditGetter>(PrefHelper.midTimePeriod, TimeUnit.MINUTES)
.addTag(REDDIT_WORK_TAG)
.build())
}, delay, TimeUnit.SECONDS)
@ -244,7 +247,7 @@ internal class LauncherActivity : AppCompatActivity() {
mWorkManager?.cancelAllWorkByTag(COMIC_WORK_TAG)
mWorkManager?.enqueueUniquePeriodicWork(
COMIC_WORK_TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<FmKoreaGetter>(midTimePeriod, TimeUnit.MINUTES)
PeriodicWorkRequestBuilder<FmKoreaGetter>(PrefHelper.midTimePeriod, TimeUnit.MINUTES)
.addTag(COMIC_WORK_TAG)
.build())
}, delay, TimeUnit.SECONDS)
@ -253,7 +256,7 @@ internal class LauncherActivity : AppCompatActivity() {
mWorkManager?.cancelAllWorkByTag(COMIC2_WORK_TAG)
mWorkManager?.enqueueUniquePeriodicWork(
COMIC2_WORK_TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<DotaxGetter>(midTimePeriod, TimeUnit.MINUTES)
PeriodicWorkRequestBuilder<DotaxGetter>(PrefHelper.midTimePeriod, TimeUnit.MINUTES)
.addTag(COMIC2_WORK_TAG)
.build())
}, delay, TimeUnit.SECONDS)
@ -262,7 +265,7 @@ internal class LauncherActivity : AppCompatActivity() {
mWorkManager?.cancelAllWorkByTag(ClienGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork(
ClienGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<ClienGetter>(midTimePeriod, TimeUnit.MINUTES)
PeriodicWorkRequestBuilder<ClienGetter>(PrefHelper.midTimePeriod, TimeUnit.MINUTES)
.addTag(ClienGetter.TAG)
.build())
}, delay, TimeUnit.SECONDS)
@ -271,7 +274,7 @@ internal class LauncherActivity : AppCompatActivity() {
mWorkManager?.cancelAllWorkByTag(DCGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork(
DCGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<DCGetter>(midTimePeriod, TimeUnit.MINUTES)
PeriodicWorkRequestBuilder<DCGetter>(PrefHelper.midTimePeriod, TimeUnit.MINUTES)
.addTag(DCGetter.TAG)
.build())
}, delay, TimeUnit.SECONDS)
@ -280,7 +283,7 @@ internal class LauncherActivity : AppCompatActivity() {
mWorkManager?.cancelAllWorkByTag(RuliWebGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork(
RuliWebGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<RuliWebGetter>(midTimePeriod, TimeUnit.MINUTES)
PeriodicWorkRequestBuilder<RuliWebGetter>(PrefHelper.midTimePeriod, TimeUnit.MINUTES)
.addTag(RuliWebGetter.TAG)
.build())
}, delay, TimeUnit.SECONDS)
@ -289,7 +292,7 @@ internal class LauncherActivity : AppCompatActivity() {
mWorkManager?.cancelAllWorkByTag(TheQooGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork(
TheQooGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<TheQooGetter>(midTimePeriod, TimeUnit.MINUTES)
PeriodicWorkRequestBuilder<TheQooGetter>(PrefHelper.midTimePeriod, TimeUnit.MINUTES)
.addTag(TheQooGetter.TAG)
.build())
}, delay, TimeUnit.SECONDS)
@ -298,7 +301,7 @@ internal class LauncherActivity : AppCompatActivity() {
mWorkManager?.cancelAllWorkByTag(ArcaGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork(
ArcaGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<ArcaGetter>(midTimePeriod, TimeUnit.MINUTES)
PeriodicWorkRequestBuilder<ArcaGetter>(PrefHelper.midTimePeriod, TimeUnit.MINUTES)
.addTag(ArcaGetter.TAG)
.build())
@ -310,7 +313,7 @@ internal class LauncherActivity : AppCompatActivity() {
mWorkManager?.cancelAllWorkByTag(LocationGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork(
LocationGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<LocationGetter>(midTimePeriod, TimeUnit.MINUTES)
PeriodicWorkRequestBuilder<LocationGetter>(PrefHelper.shortTimePeriod, TimeUnit.MINUTES)
.addTag(LocationGetter.TAG)
.build())
}, weatherDelay, TimeUnit.SECONDS)
@ -363,7 +366,7 @@ internal class LauncherActivity : AppCompatActivity() {
// }
}
@SuppressLint("NewApi")
@SuppressLint("NewApi", "MissingPermission")
override fun onCreate(savedInstanceState: Bundle?) {
installSplashScreen()
mWorkManager = WorkManager.getInstance(this)
@ -435,6 +438,8 @@ internal class LauncherActivity : AppCompatActivity() {
private fun welcomeDialog() {
var needAsk = if (
this.checkSelfPermission(Manifest.permission.READ_CALENDAR) != PackageManager.PERMISSION_GRANTED ||
this.checkSelfPermission(Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED ||
this.checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED ||
this.checkSelfPermission(Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED ||
this.checkSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED ||
@ -473,6 +478,8 @@ internal class LauncherActivity : AppCompatActivity() {
/* phone permission */
if (
this.checkSelfPermission(Manifest.permission.READ_CALENDAR) != PackageManager.PERMISSION_GRANTED ||
this.checkSelfPermission(Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED ||
this.checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED ||
this.checkSelfPermission(Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED ||
this.checkSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED ||
@ -484,6 +491,8 @@ internal class LauncherActivity : AppCompatActivity() {
this.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
) {
this.requestPermissions(arrayOf(
Manifest.permission.READ_CALENDAR,
Manifest.permission.WRITE_CALENDAR,
Manifest.permission.READ_CONTACTS,
Manifest.permission.READ_CALL_LOG,
Manifest.permission.CALL_PHONE,
@ -614,137 +623,136 @@ internal class LauncherActivity : AppCompatActivity() {
startActivity(mapIntent)
}
fun doWebSavor(url : String, callBack :CommadCallabck?) {
if (true)return
this.callBack = callBack
binding.searcher01.post { binding.searcher01.visibility = View.VISIBLE }
BLog.LOGE("binding.otherCheck before ThreadRun")
binding.searcher01.bringToFront()
binding.searcher01.alpha = 1f
binding.searcher01.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
if (url?.contains("missav") == true && isF) {
BLog.LOGE("binding.otherCheck before reload")
view?.loadUrl(url!!)
isF = true
return false
}
return false
}
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
BLog.LOGE("binding.otherCheck searcher01 in onPageStarted ${url}")
super.onPageStarted(view, url, favicon)
}
override fun onReceivedError(
view: WebView?,
request: WebResourceRequest?,
error: WebResourceError?
) {
}
override fun onReceivedSslError(
view: WebView?,
handler: SslErrorHandler?,
error: SslError?
) {
handler?.proceed()
}
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
autoScrollDown(view,url)
}
}
WebView.setWebContentsDebuggingEnabled(false)
binding.searcher01.apply {
setBackgroundColor(Color.WHITE) // 백그라운드 색상 설정
setLayerType(View.LAYER_TYPE_SOFTWARE, null) // 랜더링 이슈 해결
try {
settings.apply {
userAgentString = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
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) {
}.apply {
loadUrl(url) // 웹페이지 연결
}
}
}
fun autoScrollDown(webView: WebView?, url: String?) {
webView?.let { webView ->
val ramdomTimeSec =
800L.plus(Math.abs(Random(System.currentTimeMillis()).nextLong().rem(489L)))
BLog.LOGE("ramdomTime >>> ${ramdomTimeSec}")
if (((webView?.scrollY ?: 0) + (webView?.height
?: 0)) < webView?.contentHeight ?: 0
) {
webView?.postDelayed({
webView?.scrollY = (binding.searcher01.scrollY) + (binding.searcher01.height.toFloat() * 0.4).toInt()
autoScrollDown(webView, url)
}, ramdomTimeSec)
} else {
webView?.postDelayed({
binding.viewPager.bringToFront()
binding.searcher01.alpha = 0f
if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) {
val fileName = url?.toUri()?.path?.replace("/","_")?.replace(".","_")
val path = File(Environment.getExternalStorageDirectory(),"bums")
if (path.exists() == false) {
path.mkdirs()
}
val file = File(path, fileName.plus(".pdf"))
BLog.LOGE("file >>> ${file.absolutePath}")
try {
PDFPrint.generatePDFFromWebView(file,webView, object : PDFPrint.OnPDFPrintListener {
override fun onSuccess(file: File?) {
BLog.LOGE("file >>>> ${file!!.absolutePath}")
val shareIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
this.`package` = "com.synology.dsdrive"
val imageUri = FileProvider.getUriForFile(
this@LauncherActivity,
"rasel.lunar.launcher.debug.fileprovider", //(use your app signature + ".provider" )
file
)
putExtra(Intent.EXTRA_STREAM, imageUri)
type = "pdf"
}
this@LauncherActivity.startActivity(shareIntent)
}
override fun onError(exception: java.lang.Exception?) {
Toast.makeText(this@LauncherActivity,
"Pdf Save Failk ${exception?.localizedMessage}", Toast.LENGTH_LONG).show()
exception?.printStackTrace()
}
} )
} catch (e: IOException) {
e.printStackTrace()
}
} else {
}
}, ramdomTimeSec)
}
}
}
// fun doWebSavor(url : String, callBack :CommadCallabck?) {
// if (true)return
// this.callBack = callBack
//
// binding.searcher01.post { binding.searcher01.visibility = View.VISIBLE }
// BLog.LOGE("binding.otherCheck before ThreadRun")
// binding.searcher01.bringToFront()
// binding.searcher01.alpha = 1f
// binding.searcher01.webViewClient = object : WebViewClient() {
// override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
// if (url?.contains("missav") == true && isF) {
// BLog.LOGE("binding.otherCheck before reload")
// view?.loadUrl(url!!)
// isF = true
// return false
// }
// return false
// }
//
// override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
// BLog.LOGE("binding.otherCheck searcher01 in onPageStarted ${url}")
// super.onPageStarted(view, url, favicon)
// }
// override fun onReceivedError(
// view: WebView?,
// request: WebResourceRequest?,
// error: WebResourceError?
// ) {
//
// }
// override fun onReceivedSslError(
// view: WebView?,
// handler: SslErrorHandler?,
// error: SslError?
// ) {
// handler?.proceed()
// }
//
// override fun onPageFinished(view: WebView?, url: String?) {
// super.onPageFinished(view, url)
// autoScrollDown(view,url)
//
// }
// }
//
// WebView.setWebContentsDebuggingEnabled(false)
// binding.searcher01.apply {
// setBackgroundColor(Color.WHITE) // 백그라운드 색상 설정
// setLayerType(View.LAYER_TYPE_SOFTWARE, null) // 랜더링 이슈 해결
// try {
// settings.apply {
// userAgentString = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
// 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) {
//
// }.apply {
// loadUrl(url) // 웹페이지 연결
// }
// }
// }
// fun autoScrollDown(webView: WebView?, url: String?) {
// webView?.let { webView ->
// val ramdomTimeSec =
// 800L.plus(Math.abs(Random(System.currentTimeMillis()).nextLong().rem(489L)))
// BLog.LOGE("ramdomTime >>> ${ramdomTimeSec}")
// if (((webView?.scrollY ?: 0) + (webView?.height
// ?: 0)) < webView?.contentHeight ?: 0
// ) {
// webView?.postDelayed({
// webView?.scrollY = (binding.searcher01.scrollY) + (binding.searcher01.height.toFloat() * 0.4).toInt()
// autoScrollDown(webView, url)
// }, ramdomTimeSec)
// } else {
// webView?.postDelayed({
// binding.viewPager.bringToFront()
// binding.searcher01.alpha = 0f
// if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) {
// val fileName = url?.toUri()?.path?.replace("/","_")?.replace(".","_")
// val path = File(Environment.getExternalStorageDirectory(),"bums")
// if (path.exists() == false) {
// path.mkdirs()
// }
// val file = File(path, fileName.plus(".pdf"))
//
// BLog.LOGE("file >>> ${file.absolutePath}")
// try {
// PDFPrint.generatePDFFromWebView(file,webView, object : PDFPrint.OnPDFPrintListener {
// override fun onSuccess(file: File?) {
// BLog.LOGE("file >>>> ${file!!.absolutePath}")
// val shareIntent: Intent = Intent().apply {
// action = Intent.ACTION_SEND
// this.`package` = "com.synology.dsdrive"
// val imageUri = FileProvider.getUriForFile(
// this@LauncherActivity,
// "rasel.lunar.launcher.debug.fileprovider", //(use your app signature + ".provider" )
// file
// )
// putExtra(Intent.EXTRA_STREAM, imageUri)
// type = "pdf"
// }
// this@LauncherActivity.startActivity(shareIntent)
// }
//
// override fun onError(exception: java.lang.Exception?) {
// Toast.makeText(this@LauncherActivity,
// "Pdf Save Failk ${exception?.localizedMessage}", Toast.LENGTH_LONG).show()
// exception?.printStackTrace()
// }
// } )
// } catch (e: IOException) {
// e.printStackTrace()
// }
// } else {
//
// }
// }, ramdomTimeSec)
// }
// }
// }
var callBack : CommadCallabck? = null
var isF = false
@ -783,8 +791,6 @@ internal class LauncherActivity : AppCompatActivity() {
handler?.proceed()
}
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
lastedFinishedPageUrl = url ?: ""
@ -797,9 +803,7 @@ internal class LauncherActivity : AppCompatActivity() {
" MyJavaScriptInterface.sendValueFromHtml(document.getElementsByTagName('html')[0].innerHTML)" +
" };getAll()"
) { result ->
(result as? String)?.let {
}
(result as? String)?.let {}
}
} else if(url?.contains("translate.google.com") == true) {
binding.searcher01.postDelayed({
@ -808,9 +812,7 @@ internal class LauncherActivity : AppCompatActivity() {
" MyJavaScriptInterface.sendValueFromHtml(document.getElementsByTagName('html')[0].innerHTML)" +
" };getAll()"
) { result ->
(result as? String)?.let {
}
(result as? String)?.let {}
}
}, 6000L)
} else {
@ -820,20 +822,10 @@ internal class LauncherActivity : AppCompatActivity() {
" MyJavaScriptInterface.sendValueFromHtml(document.getElementsByTagName('html')[0].innerHTML)" +
" };getAll()"
) { result ->
(result as? String)?.let {
}
(result as? String)?.let {}
}
// if (!isF) {
// binding.searcher01.post {
// binding.searcher01.loadUrl("https://missav.com/dm11/ko")
// isF = true
// }
// }
}
if (isF) this@LauncherActivity.callBack?.collectComplete()
// binding.searcher01.post { binding.searcher01.visibility = View.GONE }
// }
}
}
WebView.setWebContentsDebuggingEnabled(false)
@ -906,7 +898,6 @@ internal class LauncherActivity : AppCompatActivity() {
}
}
fun jGuruMain(doc: Document) {
// BLog.LOGE("SimpleDateFormat D MM yy => ${SimpleDateFormat("d MMM yy", Locale.US).format(Date())}")
var temp = arrayListOf<RssData>()
val prevUrl = doc.getElementsByClass("prev").get(0).getElementsByAttribute("href").get(0).attr("href")
doc.getElementsByClass("column").forEach {
@ -925,9 +916,6 @@ internal class LauncherActivity : AppCompatActivity() {
var itemC = 0
WorkersDb.insertBulkInteface(temp)
callBack?.onConsoleLog("Stored data :: ${simpldateFormat.format(Date(minDate))} ~ ${simpldateFormat.format(Date(maxDate))} set in ${itemC}")
// Toast.makeText(this@LauncherActivity,
// "Stored data :: ${listItem.size} items :: [${simpldateFormat.format(Date(minDate))} ~ ${simpldateFormat.format(Date(maxDate))}] \n set in ${itemC}", Toast.LENGTH_LONG).show()
//// }
binding.searcher01?.post { binding.searcher01.loadData("<html></html>",null,null) }
this@LauncherActivity.callBack?.collectComplete()
}
@ -947,39 +935,26 @@ internal class LauncherActivity : AppCompatActivity() {
}
}
}.apply {
// listTags.sortByDescending { it.pubDate() }
// Toast.makeText(this@LauncherActivity,
// "Stored data :: ${listTags.size}tags", Toast.LENGTH_SHORT).show()
binding.searcher01?.post { binding.searcher01.loadData("<html></html>",null,null) }
this@LauncherActivity.callBack?.collectComplete()
}
}
inner class MyJavaScriptInterface(val webView: WebView) {
@JavascriptInterface
fun sendValueFromHtml(result: String) {
// BLog.LOGE("binding.otherCheck start with ${result}")
if (lastedFinishedPageUrl.contains(jGuruMain)) {
var htmlString = result.replace("\\u003","<")
val doc: Document = Jsoup.parse(htmlString)
if (lastedFinishedPageUrl?.contains("page") == true || lastedFinishedPageUrl?.equals(
jGuruMain
) == true
) {
if (lastedFinishedPageUrl?.contains("page") == true || lastedFinishedPageUrl?.equals(jGuruMain) == true) {
jGuruMain(doc)
} else if (lastedFinishedPageUrl?.contains("/most-watched-rank") == true) {
jGuruToday(doc)
} else if (lastedFinishedPageUrl?.contains("/tags/") == true) {
jGuruTag(doc)
}
} else if (lastedFinishedPageUrl?.contains("youtube") == true) {
// val doc: Document = Jsoup.parse(result)
// ytChannel(doc)
} else if (lastedFinishedPageUrl?.contains("missav")==true) {
} else if (lastedFinishedPageUrl?.contains("missav")==true) {
val doc: Document = Jsoup.parse(result)
// BLog.LOGE("missav >>> ${doc}")
var temp = arrayListOf<RssData>()
doc.getElementsByClass("thumbnail group").forEach { miss_li ->
if (miss_li.getElementsByTag("img").size > 0 && miss_li.getElementsByTag("img").get(0).attr("data-src").length > 10 &&
@ -999,32 +974,8 @@ internal class LauncherActivity : AppCompatActivity() {
}
}.apply {
WorkersDb.insertBulkData(temp)
// BLog.LOGE("temp >>> ${temp.size}")
// binding.searcher01?.post { binding.searcher01.loadData("<html></html>",null,null) }
}
} else if(lastedFinishedPageUrl?.contains("javmost")==true){
val doc: Document = Jsoup.parse(result)
callBack?.onConsoleLog("${lastedFinishedPageUrl} >>> ${doc.title()}")
doc.getElementsByClass("card").forEach { card ->
callBack?.onConsoleLog("${lastedFinishedPageUrl}_card >>> ${card}")
var model = if(card.getElementsByTag("img").size > 0) card.getElementsByTag("img").get(0).attr("src") else ""
var thumb = if(card.getElementsByTag("img").size > 0) card.getElementsByTag("img").get(0).attr("alt") else ""
var title = ""
var date = ""
if(card.getElementsByClass("card-block").size > 0) if(card.getElementsByClass("card-block").size > 0) {
title = card.getElementsByClass("card-block").get(0).getElementsByTag("a").get(0).attr("title")
date = card.getElementsByTag("span").get(0).text()
}
callBack?.onConsoleLog("" +
"model >>>>> ${model}\n" +
"thumb >>>>> ${thumb}\n" +
"title >>>>> ${title}\n" +
"date >>>>> ${date}" +
"")
}
} else if(lastedFinishedPageUrl?.contains("https://translate.google.com") == true){
} else if(lastedFinishedPageUrl?.contains("https://translate.google.com") == true){
callBackHandler.removeCallbacks(postNext)
val doc: Document = Jsoup.parse(result)
doc.getElementsByTag("span").forEach { span ->

View File

@ -20,13 +20,21 @@ package rasel.lunar.launcher
import android.app.Application
import android.content.ComponentCallbacks2
import android.content.Context
import android.content.SharedPreferences
import android.database.sqlite.SQLiteDatabase
import rasel.lunar.launcher.helpers.PrefHelper
internal class LunarLauncher : Application() {
companion object {
var appContext : Context? = null
}
override fun onCreate() {
super.onCreate()
// Picasso.get().setIndicatorsEnabled(true)
appContext = this
PrefHelper.inject(getSharedPreferences(PrefHelper.D_PREFIX, Context.MODE_PRIVATE))
}
override fun onTrimMemory(level: Int) {
super.onTrimMemory(level)
@ -34,4 +42,4 @@ internal class LunarLauncher : Application() {
if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) SQLiteDatabase.releaseMemory()
}
}
}

View File

@ -209,6 +209,40 @@ internal class AppDrawer : Fragment() {
false
}
}
binding.searchInput.setOnLongClickListener {
WorkersDb.getRealm().apply {
var newQ = query<AppInfo>()
appQuery = newQ.sort(Pair("clickCount", Sort.DESCENDING),Pair("lastUseDate",Sort.DESCENDING)).find()
appQuery?.let {
if(it.size > 0) {
WorkersDb.getRealm().apply {
packageList.clear()
packageList.addAll(copyFromRealm(it))
binding.appsList.post { if (packageList.size > 0) {
appsAdapter?.updateData(packageList)
} }
}
}
}
}
WorkersDb.getRealm().apply {
var newQ = query<SimpleContact>()
contactQuery = newQ.sort(Pair("touchCount", Sort.DESCENDING),Pair("lastedTouchDateTime",Sort.DESCENDING)).find()
contactQuery?.let {
if (it.size > 0) {
contactList.clear()
contactList.addAll(copyFromRealm(it).toList())
binding.contactList.post {
if (contactList.size > 0) {
contactAdapter?.updateData(contactList)
}
}
}
}
}
true
}
binding.searchInput.doOnTextChanged{ inputText, _, _, _ ->
binding.searchInput.text?.let { binding.searchInput.setSelection(it.length) }
filterAppsList(inputText.toString())
@ -216,86 +250,9 @@ internal class AppDrawer : Fragment() {
}
fun checkResult(keyword: String) {
// if(!isAdded || !isResumed || keyword.length < 1) return
// var dialog : AlertDialog.Builder? = null
// var filted = packageList.filter { it.appName.equals(keyword) }
// BLog.LOGE("filted >> ${filted.size}")
// var filtedContact = contactList.filter { it.name.equals(keyword) }
// BLog.LOGE("filtedContact >> ${filtedContact.size}")
// if (keyword.length > 0 && (packageList.size == 1 || filted.size > 0)) {
// dialog = AlertDialog.Builder(requireContext())
// dialog?.setTitle("앱 실행 확인")
// if (packageList.size == 1) {
// dialog?.setMessage("${keyword} 검색 결과 '${packageList[0].appName}' 준비됨")
// dialog?.setPositiveButton("실행") { s, d ->
// runonUi {
// startActivity(packageManager?.getLaunchIntentForPackage(packageList[0].pkgName!!))
// s.dismiss()
// }
// }
// } else if (filted.size > 0) {
// dialog?.setMessage("${keyword} 검색 결과 '${filted[0].appName}' 준비됨")
// dialog?.setPositiveButton("${filted[0].appName} 실행") { s, d ->
// runonUi {
// startActivity(packageManager?.getLaunchIntentForPackage(filted[0].pkgName!!))
// s.dismiss()
// }
// }
// if(filted.size > 1) {
// dialog?.setNeutralButton("${filted[1].appName} 실행") { s, d ->
// runonUi {
// startActivity(packageManager?.getLaunchIntentForPackage(filted[1].pkgName!!))
// s.dismiss()
// }
// }
// }
// }
// dialog?.setCancelable(false)
// dialog?.setNegativeButton("취소") { s, d ->
// runonUi { s.dismiss() }
// }
// dialog?.setOnDismissListener { registCancelSearch() }
// dialog?.show()
// } else if (contactList.size == 1 || filtedContact.size > 0) {
// dialog = AlertDialog.Builder(requireContext())
// dialog?.setTitle("연락처 실행 확인")
// dialog?.setCancelable(false)
// dialog?.setNegativeButton("취소") { s, d ->
// runonUi { s.dismiss() }
// }
// if (contactList.size == 1) {
// dialog?.setMessage("${keyword} 검색 결과 '${contactList[0].name}' 준비됨")
// dialog?.setPositiveButton("자세히 보기") { s, d ->
// runonUi {
// ContactMenu().show(childFragmentManager, contactList[0].id.toString())
// s.dismiss()
// }
// }
// } else if(filtedContact.size > 0) {
// dialog?.setMessage("${keyword} 검색 결과 '${filtedContact[0].name}' 준비됨")
// dialog?.setPositiveButton("'${filtedContact[0].name},\n${filtedContact[0].phoneNumber}'\n자세히 보기") { s, d ->
// runonUi {
// ContactMenu().show(childFragmentManager, filtedContact[0].id.toString())
// s.dismiss()
// }
// }
// if (filtedContact.size > 1) {
// dialog?.setNeutralButton("'${filtedContact[1].name},\n${filtedContact[1].phoneNumber}'\n자세히 보기") { s, d ->
// runonUi {
// ContactMenu().show(childFragmentManager, filtedContact[1].id.toString())
// s.dismiss()
// }
// }
// }
// }
// dialog?.setOnDismissListener { registCancelSearch() }
// dialog?.show()
// } else {
lActivity?.openSearchMenus(keyword) {
registCancelSearch()
}
// }
lActivity?.openSearchMenus(keyword) {
registCancelSearch()
}
}
@ -320,7 +277,7 @@ internal class AppDrawer : Fragment() {
openSearch()
registCancelSearch()
BLog.LOGE("onResume after chechHandler.postDelayed(cancelSearch, 3000L)")
// BLog.LOGE("onResume after chechHandler.postDelayed(cancelSearch, 3000L)")
}
val chechHandler = Handler(Looper.getMainLooper())
@ -328,9 +285,8 @@ internal class AppDrawer : Fragment() {
val cancelSearch = Runnable { lActivity?.viewPager?.currentItem = 1 }
fun registCancelSearch() {
BLog.LOGE("Called registCancelSearch")
chechHandler.removeCallbacks(cancelSearch)
chechHandler.postDelayed(cancelSearch, 8000L)
chechHandler.postDelayed(cancelSearch, 15000L)
}
fun clearCancelSearch() {
@ -343,13 +299,6 @@ internal class AppDrawer : Fragment() {
}
private fun setLayout() {
// when (layoutType) {
// 0, 1 -> {
// binding.appsList.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL,false)
// appsAdapter!!.updateGravity(settingsPrefs!!.getInt(KEY_DRAW_ALIGN, Gravity.CENTER))
// }
// 2 -> binding.appsList.layoutManager = GridLayoutManager(requireContext(), Math.min(settingsPrefs!!.getInt(KEY_GRID_COLUMNS, DEFAULT_GRID_COLUMNS), 4), GridLayoutManager.HORIZONTAL,false)
// }
binding.appsList.layoutManager = GridLayoutManager(requireContext(), 2, GridLayoutManager.HORIZONTAL,false)
binding.contactList.layoutManager = GridLayoutManager(requireContext(), 2, GridLayoutManager.HORIZONTAL,false)
/* initialize apps list adapter */
@ -377,20 +326,15 @@ internal class AppDrawer : Fragment() {
}
}
}
appQuery = newQ.sort(Pair("clickCount", Sort.DESCENDING),Pair("lastUseDate",Sort.DESCENDING)).limit(20).find()
appQuery = newQ.sort(Pair("clickCount", Sort.DESCENDING),Pair("lastUseDate",Sort.DESCENDING)).limit(18).find()
appQuery?.let {
if(it.size > 0) {
WorkersDb.getRealm().apply {
packageList.clear()
packageList.addAll(copyFromRealm(it))
BLog.LOGE("packageList >>> ${packageList.size}")
binding.appsList.post { if (packageList.size > 0) {
appsAdapter?.updateData(packageList)
} }
// val clo = packageList.clone()
// appNames.clear()
// appNames.addAll(packageList.filter { it.koreanName?.trim()?.length ?: 0 < 1 })
// getHangule()
}
}
}
@ -405,30 +349,22 @@ internal class AppDrawer : Fragment() {
var newQ = query<SimpleContact>()
if (keyword != null && keyword.length > 0) {
if(Pattern.matches("^[0-9]*\$", keyword)){
keyword.split("").forEach {
if (it.length > 0) newQ = newQ.query("phoneNumber CONTAINS $0", keyword)
}
keyword.split("").forEach { if (it.length > 0) newQ = newQ.query("phoneNumber CONTAINS $0", keyword) }
} else {
newQ = newQ.query(
"name CONTAINS $0 OR chosung CONTAINS $0",
keyword
)
newQ = newQ.query("name CONTAINS $0 OR chosung CONTAINS $0", keyword)
}
}
contactQuery = newQ.sort(Pair("touchCount", Sort.DESCENDING),Pair("lastedTouchDateTime",Sort.DESCENDING)).find()
contactQuery = newQ.sort(Pair("touchCount", Sort.DESCENDING),Pair("lastedTouchDateTime",Sort.DESCENDING)).limit(18).find()
contactQuery?.let {
if (it.size > 0)
WorkersDb.getRealm().apply {
contactList.clear()
contactList.addAll(copyFromRealm(it).toList())
BLog.LOGE("packageList >>> ${contactList.size}")
binding.contactList.post { if (contactList.size > 0) {
contactAdapter?.updateData(contactList)
} }
}
}
}
}
@ -469,8 +405,8 @@ internal class AppDrawer : Fragment() {
if(appHangulName?.length ?: 0 > 0) {
info.appNameChosung = JamoUtils.split(appHangulName).joinToString("")
info.koreanName = appHangulName
BLog.LOGE("appHangulName >>> $appHangulName")
BLog.LOGE("appHangulName >>> ${info.appNameChosung}")
// BLog.LOGE("appHangulName >>> $appHangulName")
// BLog.LOGE("appHangulName >>> ${info.appNameChosung}")
WorkersDb.update(info)
getHangule()
}
@ -519,53 +455,9 @@ internal class AppDrawer : Fragment() {
// }
}
var lastSearchStringLength = 0
var lastSearchString : String = ""
private fun filterAppsList(searchString: String) {
/* check each app name and add if it matches the search string */
fetchApps(searchString)
// if (searchString.length > 0 && (lastSearchStringLength != searchString.length || lastSearchString.equals(searchString) == false)) {
// BLog.LOGE("START FILTER")
// packageList.clear()
// for (pkg in oringinPackageList) {
// if (pkg.appName!!.contains(searchString,true) || pkg.category!!.contains(searchString,true) || pkg.pkgName!!.contains(searchString,true)) {
// BLog.LOGE("pkg >>> ${pkg.category} , ${pkg.appName}")
// packageList.add(pkg)
// }
// }
// packageList.sortBy { it.appName }
// BLog.LOGE("MIDDLE FILTER")
//
// appsAdapter?.updateData(packageList)
//
// contactList.clear()
// for (item in originContactList) {
// if (item.name!!.contains(searchString) || item.phoneNumber!!.contains(searchString)) {
// contactList.add(item)
// }
// }
// contactList.sortBy { it.name }
// contactAdapter?.updateData(contactList)
// BLog.LOGE("END FILTER")
//
//
// } else if(lastSearchStringLength == 0){
// contactList.clear()
// for (item in originContactList) {
// contactList.add(item)
// }
// packageList.clear()
// for (resolver in oringinPackageList) {
// packageList.add(resolver)
// }
// appsAdapter?.updateData(packageList)
// contactAdapter?.updateData(contactList)
// } else {
// afterClearSearch()
//
// }
lastSearchString = searchString
lastSearchStringLength = searchString.length
registCancelSearch()
}

View File

@ -50,6 +50,7 @@ import com.google.android.material.button.MaterialButton
import com.google.android.material.button.MaterialButtonToggleGroup
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.gson.Gson
import io.realm.kotlin.ext.query
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
import rasel.lunar.launcher.R
import rasel.lunar.launcher.apps.AppDrawer.Companion.appNamesPrefs
@ -62,7 +63,9 @@ import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_FAVORITE_APPS
import rasel.lunar.launcher.helpers.UniUtils.Companion.copyToClipboard
import rasel.lunar.launcher.helpers.UniUtils.Companion.screenHeight
import rasel.lunar.launcher.helpers.UniUtils.Companion.screenWidth
import rasel.lunar.launcher.model.AppInfo
import rasel.lunar.launcher.utils.BLog
import rasel.lunar.launcher.workers.WorkersDb
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
@ -75,8 +78,8 @@ internal class AppMenu : BottomSheetDialogFragment() {
private lateinit var binding: AppMenuBinding
private lateinit var packageName: String
private lateinit var packageManager: PackageManager
private lateinit var appInfo: ApplicationInfo
private lateinit var defAppName: String
var appInfo: ApplicationInfo? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
binding = AppMenuBinding.inflate(inflater, container, false)
@ -87,16 +90,70 @@ internal class AppMenu : BottomSheetDialogFragment() {
/* get application info */
appInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
packageManager.getApplicationInfo(packageName,
PackageManager.ApplicationInfoFlags.of(PackageManager.GET_META_DATA.toLong()))
try {
packageManager.getApplicationInfo(packageName,
PackageManager.ApplicationInfoFlags.of(PackageManager.GET_META_DATA.toLong()))
}catch (e :Exception) {
null
}
} else {
packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA)
try {
packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA)
}catch (e :Exception) {
null
}
}
if(appInfo == null){
WorkersDb.getRealm().apply {
writeBlocking {
defAppName = ""
var result = query<AppInfo>("pkgName == $0", packageName).find()
if (result.size > 0) {
val app = result.first()
delete(app)
}
}
dismiss()
}
} else {
/* get default app name */
defAppName = packageManager.resolveActivity(
Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER)
.setPackage(packageName), 0
)?.loadLabel(packageManager).toString()
WorkersDb.getRealm().apply {
writeBlocking {
var result = query<AppInfo>("pkgName == $0", packageName).find()
if (result.size > 0) {
val app = result.first()
binding.totalTouch.text = "총 실행 횟수 : ".plus(app.clickCount.toString())
binding.lastTouchDate.text =
"최종 실행 일시 : ".plus(SimpleDateFormat("yyyy-MM-dd HH:mm").format(Date(app.lastUseDate)))
// app.clickCount = app.clickCount + 15
// app.lastUseDate = Math.max(app.lastUseDate, System.currentTimeMillis())
// app.clickCount = app.clickCount + 15
// app.lastUseDate = Math.max(app.lastUseDate, System.currentTimeMillis())
}
}
}
}
/* get default app name */
defAppName = packageManager.resolveActivity(Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER)
.setPackage(packageName), 0)?.loadLabel(packageManager).toString()
fun update() {
WorkersDb.getRealm().apply {
writeBlocking {
var result = query<AppInfo>("pkgName == $0",packageName).find()
if(result.size > 0) {
val app = result.first()
app.clickCount = app.clickCount + 15
}
}
}
}
binding.totalTouch.setOnClickListener { update() }
binding.lastTouchDate.setOnClickListener { update() }
/* set application name and package name */
binding.appName.apply {
setText(appNamesPrefs?.getString(packageName, defAppName))
@ -104,9 +161,6 @@ internal class AppMenu : BottomSheetDialogFragment() {
}
binding.appPackage.text = packageName
/* favorite apps */
favoriteApps()
return binding.root
}
@ -129,56 +183,7 @@ internal class AppMenu : BottomSheetDialogFragment() {
binding.appUninstall.setOnClickListener { uninstall() }
}
/* manage initial preview and clicks for favorite apps */
@SuppressLint("PrivateResource")
private fun favoriteApps() {
val sharedPreferences = requireContext().getSharedPreferences(PREFS_FAVORITE_APPS, 0)
val enabledStroke =
ColorStateList.valueOf(requireContext().getColor(com.google.android.material.R.color.material_on_surface_stroke))
val disabledStroke =
ColorStateList.valueOf(requireContext().getColor(com.google.android.material.R.color.m3_chip_stroke_color))
for (position in 1..MAX_FAVORITE_APPS) {
val button = outlinedButton
val savedPackageName = sharedPreferences.getString(KEY_APP_NO_ + position, "")
/* set previews */
if (packageName == savedPackageName) button.isChecked = true
if (savedPackageName?.isNotEmpty() == true) button.strokeColor = enabledStroke
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
packageManager.getPackageInfo(savedPackageName!!, PackageManager.PackageInfoFlags.of(0))
else
packageManager.getPackageInfo(savedPackageName!!, 0)
} catch (e: PackageManager.NameNotFoundException) {
requireContext().getSharedPreferences(PREFS_FAVORITE_APPS, 0)
.edit().remove(KEY_APP_NO_ + position).apply()
button.strokeColor = disabledStroke
e.printStackTrace()
}
/* listen on clicks */
binding.favGroup.addOnButtonCheckedListener { _: MaterialButtonToggleGroup?,
checkedId: Int, isChecked: Boolean ->
try {
if (checkedId == button.id) {
if (isChecked) {
requireContext().getSharedPreferences(PREFS_FAVORITE_APPS, 0)
.edit().putString(KEY_APP_NO_ + position, packageName).apply()
button.strokeColor = enabledStroke
} else {
requireContext().getSharedPreferences(PREFS_FAVORITE_APPS, 0)
.edit().remove(KEY_APP_NO_ + position).apply()
button.strokeColor = disabledStroke
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}
private fun appName() {
binding.appName.setOnFocusChangeListener { _, hasFocus ->
@ -221,26 +226,28 @@ internal class AppMenu : BottomSheetDialogFragment() {
.setPositiveButton(android.R.string.cancel, null)
.show()
/* show app name */
dialogBinding.appName.text = packageManager.getApplicationLabel(appInfo)
appInfo?.let { appInfo ->
dialogBinding.appName.text = packageManager.getApplicationLabel(appInfo)
/* get package info */
val packageInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
packageManager.getPackageInfo(packageName, PackageManager.PackageInfoFlags.of(0))
} else {
packageManager.getPackageInfo(packageName, 0)
/* get package info */
val packageInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
packageManager.getPackageInfo(packageName, PackageManager.PackageInfoFlags.of(0))
} else {
packageManager.getPackageInfo(packageName, 0)
}
/* show infos */
dialogBinding.mixed.text =
"${resources.getString(R.string.version)}: ${packageInfo.versionName} (${PackageInfoCompat.getLongVersionCode(packageInfo).toInt()})\n" +
"${resources.getString(R.string.sdk)}: ${appInfo.minSdkVersion} ~ ${appInfo.targetSdkVersion}\n" +
"${resources.getString(R.string.uid)}: ${appInfo.uid}\n" +
"${resources.getString(R.string.first_install)}: ${dateTimeFormat(packageInfo.firstInstallTime)}\n" +
"${resources.getString(R.string.last_update)}: ${dateTimeFormat(packageInfo.lastUpdateTime)}"
/* show permissions */
dialogBinding.permissions.text = permissionsList
}
/* show infos */
dialogBinding.mixed.text =
"${resources.getString(R.string.version)}: ${packageInfo.versionName} (${PackageInfoCompat.getLongVersionCode(packageInfo).toInt()})\n" +
"${resources.getString(R.string.sdk)}: ${appInfo.minSdkVersion} ~ ${appInfo.targetSdkVersion}\n" +
"${resources.getString(R.string.uid)}: ${appInfo.uid}\n" +
"${resources.getString(R.string.first_install)}: ${dateTimeFormat(packageInfo.firstInstallTime)}\n" +
"${resources.getString(R.string.last_update)}: ${dateTimeFormat(packageInfo.lastUpdateTime)}"
/* show permissions */
dialogBinding.permissions.text = permissionsList
}
/* activity browser dialog */
@ -251,51 +258,55 @@ internal class AppMenu : BottomSheetDialogFragment() {
.setPositiveButton(android.R.string.cancel, null)
.show()
/* show app name */
dialogBinding.appName.text = packageManager.getApplicationLabel(appInfo)
appInfo?.let { appInfo ->
/* get activity info */
val activityInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
packageManager.getPackageInfo(
packageName, PackageManager.PackageInfoFlags.of(PackageManager.GET_ACTIVITIES.toLong())
)
} else {
packageManager.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES)
}
BLog.LOGE("activity. >>>>> ${Gson().toJson(activityInfo)}")
/* show activity list */
val activityAdapter: ArrayAdapter<String> =
ArrayAdapter(requireContext(), R.layout.list_item, R.id.itemText, ArrayList())
if (activityInfo.activities.isNotEmpty()) {
for (activity in activityInfo.activities) {
if (packageName.contains("com.kakao") == true) {
BLog.LOGE("activity. >>>>> ${Gson().toJson(activity)}")
}
activityAdapter.add(
activity.toString().split(" ").toTypedArray()[1].replace("}", "")
/* show app name */
dialogBinding.appName.text = packageManager.getApplicationLabel(appInfo)
/* get activity info */
val activityInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
packageManager.getPackageInfo(
packageName, PackageManager.PackageInfoFlags.of(PackageManager.GET_ACTIVITIES.toLong())
)
} else {
packageManager.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES)
}
dialogBinding.activityList.adapter = activityAdapter
}
/* listen item clicks */
dialogBinding.activityList.onItemClickListener =
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, i: Int, _: Long ->
try {
/* open activity */
val intent = Intent()
intent.component = ComponentName(packageName, activityAdapter.getItem(i).toString())
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
requireContext().startActivity(intent)
} catch (exception: Exception) {
/* couldn't open activity */
exception.printStackTrace()
val exceptionShort = (exception.toString().split(": ").toTypedArray())[0]
Toast.makeText(requireContext(),
"${resources.getString(R.string.unable_to_launch)} -\n$exceptionShort", Toast.LENGTH_LONG).show()
// BLog.LOGE("activity. >>>>> ${Gson().toJson(activityInfo)}")
/* show activity list */
val activityAdapter: ArrayAdapter<String> =
ArrayAdapter(requireContext(), R.layout.list_item, R.id.itemText, ArrayList())
if (activityInfo.activities.isNotEmpty()) {
for (activity in activityInfo.activities) {
if (packageName.contains("com.kakao") == true) {
// BLog.LOGE("activity. >>>>> ${Gson().toJson(activity)}")
}
activityAdapter.add(
activity.toString().split(" ").toTypedArray()[1].replace("}", "")
)
}
dialogBuilder.dismiss()
dialogBinding.activityList.adapter = activityAdapter
}
/* listen item clicks */
dialogBinding.activityList.onItemClickListener =
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, i: Int, _: Long ->
try {
/* open activity */
val intent = Intent()
intent.component = ComponentName(packageName, activityAdapter.getItem(i).toString())
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
requireContext().startActivity(intent)
} catch (exception: Exception) {
/* couldn't open activity */
exception.printStackTrace()
val exceptionShort = (exception.toString().split(": ").toTypedArray())[0]
Toast.makeText(requireContext(),
"${resources.getString(R.string.unable_to_launch)} -\n$exceptionShort", Toast.LENGTH_LONG).show()
}
dialogBuilder.dismiss()
}
}
}
/* open app's page in app store/market */
@ -337,35 +348,42 @@ internal class AppMenu : BottomSheetDialogFragment() {
private fun share() {
try {
// Create a temporary file to copy the APK
val apkLabel = packageManager.getApplicationLabel(appInfo).toString().lowercase().replace(" ", "_")
val tempApkFile = File(requireContext().externalCacheDir, "$apkLabel.apk")
appInfo?.let { appInfo ->
// Create a temporary file to copy the APK
val apkLabel = packageManager.getApplicationLabel(appInfo).toString().lowercase()
.replace(" ", "_")
val tempApkFile = File(requireContext().externalCacheDir, "$apkLabel.apk")
// Copy the APK file
FileInputStream(File(appInfo.sourceDir)).use { `in` ->
FileOutputStream(tempApkFile).use { out ->
val buffer = ByteArray(1024)
var length: Int
while (`in`.read(buffer).also { length = it } > 0) {
out.write(buffer, 0, length)
// Copy the APK file
FileInputStream(File(appInfo.sourceDir)).use { `in` ->
FileOutputStream(tempApkFile).use { out ->
val buffer = ByteArray(1024)
var length: Int
while (`in`.read(buffer).also { length = it } > 0) {
out.write(buffer, 0, length)
}
}
}
}
// Generate a content URI using FileProvider
val contentUri =
FileProvider.getUriForFile(requireContext(), "${requireContext().packageName}.fileprovider", tempApkFile)
// Generate a content URI using FileProvider
val contentUri =
FileProvider.getUriForFile(
requireContext(),
"${requireContext().packageName}.fileprovider",
tempApkFile
)
//requireContext().grantUriPermission(receivers.package.name, contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
//requireContext().grantUriPermission(receivers.package.name, contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
// Create a Share Intent
Intent(Intent.ACTION_SEND).apply {
type = "application/vnd.android.package-archive"
putExtra(Intent.EXTRA_STREAM, contentUri)
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}.let {
// Start the chooser activity
startActivity(Intent.createChooser(it, getString(R.string.share_apk_message)))
// Create a Share Intent
Intent(Intent.ACTION_SEND).apply {
type = "application/vnd.android.package-archive"
putExtra(Intent.EXTRA_STREAM, contentUri)
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}.let {
// Start the chooser activity
startActivity(Intent.createChooser(it, getString(R.string.share_apk_message)))
}
}
}
catch (e: PackageManager.NameNotFoundException) { e.printStackTrace() }
@ -382,18 +400,6 @@ internal class AppMenu : BottomSheetDialogFragment() {
this.dismiss()
}
/* create and add an outlined button to the toggle group */
private val outlinedButton: MaterialButton get() {
val style = com.google.android.material.R.attr.materialButtonOutlinedStyle
val button = MaterialButton(requireContext(), null, style)
button.layoutParams = LinearLayoutCompat.LayoutParams(
LinearLayoutCompat.LayoutParams.WRAP_CONTENT,
LinearLayoutCompat.LayoutParams.WRAP_CONTENT, 1F
)
binding.favGroup.addView(button)
return button
}
/* long value to local date-time format */
private fun dateTimeFormat(long: Long) : String = SimpleDateFormat.getDateTimeInstance().format(Date(long))

View File

@ -93,6 +93,16 @@ internal class AppsAdapter(
/* on long click - open app menu */
setOnLongClickListener {
WorkersDb.getRealm().apply {
writeBlocking {
var result = query<AppInfo>("pkgName == $0",item.pkgName).find()
if(result.size > 0) {
val app = result.first()
app.clickCount = app.clickCount + 15
// app.lastUseDate = Math.max(app.lastUseDate, System.currentTimeMillis())
}
}
}
AppMenu().apply {
}.show(fragmentManager, item.pkgName)
true

View File

@ -18,65 +18,63 @@
package rasel.lunar.launcher.apps
import android.annotation.SuppressLint
import android.app.ActivityOptions
import android.content.ActivityNotFoundException
import android.content.ComponentName
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.content.res.ColorStateList
import android.graphics.Rect
import android.icu.text.SimpleDateFormat
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.ContactsContract
import android.provider.Settings
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.Toast
import androidx.appcompat.widget.LinearLayoutCompat
import androidx.core.content.FileProvider
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.android.material.button.MaterialButton
import com.google.android.material.button.MaterialButtonToggleGroup
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import io.realm.kotlin.ext.query
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
import rasel.lunar.launcher.R
import rasel.lunar.launcher.databinding.ActivityBrowserDialogBinding
import rasel.lunar.launcher.databinding.ContactMenuBinding
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_APP_NO_
import rasel.lunar.launcher.helpers.Constants.Companion.MAX_FAVORITE_APPS
import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_FAVORITE_APPS
import rasel.lunar.launcher.helpers.UniUtils.Companion.screenHeight
import rasel.lunar.launcher.helpers.UniUtils.Companion.screenWidth
import rasel.lunar.launcher.utils.BLog
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException
import rasel.lunar.launcher.workers.WorkersDb
import java.text.SimpleDateFormat
import java.util.Date
internal class ContactMenu : BottomSheetDialogFragment() {
private lateinit var binding: ContactMenuBinding
private lateinit var packageName: String
private lateinit var packageManager: PackageManager
private lateinit var appInfo: ApplicationInfo
private lateinit var defAppName: String
private lateinit var contactId: String
var contactName : String = ""
var contactPhoneNumber : String = ""
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
binding = ContactMenuBinding.inflate(inflater, container, false)
/* get package name from fragment's tag */
packageName = tag.toString()
contactId = tag.toString()
WorkersDb.getRealm().writeBlocking {
if (contactId != null && contactId.length ?: 0 > 0) {
val result = query<SimpleContact>().query("id == $0", contactId).find()
if(result.size > 0){
var contact = result.first()
binding.totalTouch.text = "총 연락 횟수 : ".plus(contact.touchCount.toString())
binding.lastTouchDate.text = "마지막 연락 시간 : ".plus(SimpleDateFormat("yyyy-MM-dd HH:mm").format(Date(contact.lastedTouchDateTime)))
}
}
}
fun update() {
WorkersDb.getRealm().writeBlocking {
if (contactId != null && contactId.length ?: 0 > 0) {
val result = query<SimpleContact>().query("id == $0", contactId).find()
if(result.size > 0){
var contact = result.first()
contact.touchCount = contact.touchCount + 15
}
}
}
}
binding.totalTouch.setOnClickListener { update() }
binding.lastTouchDate.setOnClickListener { update() }
val resolver = lActivity!!.contentResolver
val phoneUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI
val projection = arrayOf(
@ -84,9 +82,9 @@ internal class ContactMenu : BottomSheetDialogFragment() {
ContactsContract.CommonDataKinds.Phone.NUMBER,
)
BLog.LOGE("GetContact", "packageName ${packageName}")
BLog.LOGE("GetContact", "packageName ${contactId}")
try {
val cursor = resolver.query(phoneUri, projection, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + packageName, null , null)
val cursor = resolver.query(phoneUri, projection, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId, null , null)
if (cursor != null) {
while (cursor.moveToNext()) {
val nameIndex = cursor.getColumnIndex(projection[0])
@ -120,6 +118,8 @@ internal class ContactMenu : BottomSheetDialogFragment() {
//
appName()
binding.detailedInfo.setOnClickListener { detailedInfo() }
binding.call.setOnClickListener { callPhone() }
binding.sms.setOnClickListener { sendSms() }
// binding.activityBrowser.setOnClickListener { activityBrowser() }
// binding.appStore.setOnClickListener { appStore() }
// binding.appFreeform.setOnClickListener { freeform() }
@ -128,56 +128,7 @@ internal class ContactMenu : BottomSheetDialogFragment() {
// binding.appUninstall.setOnClickListener { uninstall() }
}
/* manage initial preview and clicks for favorite apps */
@SuppressLint("PrivateResource")
private fun favoriteApps() {
val sharedPreferences = requireContext().getSharedPreferences(PREFS_FAVORITE_APPS, 0)
val enabledStroke =
ColorStateList.valueOf(requireContext().getColor(com.google.android.material.R.color.material_on_surface_stroke))
val disabledStroke =
ColorStateList.valueOf(requireContext().getColor(com.google.android.material.R.color.m3_chip_stroke_color))
for (position in 1..MAX_FAVORITE_APPS) {
val button = outlinedButton
val savedPackageName = sharedPreferences.getString(KEY_APP_NO_ + position, "")
/* set previews */
if (packageName == savedPackageName) button.isChecked = true
if (savedPackageName?.isNotEmpty() == true) button.strokeColor = enabledStroke
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
packageManager.getPackageInfo(savedPackageName!!, PackageManager.PackageInfoFlags.of(0))
else
packageManager.getPackageInfo(savedPackageName!!, 0)
} catch (e: PackageManager.NameNotFoundException) {
requireContext().getSharedPreferences(PREFS_FAVORITE_APPS, 0)
.edit().remove(KEY_APP_NO_ + position).apply()
button.strokeColor = disabledStroke
e.printStackTrace()
}
/* listen on clicks */
binding.favGroup.addOnButtonCheckedListener { _: MaterialButtonToggleGroup?,
checkedId: Int, isChecked: Boolean ->
try {
if (checkedId == button.id) {
if (isChecked) {
requireContext().getSharedPreferences(PREFS_FAVORITE_APPS, 0)
.edit().putString(KEY_APP_NO_ + position, packageName).apply()
button.strokeColor = enabledStroke
} else {
requireContext().getSharedPreferences(PREFS_FAVORITE_APPS, 0)
.edit().remove(KEY_APP_NO_ + position).apply()
button.strokeColor = disabledStroke
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}
private fun appName() {
binding.appName.text = contactName
@ -187,195 +138,21 @@ internal class ContactMenu : BottomSheetDialogFragment() {
private fun detailedInfo() {
var intent = Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(ContactsContract.Contacts.CONTENT_URI.toString() + "/" + packageName));
intent.setData(Uri.parse(ContactsContract.Contacts.CONTENT_URI.toString() + "/" + contactId));
startActivity(intent);
}
/* activity browser dialog */
private fun activityBrowser() {
val dialogBinding = ActivityBrowserDialogBinding.inflate(lActivity!!.layoutInflater)
val dialogBuilder = MaterialAlertDialogBuilder(lActivity!!)
.setView(dialogBinding.root)
.setPositiveButton(android.R.string.cancel, null)
.show()
/* show app name */
dialogBinding.appName.text = packageManager.getApplicationLabel(appInfo)
/* get activity info */
val activityInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
packageManager.getPackageInfo(
packageName, PackageManager.PackageInfoFlags.of(PackageManager.GET_ACTIVITIES.toLong())
)
} else {
packageManager.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES)
}
/* show activity list */
val activityAdapter: ArrayAdapter<String> =
ArrayAdapter(requireContext(), R.layout.list_item, R.id.itemText, ArrayList())
if (activityInfo.activities.isNotEmpty()) {
for (activity in activityInfo.activities) {
activityAdapter.add(
activity.toString().split(" ").toTypedArray()[1].replace("}", "")
)
}
dialogBinding.activityList.adapter = activityAdapter
}
/* listen item clicks */
dialogBinding.activityList.onItemClickListener =
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, i: Int, _: Long ->
try {
/* open activity */
val intent = Intent()
intent.component = ComponentName(packageName, activityAdapter.getItem(i).toString())
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
requireContext().startActivity(intent)
} catch (exception: Exception) {
/* couldn't open activity */
exception.printStackTrace()
val exceptionShort = (exception.toString().split(": ").toTypedArray())[0]
Toast.makeText(requireContext(),
"${resources.getString(R.string.unable_to_launch)} -\n$exceptionShort", Toast.LENGTH_LONG).show()
}
dialogBuilder.dismiss()
}
private fun sendSms() {
var intent = Intent(Intent.ACTION_SEND);
intent.setData(Uri.parse("smsto:" + contactPhoneNumber));
startActivity(intent);
}
private fun callPhone() {
var intent = Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:" + contactPhoneNumber));
startActivity(intent);
}
/* open app's page in app store/market */
private fun appStore() {
try {
val storeIntent = Intent(Intent.ACTION_VIEW)
storeIntent.data = Uri.parse("market://details?id=$packageName")
storeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
requireContext().startActivity(storeIntent)
} catch (activityNotFoundException: ActivityNotFoundException) {
/* no app store found exception */
Toast.makeText(requireContext(), requireContext().getString(R.string.null_app_store_message),
Toast.LENGTH_SHORT).show()
activityNotFoundException.printStackTrace()
}
this.dismiss()
}
/* launch app as a freeform window */
private fun freeform() {
val freeformIntent = requireContext().packageManager.getLaunchIntentForPackage(packageName)
freeformIntent!!.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT or
Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
val rect = Rect(0, screenHeight / 2, screenWidth, screenHeight)
var activityOptions = activityOptions
activityOptions = activityOptions.setLaunchBounds(rect)
requireContext().startActivity(freeformIntent, activityOptions.toBundle())
this.dismiss()
}
/* open android's app info screen */
private fun appInfo() {
val infoIntent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
infoIntent.data = Uri.parse("package:$packageName")
infoIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
requireContext().startActivity(infoIntent)
this.dismiss()
}
private fun share() {
try {
// Create a temporary file to copy the APK
val apkLabel = packageManager.getApplicationLabel(appInfo).toString().lowercase().replace(" ", "_")
val tempApkFile = File(requireContext().externalCacheDir, "$apkLabel.apk")
// Copy the APK file
FileInputStream(File(appInfo.sourceDir)).use { `in` ->
FileOutputStream(tempApkFile).use { out ->
val buffer = ByteArray(1024)
var length: Int
while (`in`.read(buffer).also { length = it } > 0) {
out.write(buffer, 0, length)
}
}
}
// Generate a content URI using FileProvider
val contentUri =
FileProvider.getUriForFile(requireContext(), "${requireContext().packageName}.fileprovider", tempApkFile)
//requireContext().grantUriPermission(receivers.package.name, contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
// Create a Share Intent
Intent(Intent.ACTION_SEND).apply {
type = "application/vnd.android.package-archive"
putExtra(Intent.EXTRA_STREAM, contentUri)
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}.let {
// Start the chooser activity
startActivity(Intent.createChooser(it, getString(R.string.share_apk_message)))
}
}
catch (e: PackageManager.NameNotFoundException) { e.printStackTrace() }
catch (e: IOException) { e.printStackTrace() }
this.dismiss()
}
/* uninstall the app */
private fun uninstall() {
val uninstallIntent = Intent(Intent.ACTION_DELETE)
uninstallIntent.data = Uri.parse("package:$packageName")
uninstallIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
requireContext().startActivity(uninstallIntent)
this.dismiss()
}
/* create and add an outlined button to the toggle group */
private val outlinedButton: MaterialButton get() {
val style = com.google.android.material.R.attr.materialButtonOutlinedStyle
val button = MaterialButton(requireContext(), null, style)
button.layoutParams = LinearLayoutCompat.LayoutParams(
LinearLayoutCompat.LayoutParams.WRAP_CONTENT,
LinearLayoutCompat.LayoutParams.WRAP_CONTENT, 1F
)
binding.favGroup.addView(button)
return button
}
/* long value to local date-time format */
private fun dateTimeFormat(long: Long) : String = SimpleDateFormat.getDateTimeInstance().format(Date(long))
/* get and arrange all the permissions for an application */
private val permissionsList : String get() {
val packageInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
packageManager.getPackageInfo(packageName, PackageManager.PackageInfoFlags.of(PackageManager.GET_PERMISSIONS.toLong()))
} else {
packageManager.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS)
}
return if (packageInfo.requestedPermissions.isNotEmpty()) {
val stringBuilder = StringBuilder()
packageInfo.requestedPermissions.indices.forEach { i: Int ->
if (i != packageInfo.requestedPermissions.size - 1)
stringBuilder.append("${packageInfo.requestedPermissions[i]}\n\n")
/* don't add any new line after the last entry */
else
stringBuilder.append(packageInfo.requestedPermissions[i])
}
stringBuilder.toString()
} else {
""
}
}
/* get activity options for launching app in freeform mode */
private val activityOptions: ActivityOptions get() {
val activityOptions = ActivityOptions.makeBasic()
try {
val method =
ActivityOptions::class.java.getMethod("setLaunchWindowingMode", Int::class.javaPrimitiveType)
method.invoke(activityOptions, 5)
} catch (exception: Exception) {
exception.printStackTrace()
}
return activityOptions
}
}

View File

@ -69,12 +69,12 @@ internal class IconPackManager {
val appFilterId = iconPackRes!!.getIdentifier("appfilter", "xml", packageName)
if (appFilterId > 0) {
xpp = iconPackRes!!.getXml(appFilterId)
BLog.LOGE("packageName >>> ${packageName}")
// BLog.LOGE("packageName >>> ${packageName}")
} else {
try {
xpp = XmlPullParserFactory.newInstance().apply { isNamespaceAware = true }
.newPullParser().apply {
BLog.LOGE("packageName >>> ${packageName}")
// BLog.LOGE("packageName >>> ${packageName}")
setInput(iconPackRes!!.assets.open("appfilter.xml"), "utf-8")
}
} catch (e: IOException) {

View File

@ -50,6 +50,8 @@ import com.google.android.material.button.MaterialButtonToggleGroup
import com.google.gson.Gson
import io.realm.kotlin.ext.query
import io.realm.kotlin.query.Sort
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
@ -58,10 +60,12 @@ import org.jsoup.Jsoup
import rasel.lunar.launcher.CommadCallabck
import rasel.lunar.launcher.LauncherActivity.Companion.appWidgetHost
import rasel.lunar.launcher.LauncherActivity.Companion.appWidgetManager
import rasel.lunar.launcher.LauncherActivity.Companion.getCal
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
import rasel.lunar.launcher.LauncherActivity.Companion.refreshDeviceData
import rasel.lunar.launcher.LauncherActivity.Companion.refreshFeeds
import rasel.lunar.launcher.R
import rasel.lunar.launcher.apps.ContactMenu
import rasel.lunar.launcher.databinding.FeedsBinding
import rasel.lunar.launcher.feeds.rss.RssAdapter
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_WIDGET_HEIGHTS
@ -70,6 +74,7 @@ import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_WIDGETS
import rasel.lunar.launcher.helpers.Constants.Companion.SEPARATOR
import rasel.lunar.launcher.helpers.Constants.Companion.requestCreateWidget
import rasel.lunar.launcher.helpers.Constants.Companion.requestPickWidget
import rasel.lunar.launcher.helpers.PrefHelper
import rasel.lunar.launcher.home.LauncherHome.Companion.home
import rasel.lunar.launcher.home.LauncherHome.Companion.lastedFinishedPageUrl
import rasel.lunar.launcher.home.LauncherHome.Companion.listTags
@ -82,6 +87,7 @@ import rasel.lunar.launcher.model.jGuruTag
import rasel.lunar.launcher.model.dateFormat
import rasel.lunar.launcher.model.getRssData
import rasel.lunar.launcher.utils.BLog
import rasel.lunar.launcher.utils.FeedParseManager
import rasel.lunar.launcher.utils.JamoUtils
import rasel.lunar.launcher.utils.RssList.jGuruMain
import rasel.lunar.launcher.utils.USAGT
@ -93,6 +99,7 @@ import rasel.lunar.launcher.workers.WorkersDb
import java.net.URLEncoder
import java.nio.charset.Charset
import java.text.SimpleDateFormat
import java.util.Base64
import java.util.Date
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
@ -175,11 +182,10 @@ internal class Feeds : Fragment() , CommadCallabck {
mMainHandler.removeCallbacks(hideConsole)
binding.consoleLog.post {
binding.consoleLog.visibility = View.VISIBLE
binding.consoleLog.text = str
binding.consoleLog.text = binding.consoleLog.text.toString() + "\n" + str
}
mMainHandler.postDelayed(hideConsole,10000L)
BLog.LOGE("consoleLog >>>> ${str}")
}
fun openOpera(schemeString : String) {
@ -224,20 +230,39 @@ internal class Feeds : Fragment() , CommadCallabck {
builder.setPositiveButton(android.R.string.ok,
DialogInterface.OnClickListener { dialog, which ->
dialog.dismiss()
BLog.LOGE("input.text.toString() >>>> ${input.text.toString()}")
consoleLog("input.text.toString() >>>> ${input.text.toString()}")
if (input.text.toString().trim().contains(" ")) {
val cmd = input.text.toString().trim().split(" ")
when(cmd[0]) {
"so"-> {
CoroutineScope(Dispatchers.IO).launch {
consoleLog("${cmd[0]} Start ${cmd[1]}")
String.format(String(Base64.getMimeDecoder().decode("aHR0cHM6Ly9rciVzLnNvZ2lybC5zby8=".toByteArray())),cmd[1]).getJ().let { doc -> FeedParseManager.parse(doc){consoleLog(it)} }
consoleLog("current j req() ${WorkersDb.getRealm().query<RssData>("category == $0", RssDataType.GURU.name).find().size}")
consoleLog("${cmd[0]} END ${cmd[1]}")
}
}
"s" -> {
home?.queryInfos(keyword = cmd[1])
}
"jf" -> {
consoleLog("on Cmd JF")
GlobalScope.launch { excuteGetterMostByUrl("https://javmost.to/search/movie/${cmd[1]}") }
CoroutineScope(Dispatchers.IO).launch {
consoleLog("${cmd[0]} Start ${cmd[1]}")
String.format(String(Base64.getMimeDecoder().decode("aHR0cHM6Ly9qYXZtb3N0LnRvL3NlYXJjaC9tb3ZpZS8lcw==".toByteArray())),cmd[1]).getJ().let { doc -> FeedParseManager.parse(doc){consoleLog(it)} }
consoleLog("current j req() ${WorkersDb.getRealm().query<RssData>("category == $0", RssDataType.GURU.name).find().size}")
consoleLog("${cmd[0]} END ${cmd[1]}")
}
CoroutineScope(Dispatchers.IO).launch {
consoleLog("on Cmd JF with SO")
consoleLog("${cmd[0]} Start ${cmd[1]}")
String.format(String(Base64.getMimeDecoder().decode("aHR0cHM6Ly9rcjcwLnNvZ2lybC5zby8/cz0lcw==".toByteArray())),cmd[1]).getJ().let { doc -> FeedParseManager.parse(doc){consoleLog(it)} }
consoleLog("current j req() ${WorkersDb.getRealm().query<RssData>("category == $0", RssDataType.GURU.name).find().size}")
consoleLog("${cmd[0]} END ${cmd[1]}")
}
}
"mgn"-> {
// lActivity?.doWebParseStart("https://cili.site/search?q=${URLEncoder.encode(cmd[1], Charset.defaultCharset().name())}") {}
GlobalScope.launch {
CoroutineScope(Dispatchers.IO).launch {
var temp = arrayListOf<CiliMagnet>()
consoleLog("this >>>> cili ${cmd[0]} -> ${cmd[1]}")
Jsoup.connect("https://cili.site/search?q=${URLEncoder.encode(cmd[1], Charset.defaultCharset().name())}").get().let { cili ->
@ -253,8 +278,6 @@ internal class Feeds : Fragment() , CommadCallabck {
if (mgn_Page.getElementsByClass("input-group magnet-box").size > 0) {
mgn_Page.getElementsByClass("input-group magnet-box")
.get(0)?.let { magnet_box ->
// BLog.LOGE("magnet_box >>> ${magnet_box}")
// if (magnet_box.getElementById("input-magnet").size > 0) {
magnet_box.getElementById(
"input-magnet"
)?.let { input_magnet ->
@ -277,48 +300,19 @@ internal class Feeds : Fragment() , CommadCallabck {
}
}.start()
}
}
binding.expandRss.isChecked = false
} else {
when (input.text.toString()) {
"so" -> GlobalScope.launch {
"https://kr69.sogirl.so".getJ().let { doc ->
BLog.LOGE("ogirl >>> ${doc.title()}")
doc.getElementsByTag("article").forEach { article ->
BLog.LOGE("ogirl article >>> ${article.text()}")
val title = article.getElementsByTag("a").get(0).attr("title")
val href = article.getElementsByTag("a").get(0).attr("href")
val img = article.getElementsByTag("img").get(0).attr("data-src")
WorkersDb.getRealm().writeBlocking {
if (query<RssData>("originPage == $0", href).find().size == 0) {
RssData().apply {
this.originPage = href
this.title = title
this.description = "Sogirl"
this.thumbnail = img
this.pubDate = Date().time
this.category = RssDataType.GURU.name
this.chosung =
JamoUtils.split(title).joinToString("")
copyToRealm(this)
}
}
}
}
}
consoleLog("current j req() ${WorkersDb.getRealm()
.query<RssData>("category == $0", RssDataType.GURU.name).find().size}")
val urls = arrayOf("https://javmost.to/latest-updates",
"https://javmost.to/latest-updates/page-2",
"https://javmost.to/latest-updates/page-3",
"https://javmost.to/latest-updates/page-4",
"https://javmost.to/latest-updates/page-5")
urls.forEach { mostUrl ->
GlobalScope.launch {
excuteGetterMostByUrl(mostUrl)
}.start()
}
"loc_ck" -> {
FeedsResult().show(parentFragmentManager, "")
}
"loc_on" -> {
PrefHelper.location(!PrefHelper.isLocationOn())
consoleLog("PrefHelper.isLocationOn() >>> ${PrefHelper.isLocationOn()}")
}
"cal" ->{
getCal()
}
"ojs" -> home?.queryInfos(arrayListOf<RssDataType>().apply {
addAll(RssDataType.values())
@ -336,8 +330,6 @@ internal class Feeds : Fragment() , CommadCallabck {
addAll(RssDataType.values())
remove(RssDataType.REDDIT)
})
"req" -> {
refreshFeeds()
refreshDeviceData()
@ -375,7 +367,6 @@ internal class Feeds : Fragment() , CommadCallabck {
refresh.visibility = View.GONE
}
}
"jjp" -> {
// lActivity?.doWebParseStart("https://projectjav.com") {}
}
@ -398,10 +389,6 @@ internal class Feeds : Fragment() , CommadCallabck {
.query<RssData>("category == $0", RssDataType.GURU.name).find().size}")
}
})
// {
// consoleLog("excuted j req() ${WorkersDb.getRealm()
// .query<RssData>("category == $0", RssDataType.GURU.name).find().size}")
// }
}
"jtag" -> {
@ -493,72 +480,6 @@ internal class Feeds : Fragment() , CommadCallabck {
}
}
var dmy = SimpleDateFormat("dd-MM-yyyy")
fun excuteGetterMostByUrl(mostUrl : String) {
Executors.newSingleThreadScheduledExecutor().schedule({
Jsoup.connect(mostUrl).userAgent(USAGT).get().let { doc ->
onConsoleLog("$lastedFinishedPageUrl >>> ${doc.title()}")
doc.getElementsByClass("card").forEach { card ->
onConsoleLog("${lastedFinishedPageUrl}_card >>> ${card}")
var thumb = if(card.getElementsByTag("img").size > 0) card.getElementsByTag("img").get(0).attr("src") else ""
if (thumb.contains("No+Poster")) thumb = if(card.getElementsByTag("img").size > 0) card.getElementsByTag("img").get(0).attr("data-src") else thumb
var model = if(card.getElementsByTag("img").size > 0) card.getElementsByTag("img").get(0).attr("alt") else ""
var title = ""
var date = ""
var link = ""
if(card.getElementsByClass("card-block").size > 0) if(card.getElementsByClass("card-block").size > 0) {
link = card.getElementsByClass("card-block").get(0).getElementsByTag("a").get(0).attr("href")
title = card.getElementsByClass("card-block").get(0).getElementsByTag("a").get(0).attr("title")
date = card.getElementsByTag("span").get(0).text()
}
MostItem().let { ms ->
ms.model = model
ms.image = thumb
ms.pageLink = link
ms.title = title
try {
ms.date = dmy.parse(date).time
consoleLog("dateFormat.format(Date(ms.date)) ${dateFormat.format(Date(ms.date))}")
}catch (e : Exception) {e.printStackTrace()}
if (ms.isValid()) {
WorkersDb.insertData(ms.getRssData())
}
}
onConsoleLog("" +
"model >>>>> ${model}\n" +
"thumb >>>>> ${thumb}\n" +
"title >>>>> ${title}\n" +
"date >>>>> ${date}" +
"")
}
consoleLog("excuted j req() ${WorkersDb.getRealm()
.query<RssData>("category == $0", RssDataType.GURU.name).find().size}")
}
}, 1500, TimeUnit.MILLISECONDS)
}
/* rss service's result receiver */
@Suppress("UNCHECKED_CAST")
private val resultReceiver: ResultReceiver = object : ResultReceiver(Handler(Looper.getMainLooper())) {
// override fun onReceiveResult(resultCode: Int, resultData: Bundle) {
// when (val items = resultData.getSerializable(RSS_ITEMS) as List<Rss>?) {
// null -> resumeService()
// else -> {
// binding.feedsRss.apply {
// if(rss.adapter != null) {
// (rss.adapter as RssAdapter).items.addAll(items)
// }
// refresh.visibility = View.GONE
// loading.visibility = View.GONE
// rss.visibility = View.VISIBLE
// }
// }
// }
// }
}
private fun systemInfo() {
viewLifecycleOwner.lifecycleScope.launch {

View File

@ -0,0 +1,81 @@
package rasel.lunar.launcher.feeds
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.FragmentManager
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.gson.Gson
import io.realm.kotlin.ext.query
import rasel.lunar.launcher.BuildConfig
import rasel.lunar.launcher.apps.DismissCalback
import rasel.lunar.launcher.databinding.FeedsResultMenuBinding
import rasel.lunar.launcher.databinding.SearchMenuBinding
import rasel.lunar.launcher.model.LocationLog
import rasel.lunar.launcher.utils.BLog
import rasel.lunar.launcher.workers.WorkersDb
import java.text.SimpleDateFormat
import java.util.Date
internal class FeedsResult : BottomSheetDialogFragment() {
private lateinit var binding: FeedsResultMenuBinding
private lateinit var searchWord: String
private lateinit var packageManager: PackageManager
private lateinit var appInfo: ApplicationInfo
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
binding = FeedsResultMenuBinding.inflate(inflater, container, false)
/* get package name from fragment's tag */
searchWord = tag.toString()
WorkersDb.getRealm().query<LocationLog>().find()?.let {
if (it.size > 0) {
binding.logs.text = it.map {
BLog.LOGE("LocLog >> ${it.toString()}")
SimpleDateFormat("yyy/MM/dd-HH:mm:ss").format(Date(it.time))
it.mAddressLines.joinToString(" , ")
}.joinToString( " , ")
}
}
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
(requireDialog() as BottomSheetDialog).dismissWithAnimation = true
}
var mDismissCalback : DismissCalback? = null
fun show(manager: FragmentManager, tag: String?, dismissCalback : DismissCalback?) {
this.mDismissCalback = dismissCalback
this.show(manager, tag)
}
override fun show(manager: FragmentManager, tag: String?) {
super.show(manager, tag)
}
override fun dismiss() {
BLog.LOGE("dismiss()")
mDismissCalback?.invoke()
super.dismiss()
}
override fun onDismiss(dialog: DialogInterface) {
BLog.LOGE("onDismiss(dialog: DialogInterface)")
mDismissCalback?.invoke()
super.onDismiss(dialog)
}
}

View File

@ -0,0 +1,52 @@
package rasel.lunar.launcher.helpers
import android.content.Context
import android.content.SharedPreferences
object PrefHelper {
val D_PREFIX = "rasel.lunar.launcher.helpers"
val BOOL_PRE = D_PREFIX.plus(".BOOL.")
val LONG_PRE = D_PREFIX.plus(".LONG.")
fun inject(SharedPreferences : SharedPreferences) {
this.sharedPreferences = SharedPreferences
}
var sharedPreferences : SharedPreferences? = null
fun location(boolean: Boolean) {
sharedPreferences?.edit()?.putBoolean(BOOL_PRE.plus("location"), boolean)?.apply()
}
fun isLocationOn() = sharedPreferences?.getBoolean(BOOL_PRE.plus("location") , false) ?: false
var shortTimePeriod : Long
get() {
return sharedPreferences?.getLong(LONG_PRE.plus("shortTimePeriod"), 20L) ?: 20L
}
set(value) {
sharedPreferences?.edit()?.putLong(LONG_PRE.plus("shortTimePeriod"),value)?.apply()
}
var longTimePeriod : Long
get() {
return sharedPreferences?.getLong(LONG_PRE.plus("longTimePeriod"), 60L) ?: 60L
}
set(value) {
sharedPreferences?.edit()?.putLong(LONG_PRE.plus("longTimePeriod"),value)?.apply()
}
var midTimePeriod : Long
get() {
return sharedPreferences?.getLong(LONG_PRE.plus("midTimePeriod"), 30L) ?: 30L
}
set(value) {
sharedPreferences?.edit()?.putLong(LONG_PRE.plus("midTimePeriod"),value)?.apply()
}
}
typealias BLOCK = ()->Unit
inline fun Boolean.letTrue(block: BLOCK) {
if (this) {
block.invoke()
} else {
// elseblock.invoke()
}
}

View File

@ -178,11 +178,12 @@ internal class LauncherHome : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
home = this
BLog.LOGE("${this} ::::: onCreate >>>> ")
// BLog.LOGE("${this} ::::: onCreate >>>> ")
}
var mWeatherResult : RealmResults<WeatherForcast>? = null
var musicJob : Job? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
BLog.LOGE("${this} ::::: onCreateView >>>> ")
// BLog.LOGE("${this} ::::: onCreateView >>>> ")
binding = LauncherHomeBinding.inflate(inflater, container, false)
fragManager = lActivity!!.supportFragmentManager
settingsPrefs = requireContext().getSharedPreferences(PREFS_SETTINGS, 0)
@ -234,8 +235,8 @@ internal class LauncherHome : Fragment() {
}
}
}
GlobalScope.launch {
musicJob?.cancel()
musicJob = CoroutineScope(Dispatchers.Default).launch {
WorkersDb.getRealm().apply {
query<CurrentPlayItem>().find().asFlow().collect { changes: ResultsChange<CurrentPlayItem> ->
binding.currentMusic?.postDelayed({
@ -262,7 +263,7 @@ internal class LauncherHome : Fragment() {
}
}
}
musicJob?.start()
// BLog.LOGE("onCreateView()")
binding.nextBtn.setOnClickListener {
val mAudioManager =
@ -362,14 +363,14 @@ internal class LauncherHome : Fragment() {
val hideListViewTime = 1000L * 60L * 15L
val hideListView = {
binding.notiList.visibility = View.GONE
binding.mainList.visibility = View.GONE
binding.infoList.visibility = View.GONE
binding.smsList.visibility = View.GONE
binding.otherCheck.isSelected = false
binding.recentSms.isSelected = false
binding.missedCalls.isSelected = false
binding.notice.isSelected = false
// binding.notiList.visibility = View.GONE
// binding.mainList.visibility = View.GONE
// binding.infoList.visibility = View.GONE
// binding.smsList.visibility = View.GONE
// binding.otherCheck.isSelected = false
// binding.recentSms.isSelected = false
// binding.missedCalls.isSelected = false
// binding.notice.isSelected = false
}
@ -397,7 +398,7 @@ internal class LauncherHome : Fragment() {
private fun queryNotice() {
var mWorkManager = WorkManager.getInstance(requireContext())
Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager.enqueue(OneTimeWorkRequest.from(TelegramBotGetter::class.java))
// mWorkManager.enqueue(OneTimeWorkRequest.from(TelegramBotGetter::class.java))
}, 5, TimeUnit.SECONDS)
try { noticeJob?.cancel() } catch (e:Exception) {e.printStackTrace()}
mNotificationResult = null
@ -483,7 +484,7 @@ internal class LauncherHome : Fragment() {
}}
var rQ = WorkersDb.getRealm().query<RssData>().query("pubDate > $0", beforeDay(Date(),3))
if(keyword.length > 0) {
BLog.LOGE("queryInfos it >>> ${keyword}")
// BLog.LOGE("queryInfos it >>> ${keyword}")
if (JamoUtils.CHOSUNG.contains(keyword.split("")[0])) {
rQ = rQ.query(
"title CONTAINS $0 OR chosung CONTAINS $1 ",
@ -580,7 +581,7 @@ internal class LauncherHome : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
BLog.LOGE("${this} ::::: onViewCreated >>>> ")
// BLog.LOGE("${this} ::::: onViewCreated >>>> ")
rootViewGestures()
batteryProgressGestures()
@ -804,7 +805,7 @@ internal class LauncherHome : Fragment() {
}
override fun onResume() {
super.onResume()
BLog.LOGE("${this} ::::: onResume >>>> ")
// BLog.LOGE("${this} ::::: onResume >>>> ")
if (shouldResume) {
/* register battery changes */

View File

@ -79,20 +79,12 @@ internal class RssItemAdapter (
}
}
private var rssDataItemLis: ArrayList<RssDataInterface> = arrayListOf()
val mLongClickListener = View.OnLongClickListener { v ->
(v?.tag as? Int)?.let { idx ->
val rss = rssDataItemLis[idx]
lActivity?.doWebSavor(rss.originPage(),null)
// when (rss.category()) {
// RssDataType.GURU ,RssDataType.Most , RssDataType.TAGS-> { openOpera(rss.originPage()) }
// RssDataType.REDDIT -> { openReddit(rss.originPage()) }
// RssDataType.Dotax -> { openDotax(rss.originPage()) }
// RssDataType.YOUTUBE -> { openYouTube(rss.originPage()) }
// else -> { openNews(rss.originPage()) }
// }
}
true
}
// val mLongClickListener = View.OnLongClickListener { v ->
// (v?.tag as? Int)?.let { idx ->
// val rss = rssDataItemLis[idx]
// }
// true
// }
}
@ -135,7 +127,7 @@ internal class RssItemAdapter (
holder.view.root.tag = position
holder.view.root.setOnClickListener(dateViewClick)
holder.view.root.setOnLongClickListener(mLongClickListener)
// holder.view.root.setOnLongClickListener(mLongClickListener)
}
var layoutManager : LinearLayoutManager? = null
@ -152,9 +144,10 @@ internal class RssItemAdapter (
}.dispatchUpdatesTo(this).apply {
val visibleItemCount = (layoutManager?.findLastVisibleItemPosition() ?: 0) - (layoutManager?.findFirstVisibleItemPosition() ?: 0)
val first = layoutManager?.findLastVisibleItemPosition() ?: 0
if (visibleItemCount > 0) {
this@RssItemAdapter.notifyItemRangeChanged(0, visibleItemCount)
recyclerView?.scrollToPosition(0)
this@RssItemAdapter.notifyItemRangeChanged(first, visibleItemCount)
// recyclerView?.scrollToPosition(0)
}
}
rssDataItemLis.clear()

View File

@ -0,0 +1,77 @@
package rasel.lunar.launcher.model
import android.location.Address
import android.os.Bundle
import io.realm.kotlin.ext.realmAnyListOf
import io.realm.kotlin.ext.realmListOf
import io.realm.kotlin.types.RealmList
import io.realm.kotlin.types.RealmObject
import java.util.Locale
class LocationLog : RealmObject {
var mFeatureName: String? = null
var mAddressLines: RealmList<String> = realmListOf()
var mAdminArea: String? = null
var mSubAdminArea: String? = null
var mLocality: String? = null
var mSubLocality: String? = null
var mThoroughfare: String? = null
var mSubThoroughfare: String? = null
var mPremises: String? = null
var mPostalCode: String? = null
var mCountryCode: String? = null
var mCountryName: String? = null
var mLatitude = 0.0
var mLongitude = 0.0
var mHasLatitude = false
var mHasLongitude = false
var mPhone: String? = null
var mUrl: String? = null
var time : Long = 0L
fun fillData(address: Address) {
time = System.currentTimeMillis()
mFeatureName = address.featureName
mAddressLines.apply {
for (i in 0..address.maxAddressLineIndex) {
this.add(address.getAddressLine(i))
}
}
mAdminArea = address.adminArea
mSubAdminArea = address.subAdminArea
mLocality = address.locality
mSubLocality = address.subLocality
mThoroughfare = address.thoroughfare
mSubThoroughfare = address.subThoroughfare
mPremises = address.premises
mPostalCode = address.postalCode
mCountryCode = address.countryCode
mCountryName = address.countryName
mLatitude = address.latitude
mLongitude = address.longitude
mPhone = address.phone
mUrl = address.url
}
override fun toString(): String {
val buffer = StringBuffer()
buffer.append(mFeatureName).append("|").append("\n")
buffer.append(mAddressLines.joinToString(" , ")).append("|").append("\n")
buffer.append(mAdminArea).append("|").append("\n")
buffer.append(mSubAdminArea).append("|").append("\n")
buffer.append(mLocality).append("|").append("\n")
buffer.append(mSubLocality).append("|").append("\n")
buffer.append(mThoroughfare).append("|").append("\n")
buffer.append(mSubThoroughfare).append("|").append("\n")
buffer.append(mPremises).append("|").append("\n")
buffer.append(mPostalCode).append("|").append("\n")
buffer.append(mCountryCode).append("|").append("\n")
buffer.append(mCountryName).append("|").append("\n")
buffer.append(mLatitude).append("|").append("\n")
buffer.append(mLongitude).append("|").append("\n")
buffer.append(mPhone).append("|").append("\n")
buffer.append(mUrl).append("|").append("\n")
return buffer.toString()
}
}

View File

@ -61,11 +61,11 @@ class NLService : NotificationListenerService() {
val skips = arrayListOf("com.wssyncmldm")
@RequiresApi(Build.VERSION_CODES.S)
override fun onNotificationPosted(sbn: StatusBarNotification) {
BLog.LOGE("NLService********** onNotificationPosted")
BLog.LOGE("NLServiceID :" + sbn.id + "\t${sbn.notification.tickerText}\t" + sbn.packageName)
sbn.notification.extras.keySet().forEach {
BLog.LOGE("NLService********** keySet >> ${it} ${sbn.notification.extras.get(it)}")
}
// BLog.LOGE("NLService********** onNotificationPosted")
// BLog.LOGE("NLServiceID :" + sbn.id + "\t${sbn.notification.tickerText}\t" + sbn.packageName)
// sbn.notification.extras.keySet().forEach {
// BLog.LOGE("NLService********** keySet >> ${it} ${sbn.notification.extras.get(it)}")
// }
if (sbn.id != 0 && (sbn.packageName.contains(".") || sbn.packageName.contains("android")) && sbn.packageName.length > 0) {
NotificationItem().apply {
notiId = sbn.id
@ -77,24 +77,15 @@ class NLService : NotificationListenerService() {
postTime = sbn.postTime
var uniq = title ?: subtext ?: selfDisplayName ?: tikerMsg ?: ""
uniq_id = "${sbn.id}_${sbn.packageName}_${if (uniq.length > 3) uniq.substring(0,3) else uniq}"
BLog.LOGE("NLService********** enqueue TelegramBotGetter ${true == "bumssavor".equals(title)}")
BLog.LOGE("NLService********** enqueue TelegramBotGetter ${(true == "org.telegram.messenger".equals(pkgName))}")
BLog.LOGE("NLService********** enqueue TelegramBotGetter ${sbn.notification?.extras?.getString("android.text")?.startsWith("/") == true}")
if ((title?.contains("성희") == true) && (true == "org.telegram.messenger".equals(pkgName)) &&
tikerMsg?.contains("어디") == true) {
getLastLocation(applicationContext)
// BLog.LOGE("NLService********** enqueue TelegramBotGetter ")
// var mWorkManager = WorkManager.getInstance(applicationContext)
// Executors.newSingleThreadScheduledExecutor().schedule({
// mWorkManager.enqueue(OneTimeWorkRequest.from(TelegramBotGetter::class.java))
// }, 5, TimeUnit.SECONDS)
}
// BLog.LOGE("NLService********** enqueue TelegramBotGetter ${true == "bumssavor".equals(title)}")
// BLog.LOGE("NLService********** enqueue TelegramBotGetter ${(true == "org.telegram.messenger".equals(pkgName))}")
// BLog.LOGE("NLService********** enqueue TelegramBotGetter ${sbn.notification?.extras?.getString("android.text")?.startsWith("/") == true}")
}.apply {
if (skips.contains(pkgName)) {
} else {
WorkersDb.insertNoti(this)
BLog.LOGE("NLService********** onNotificationPosted ${Gson().toJson(this)}")
// BLog.LOGE("NLService********** onNotificationPosted ${Gson().toJson(this)}")
}
}
}
@ -104,7 +95,7 @@ class NLService : NotificationListenerService() {
val m = getSystemService<MediaSessionManager>()!!
val component = ComponentName(this, NLService::class.java)
val sessions = m.getActiveSessions(component)
BLog.LOGE("Sessions", "count: ${sessions.size}")
// BLog.LOGE("Sessions", "count: ${sessions.size}")
sessions.forEach { session ->
WorkersDb.getRealm().writeBlocking {
if (session.playbackState?.isActive == true) {
@ -116,23 +107,23 @@ class NLService : NotificationListenerService() {
current = CurrentPlayItem()
copyToRealm(current, UpdatePolicy.ALL)
}
BLog.LOGE(
"Sessions",
"$session -- " + (session.playbackState?.state)
)
BLog.LOGE(
"Sessions",
"$session -- " + (session?.metadata?.keySet()?.joinToString())
)
BLog.LOGE(
"Sessions",
"$session -- " + (session?.metadata?.getString(MediaMetadata.METADATA_KEY_ARTIST))
)
// BLog.LOGE(
// "Sessions",
// "$session -- " + (session.playbackState?.state)
// )
// BLog.LOGE(
// "Sessions",
// "$session -- " + (session?.metadata?.keySet()?.joinToString())
// )
// BLog.LOGE(
// "Sessions",
// "$session -- " + (session?.metadata?.getString(MediaMetadata.METADATA_KEY_ARTIST))
// )
if (session?.metadata?.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ART) == true) {
BLog.LOGE(
"Sessions",
"$session -- " + (session?.metadata?.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART))
)
// BLog.LOGE(
// "Sessions",
// "$session -- " + (session?.metadata?.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART))
// )
current.albumArt = BitmapConverter.BitmapToString(
session.metadata?.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART)
)
@ -160,8 +151,8 @@ class NLService : NotificationListenerService() {
}
override fun onNotificationRemoved(sbn: StatusBarNotification) {
BLog.LOGE("NLService********** onNOtificationRemoved")
BLog.LOGE("NLService ID :" + sbn.id + "\t" + sbn.notification.tickerText + "\t" + sbn.packageName)
// BLog.LOGE("NLService********** onNOtificationRemoved")
// BLog.LOGE("NLService ID :" + sbn.id + "\t" + sbn.notification.tickerText + "\t" + sbn.packageName)
var uniq_id = "${sbn.id}_${sbn.packageName}"
try {
WorkersDb.getRealm()?.apply {
@ -177,7 +168,7 @@ class NLService : NotificationListenerService() {
internal inner class NLServiceReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent) {
BLog.LOGE("NLService intent >>> ${intent.action}")
// BLog.LOGE("NLService intent >>> ${intent.action}")
if (intent.getStringExtra("command") == "clearall") {
this@NLService.cancelAllNotifications()
} else if (intent.getStringExtra("command") == "list") {
@ -186,7 +177,7 @@ class NLService : NotificationListenerService() {
// sendBroadcast(i1)
var i = 1
for (sbn in this@NLService.activeNotifications) {
BLog.LOGE("NLService sbn >>> ${sbn.packageName} , ${Gson().toJson(sbn.notification.extras.keySet())}")
// BLog.LOGE("NLService sbn >>> ${sbn.packageName} , ${Gson().toJson(sbn.notification.extras.keySet())}")
// val i2 = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
// i2.putExtra("notification_event", i.toString() + " " + sbn.packageName + "\n")
// sendBroadcast(i2)
@ -203,67 +194,67 @@ class NLService : NotificationListenerService() {
@SuppressLint("MissingPermission")
private fun getLastLocation(context: Context) {
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context);
BLog.LOGE("Location getLastLocation")
// BLog.LOGE("Location getLastLocation")
fusedLocationProviderClient?.getLastLocation()?.addOnSuccessListener(object :
OnSuccessListener<Location?> {
override fun onSuccess(location: Location?) {
if (location != null) {
// Log the latitude and longitude
BLog.LOGE("Location Latitude: " + location.getLatitude())
BLog.LOGE("Location Longitude: " + location.getLongitude())
// Use Geocoder to get detailed location information
try {
val geocoder = Geocoder(context, Locale.getDefault())
val addresses: List<Address>? = geocoder.getFromLocation(
location.getLatitude(),
location.getLongitude(),
1
)
addresses?.first()?.let {
it.getAddressLine(0)?.let {
Executors.newSingleThreadScheduledExecutor().schedule({
try {
//////-1002450229641
val url =
"https://api.telegram.org/bot7934509464:AAE_xUbICxMdywLGnxo7BkeIqA1nVza4P9w/sendMessage?chat_id=83268260&text=남편의현위치는${it}"
//7068729507
// OkHttp 클라이언트 객체 생성
val client = OkHttpClient.Builder()
.connectionPool(ConnectionPool(5, 60, TimeUnit.SECONDS))
.build()
// GET 요청 객체 생성
val builder: Request.Builder = Request.Builder().url(url)
.addHeader("Content-Type", "application/json").get()
val request: Request = builder.build()
BLog.LOGE("telegram before request ")
// OkHttp 클라이언트로 GET 요청 객체 전송
val response: Response = client.newCall(request).execute()
if (response.isSuccessful()) {
// 응답 받아서 처리
val body: ResponseBody? = response.body()
if (body != null) {
}
} else BLog.LOGE("telegram Error Occurred")
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
}, 5, TimeUnit.SECONDS)
}
}
// Display location details on UI elements
// Log detailed location information
BLog.LOGE("Location Addresses: $addresses")
} catch (e: IOException) {
e.printStackTrace()
}
}
// if (location != null) {
// // Log the latitude and longitude
// BLog.LOGE("Location Latitude: " + location.getLatitude())
// BLog.LOGE("Location Longitude: " + location.getLongitude())
//
// // Use Geocoder to get detailed location information
// try {
// val geocoder = Geocoder(context, Locale.getDefault())
// val addresses: List<Address>? = geocoder.getFromLocation(
// location.getLatitude(),
// location.getLongitude(),
// 1
// )
//
// addresses?.first()?.let {
// it.getAddressLine(0)?.let {
// Executors.newSingleThreadScheduledExecutor().schedule({
// try {
// //////-1002450229641
// val url =
// "https://api.telegram.org/bot7934509464:AAE_xUbICxMdywLGnxo7BkeIqA1nVza4P9w/sendMessage?chat_id=83268260&text=남편의현위치는${it}"
// //7068729507
// // OkHttp 클라이언트 객체 생성
// val client = OkHttpClient.Builder()
// .connectionPool(ConnectionPool(5, 60, TimeUnit.SECONDS))
// .build()
//
// // GET 요청 객체 생성
// val builder: Request.Builder = Request.Builder().url(url)
// .addHeader("Content-Type", "application/json").get()
//
// val request: Request = builder.build()
//
// BLog.LOGE("telegram before request ")
// // OkHttp 클라이언트로 GET 요청 객체 전송
// val response: Response = client.newCall(request).execute()
// if (response.isSuccessful()) {
// // 응답 받아서 처리
// val body: ResponseBody? = response.body()
// if (body != null) {
//
// }
// } else BLog.LOGE("telegram Error Occurred")
//
// } catch (e: java.lang.Exception) {
// e.printStackTrace()
// }
// }, 5, TimeUnit.SECONDS)
// }
// }
// // Display location details on UI elements
// // Log detailed location information
// BLog.LOGE("Location Addresses: $addresses")
// } catch (e: IOException) {
// e.printStackTrace()
// }
// }
}
})
}

View File

@ -117,17 +117,17 @@ internal class SettingsActivity : AppCompatActivity() {
/* source code at github */
aboutBinding.sourceCode.setOnClickListener {
bottomSheetDialog.dismiss()
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(sourceCode)))
// startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(sourceCode)))
}
/* wiki at github */
aboutBinding.wiki.setOnClickListener {
bottomSheetDialog.dismiss()
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("$sourceCode/wiki")))
// startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("$sourceCode/wiki")))
}
/* telegram community */
aboutBinding.telegramGroup.setOnClickListener {
bottomSheetDialog.dismiss()
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("https://t.me/LunarLauncher_chats")))
// startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("https://t.me/LunarLauncher_chats")))
}
}
@ -138,15 +138,15 @@ internal class SettingsActivity : AppCompatActivity() {
.setMessage(R.string.support_message)
/* star button */
.setNeutralButton(R.string.star) { _, _ ->
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(sourceCode)))
// startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(sourceCode)))
}
/* affiliate button */
.setNegativeButton(R.string.amazon) { _, _ ->
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("https://amzn.to/44krAw9")))
// startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("https://amzn.to/44krAw9")))
}
/* donate button */
.setPositiveButton(R.string.donate) { _, _ ->
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("https://iamrasel.github.io/donate")))
// startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("https://iamrasel.github.io/donate")))
}
.show()
}

View File

@ -1,6 +1,101 @@
package rasel.lunar.launcher.utils
import io.realm.kotlin.ext.query
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import rasel.lunar.launcher.home.LauncherHome.Companion.lastedFinishedPageUrl
import rasel.lunar.launcher.model.MostItem
import rasel.lunar.launcher.model.RssData
import rasel.lunar.launcher.model.RssDataType
import rasel.lunar.launcher.model.dateFormat
import rasel.lunar.launcher.model.getRssData
import rasel.lunar.launcher.workers.WorkersDb
import java.nio.charset.Charset
import java.text.SimpleDateFormat
import java.util.Base64
import java.util.Date
val USAGT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Safari/605.1.15"
fun String.getJ() = Jsoup.connect("https://kr69.sogirl.so/").userAgent(USAGT).get()
fun String.getJ() = Jsoup.connect(this).userAgent(USAGT).get()
object FeedParseManager {
val parsers = listOf<SoInterface>(QVZTb2dpcmw,SkFWTW9zdA)
fun parse(doc : Document, consoleLog : (String)-> Unit) {
consoleLog("FeedParseManager START")
try {
parsers.filter { doc.title().contains(it.getName()) }.first()?.let {
it.parse(doc,consoleLog)
}
} catch (e : Exception) {
consoleLog(e.message ?: "Exception")
e.printStackTrace()
}
consoleLog("FeedParseManager END")
}
}
interface SoInterface{
fun getName() : String
fun parse(doc : Document, consoleLog : (String)-> Unit)
}
object QVZTb2dpcmw : SoInterface {
override fun getName(): String {
return String(Base64.getMimeDecoder().decode(this.javaClass.simpleName.plus("==").toByteArray()))
}
override fun parse(doc : Document, consoleLog : (String)-> Unit) {
doc.getElementsByTag("article").forEach { article ->
consoleLog("ogirl article >>> ${article.text()}")
val title = article.getElementsByTag("a").get(0).attr("title")
val href = article.getElementsByTag("a").get(0).attr("href")
val img = article.getElementsByTag("img").get(0).attr("data-src")
WorkersDb.getRealm().writeBlocking {
if (query<RssData>("originPage == $0", href).find().size == 0) {
RssData().apply {
this.originPage = href
this.title = title
this.description = "Sogirl"
this.thumbnail = img
this.pubDate = Date().time
this.category = RssDataType.GURU.name
this.chosung =
JamoUtils.split(title).joinToString("")
copyToRealm(this)
}
consoleLog("title $title | href $href | img $img" )
}
}
}
}
}
object SkFWTW9zdA : SoInterface {
var dmy = SimpleDateFormat("dd-MM-yyyy")
override fun getName(): String {
return String(Base64.getMimeDecoder().decode(this.javaClass.simpleName.plus("==").toByteArray()))
}
override fun parse(doc: Document, consoleLog: (String) -> Unit) {
consoleLog("$lastedFinishedPageUrl >>> ${doc.title()}")
doc.getElementsByClass("card").forEach { card ->
var thumb = if(card.getElementsByTag("img").size > 0) card.getElementsByTag("img").get(0).attr("src") else ""
if (thumb.contains("No+Poster")) thumb = if(card.getElementsByTag("img").size > 0) card.getElementsByTag("img").get(0).attr("data-src") else thumb
var model = if(card.getElementsByTag("img").size > 0) card.getElementsByTag("img").get(0).attr("alt") else ""
if(card.getElementsByClass("card-block").size > 0) if(card.getElementsByClass("card-block").size > 0) {
val link = card.getElementsByClass("card-block").get(0).getElementsByTag("a").get(0).attr("href")
val title = card.getElementsByClass("card-block").get(0).getElementsByTag("a").get(0).attr("title")
val date = card.getElementsByTag("span").get(0).text()
MostItem().let { ms ->
ms.model = model
ms.image = thumb
ms.pageLink = link
ms.title = title
try {
ms.date = dmy.parse(date).time
consoleLog("dateFormat.format(Date(ms.date)) ${dateFormat.format(Date(ms.date))}")
}catch (e : Exception) {e.printStackTrace()}
if (ms.isValid()) {
WorkersDb.insertData(ms.getRssData())
}
}
consoleLog(" model >>>>> ${model}\n | thumb >>>>> ${thumb}\n | title >>>>> ${title}\n | date >>>>> ${date} | ")
}
}
consoleLog("excuted j req() ${WorkersDb.getRealm().query<RssData>("category == $0", RssDataType.GURU.name).find().size}")
}
}

View File

@ -482,17 +482,17 @@ class SimpleFingerGestures : OnTouchListener {
override fun onTouch(view: View, ev: MotionEvent): Boolean {
if (debug) Log.d(TAG, "onTouch")
// if (debug) Log.d(TAG, "onTouch")
when (ev.action and MotionEvent.ACTION_MASK) {
MotionEvent.ACTION_DOWN -> {
if (debug) Log.d(TAG, "ACTION_DOWN")
// if (debug) Log.d(TAG, "ACTION_DOWN")
startTracking(0)
ga.trackGesture(ev)
return consumeTouchEvents
}
MotionEvent.ACTION_UP -> {
if (debug) Log.d(TAG, "ACTION_UP")
// if (debug) Log.d(TAG, "ACTION_UP")
if (tracking[0]) {
doCallBack(view,ga.getGesture(ev))
}
@ -502,14 +502,14 @@ class SimpleFingerGestures : OnTouchListener {
}
MotionEvent.ACTION_POINTER_DOWN -> {
if (debug) Log.d(TAG, "ACTION_POINTER_DOWN" + " " + "num" + ev.pointerCount)
// if (debug) Log.d(TAG, "ACTION_POINTER_DOWN" + " " + "num" + ev.pointerCount)
startTracking(ev.pointerCount - 1)
ga.trackGesture(ev)
return consumeTouchEvents
}
MotionEvent.ACTION_POINTER_UP -> {
if (debug) Log.d(TAG, "ACTION_POINTER_UP" + " " + "num" + ev.pointerCount)
// if (debug) Log.d(TAG, "ACTION_POINTER_UP" + " " + "num" + ev.pointerCount)
if (tracking[1]) {
doCallBack(view,ga.getGesture(ev))
}
@ -519,12 +519,12 @@ class SimpleFingerGestures : OnTouchListener {
}
MotionEvent.ACTION_CANCEL -> {
if (debug) Log.d(TAG, "ACTION_CANCEL")
// if (debug) Log.d(TAG, "ACTION_CANCEL")
return true
}
MotionEvent.ACTION_MOVE -> {
if (debug) Log.d(TAG, "ACTION_MOVE")
// if (debug) Log.d(TAG, "ACTION_MOVE")
return consumeTouchEvents
}
}
@ -685,17 +685,17 @@ class SimpleFingerGestures : OnTouchListener {
// onFingerGestureListener!!.onDoubleTap(1)
}
GestureAnalyser.CLICK_1 -> {
BLog.LOGE("GestureAnalyser.CLICK_1")
// BLog.LOGE("GestureAnalyser.CLICK_1")
onFingerGestureListener!!.onClick(targetView, 1)
// onFingerGestureListener!!.onDoubleTap(1)
}
GestureAnalyser.CLICK_2 -> {
BLog.LOGE("GestureAnalyser.CLICK_2")
// BLog.LOGE("GestureAnalyser.CLICK_2")
onFingerGestureListener!!.onClick(targetView, 2)
// onFingerGestureListener!!.onDoubleTap(1)
}
GestureAnalyser.CLICK_3 -> {
BLog.LOGE("GestureAnalyser.CLICK_3")
// BLog.LOGE("GestureAnalyser.CLICK_3")
onFingerGestureListener!!.onClick(targetView, 3)
// onFingerGestureListener!!.onDoubleTap(1)
}
@ -709,15 +709,15 @@ class SimpleFingerGestures : OnTouchListener {
// }
GestureAnalyser.LONG_CLICK_1 -> {
BLog.LOGE("GestureAnalyser.LONG_CLICK_1")
// BLog.LOGE("GestureAnalyser.LONG_CLICK_1")
onFingerGestureListener!!.onLongPress(targetView,1)
}
GestureAnalyser.LONG_CLICK_2 -> {
BLog.LOGE("GestureAnalyser.LONG_CLICK_2")
// BLog.LOGE("GestureAnalyser.LONG_CLICK_2")
onFingerGestureListener!!.onLongPress(targetView,2)
}
GestureAnalyser.LONG_CLICK_3 -> {
BLog.LOGE("GestureAnalyser.LONG_CLICK_3")
// BLog.LOGE("GestureAnalyser.LONG_CLICK_3")
onFingerGestureListener!!.onLongPress(targetView,3)
}

View File

@ -25,6 +25,7 @@ class AppInfoGetter : BaseGetter {
}
override fun realWork(): Result {
try {
var packageManager = lActivity?.packageManager
var packageInfoList: MutableList<ResolveInfo> = mutableListOf()
packageInfoList = (if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {

View File

@ -0,0 +1,149 @@
package rasel.lunar.launcher.workers
import android.content.Context
import android.net.Uri
import androidx.work.WorkerParameters
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
import rasel.lunar.launcher.utils.BLog
class CalendarGetter : BaseGetter {
companion object {
val TAG = "DCGetter"
}
constructor(context: Context, workerParams: WorkerParameters) : super(context, workerParams) {
}
override fun realWork(): Result {
setCalendar()
return Result.success().apply {
}
}
fun setCalendar() {
val calendars = Uri.parse("content://com.android.calendar/events")
val projection = arrayOf(
"calendar_id",
// "htmlUri",
"title",
// "eventLocation",
"description",
// "eventStatus",
// "selfAttendeeStatus",
// "commentsUri",
"dtstart",
"dtend",
// "eventTimezone",
// "duration",
// "allDay",
// "visibility",
// "transparency",
// "hasAlarm",
// "hasExtendedProperties",
// "rrule",
"rdate",
// "exrule",
// "exdate",
// "originalEvent",
// "originalInstanceTime",
// "originalAllDay",
// "lastDate",
// "hasAttendeeData",
// "guestsCanModify",
// "guestsCanInviteOthers",
// "guestsCanSeeGuests",
// "organizer",
// "deleted"
)
// val managedCursor: Cursor =
lActivity?.contentResolver?.query(calendars, projection, null, null, null)?.let { managedCursor ->
if (managedCursor.moveToFirst()) {
val calendar_id = IntArray(managedCursor.count)
// val htmlUri = arrayOfNulls<String>(managedCursor.count)
val title = arrayOfNulls<String>(managedCursor.count)
// val eventLocation = arrayOfNulls<String>(managedCursor.count)
val description = arrayOfNulls<String>(managedCursor.count)
// val eventStatus = IntArray(managedCursor.count)
// val selfAttendeeStatus = IntArray(managedCursor.count)
// val commentsUri = arrayOfNulls<String>(managedCursor.count)
val dtstart = arrayOfNulls<String>(managedCursor.count)
val dtend = arrayOfNulls<String>(managedCursor.count)
// val eventTimezone = arrayOfNulls<String>(managedCursor.count)
// val duration = arrayOfNulls<String>(managedCursor.count)
// val allDay = IntArray(managedCursor.count)
// val visibility = IntArray(managedCursor.count)
// val transparency = IntArray(managedCursor.count)
// val hasAlarm = IntArray(managedCursor.count)
// val hasExtendedProperties = IntArray(managedCursor.count)
// val rrule = arrayOfNulls<String>(managedCursor.count)
val rdate = arrayOfNulls<String>(managedCursor.count)
// val exrule = arrayOfNulls<String>(managedCursor.count)
// val exdate = arrayOfNulls<String>(managedCursor.count)
// val originalEvent = arrayOfNulls<String>(managedCursor.count)
// val originalInstanceTime = IntArray(managedCursor.count)
// val originalAllDay = IntArray(managedCursor.count)
// val lastDate = IntArray(managedCursor.count)
// val hasAttendeeData = IntArray(managedCursor.count)
// val guestsCanModify = IntArray(managedCursor.count)
// val guestsCanInviteOthers = IntArray(managedCursor.count)
// val guestsCanSeeGuests = IntArray(managedCursor.count)
// val organizer = arrayOfNulls<String>(managedCursor.count)
// val deleted = IntArray(managedCursor.count)
for (i in title.indices) {
calendar_id[i] = managedCursor.getInt(0)
BLog.LOGE("Calendar ID : " + calendar_id[i])
// htmlUri[i] = managedCursor.getString(1)
// Log.i("Calendar", "htmlUri : " + htmlUri[i])
title[i] = managedCursor.getString(1)
BLog.LOGE("Calendar title : " + title[i])
// eventLocation[i] = managedCursor.getString(3)
// Log.i("Calendar", "eventLocation : " + eventLocation[i])
description[i] = managedCursor.getString(2)
// eventStatus[i] = managedCursor.getInt(5)
// selfAttendeeStatus[i] = managedCursor.getInt(6)
// commentsUri[i] = managedCursor.getString(7)
dtstart[i] = managedCursor.getString(3)
BLog.LOGE("Calendar dtstart : " + rdate[i])
dtend[i] = managedCursor.getString(4)
BLog.LOGE("Calendar dtend : " + rdate[i])
// eventTimezone[i] = managedCursor.getString(10)
// duration[i] = managedCursor.getString(11)
// allDay[i] = managedCursor.getInt(12)
// visibility[i] = managedCursor.getInt(13)
// transparency[i] = managedCursor.getInt(14)
// hasAlarm[i] = managedCursor.getInt(15)
// hasExtendedProperties[i] = managedCursor.getInt(16)
// rrule[i] = managedCursor.getString(17)
rdate[i] = managedCursor.getString(5)
BLog.LOGE("Calendar rdate : " + rdate[i])
// exrule[i] = managedCursor.getString(19)
// exdate[i] = managedCursor.getString(20)
// originalEvent[i] = managedCursor.getString(21)
// originalInstanceTime[i] = managedCursor.getInt(22)
// originalAllDay[i] = managedCursor.getInt(23)
// lastDate[i] = managedCursor.getInt(24)
// hasAttendeeData[i] = managedCursor.getInt(25)
// guestsCanModify[i] = managedCursor.getInt(26)
// guestsCanInviteOthers[i] = managedCursor.getInt(27)
// guestsCanSeeGuests[i] = managedCursor.getInt(28)
// organizer[i] = managedCursor.getString(29)
// deleted[i] = managedCursor.getInt(30)
if (title[i] != null) {
BLog.LOGE("title[i] ${title[i]}")
}
managedCursor.moveToNext()
}
}
managedCursor.close()
}
}
}

View File

@ -74,7 +74,7 @@ class ClienGetter : BaseGetter {
Jsoup.connect(url)
.userAgent(USAGT)
.get().let { ruli ->
BLog.LOGE("test ${url} >> ${ruli.title()}")
// BLog.LOGE("test ${url} >> ${ruli.title()}")
ruli.getElementsByClass("list_item symph_row ").forEach { ruli_tr ->
parseClien(ruli_tr)
}
@ -82,7 +82,6 @@ class ClienGetter : BaseGetter {
}
} catch (e:Exception){e.printStackTrace()}
return Result.success().apply {
BLog.LOGE("ClienGetter temp >>>> ${temp.size}")
WorkersDb.insertBulkData(temp)
}
}

View File

@ -8,6 +8,9 @@ import rasel.lunar.launcher.model.Dotax
import rasel.lunar.launcher.model.getRssData
class DotaxGetter : BaseGetter {
companion object {
val COMIC2_WORK_TAG = "ComicGetter2"
}
constructor(context: Context, workerParams: WorkerParameters) : super(context, workerParams) {
}

View File

@ -9,6 +9,9 @@ import rasel.lunar.launcher.model.getRssData
import java.util.Date
class FmKoreaGetter : BaseGetter {
companion object {
val COMIC_WORK_TAG = "ComicGetter"
}
constructor(context: Context, workerParams: WorkerParameters) : super(context, workerParams) {
}

View File

@ -2,13 +2,31 @@ package rasel.lunar.launcher.workers
import android.annotation.SuppressLint
import android.content.Context
import android.location.Address
import android.location.Geocoder
import android.location.Location
import android.os.Build
import androidx.work.WorkerParameters
import com.google.android.gms.location.LocationServices
import com.google.android.gms.location.Priority
import com.google.android.gms.tasks.CancellationTokenSource
import rasel.lunar.launcher.LauncherActivity.Companion.doGetWheaterByLocationInfo
import okhttp3.ConnectionPool
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import okhttp3.ResponseBody
import rasel.lunar.launcher.LauncherActivity.Companion.runWeatherGetter
import rasel.lunar.launcher.helpers.PrefHelper
import rasel.lunar.launcher.helpers.letTrue
import rasel.lunar.launcher.model.LocationLog
import rasel.lunar.launcher.utils.BLog
import java.io.IOException
import java.math.BigDecimal
import java.math.RoundingMode
import java.util.Locale
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
import kotlin.math.cos
class LocationGetter(context: Context, workerParams: WorkerParameters) : BaseGetter(context, workerParams) {
companion object {
@ -29,7 +47,10 @@ class LocationGetter(context: Context, workerParams: WorkerParameters) : BaseGet
BLog.LOGE("Location >>> (latitude)${it.longitude}/(longitude)${it.latitude}")
longitude = it.longitude
latitude = it.latitude
doGetWheaterByLocationInfo()
runWeatherGetter()
PrefHelper.isLocationOn().letTrue {
pushLocation(it)
}
}
}.addOnFailureListener{
BLog.LOGE("Location error >>> $it")
@ -38,4 +59,88 @@ class LocationGetter(context: Context, workerParams: WorkerParameters) : BaseGet
return Result.success()
}
}
fun pushLocation(location: Location) {
try {
val geocoder = Geocoder(this.applicationContext, Locale.getDefault())
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
geocoder.getFromLocation(
BigDecimal.valueOf(location.getLatitude()).setScale(6,RoundingMode.HALF_UP).toDouble(),
BigDecimal.valueOf(location.getLongitude()).setScale(6,RoundingMode.HALF_UP).toDouble(),
1) { addresses ->
addresses.first()?.let {
WorkersDb.push(LocationLog().apply {
fillData(it)
})
// it.getAddressLine(0)?.let {
// Executors.newSingleThreadScheduledExecutor().schedule({
// try {
// //////-1002450229641
// val url =
// "https://api.telegram.org/bot7934509464:AAE_xUbICxMdywLGnxo7BkeIqA1nVza4P9w/sendMessage?chat_id=83268260&text=남편의현위치는${it}"
// //7068729507
// // OkHttp 클라이언트 객체 생성
// val client = OkHttpClient.Builder()
// .connectionPool(ConnectionPool(5, 60, TimeUnit.SECONDS))
// .build()
//
// // GET 요청 객체 생성
// val builder: Request.Builder = Request.Builder().url(url)
// .addHeader("Content-Type", "application/json").get()
//
// val request: Request = builder.build()
//
// BLog.LOGE("telegram before request ")
// // OkHttp 클라이언트로 GET 요청 객체 전송
// val response: Response = client.newCall(request).execute()
// if (response.isSuccessful()) {
// // 응답 받아서 처리
// val body: ResponseBody? = response.body()
// if (body != null) {
//
// }
// } else BLog.LOGE("telegram Error Occurred")
//
// } catch (e: java.lang.Exception) {
// e.printStackTrace()
// }
// }, 5, TimeUnit.SECONDS)
// }
}
addresses.forEach { }
}
}
} catch (e: IOException) {
e.printStackTrace()
}
}
}
val EARTH_RADIUS_METERS = 6371000
val LATITUDE_DEGREE_PER_METER: Double = 1.0 / (2 * Math.PI * EARTH_RADIUS_METERS / 360)
fun latitudeRange(latitude: Double, radiusInMeters: Int): DoubleArray {
val degreeRange = radiusInMeters * LATITUDE_DEGREE_PER_METER
val minLatitude = latitude - degreeRange
val maxLatitude = latitude + degreeRange
return doubleArrayOf(minLatitude, maxLatitude)
}
fun longitudeRange(latitude: Double, longitude: Double, radiusInMeters: Int): DoubleArray {
val longitudeDegreePerMeter: Double = 360 / (2 * Math.PI * EARTH_RADIUS_METERS * cos(Math.toRadians(latitude)))
val degreeRange = longitudeDegreePerMeter * radiusInMeters
val minLongitude = longitude - degreeRange
val maxLongitude = longitude + degreeRange
return doubleArrayOf(minLongitude, maxLongitude)
}
//https://jinkpark.tistory.com/296
//https://develoyummer.tistory.com/103
//https://ghj1001020.tistory.com/300

View File

@ -8,9 +8,11 @@ import rasel.lunar.launcher.home.adapters.RssFeedsParser
import rasel.lunar.launcher.utils.RssList
class NewsFeedsGetter : BaseGetter {
companion object {
val FEDDS_WORK_TAG = "NewsFeedsGetter"
}
var feddsUrls = arrayListOf<String>()
constructor(context: Context, workerParams: WorkerParameters) : super(context, workerParams) {
}
@SuppressLint("RestrictedApi")

View File

@ -27,6 +27,7 @@ import java.util.Date
class RecentSmsGetter : BaseGetter {
companion object {
var dayRange = BaseGetter.defaultDay
val SMS_WORK_TAG = "RecentSmsGetter"
}
constructor(context: Context, workerParams: WorkerParameters) : super(context, workerParams) {

View File

@ -9,6 +9,9 @@ import rasel.lunar.launcher.home.adapters.RssFeedsParser
import rasel.lunar.launcher.utils.RssList.feedJsons
class RedditGetter : BaseGetter {
companion object{
val REDDIT_WORK_TAG = "RedditGetter"
}
constructor(context: Context, workerParams: WorkerParameters) : super(context, workerParams) {
}

View File

@ -65,7 +65,7 @@ class RuliWebGetter : BaseGetter {
Jsoup.connect(url)
.userAgent(USAGT)
.get().let { ruli ->
BLog.LOGE("test ${testUrl2} >> ${ruli.title()}")
// BLog.LOGE("test ${testUrl2} >> ${ruli.title()}")
ruli.getElementsByTag("tr").forEach { ruli_tr ->
parseRuli(ruli_tr)
}

View File

@ -99,68 +99,68 @@ class TelegramBotGetter : BaseGetter {
var fusedLocationProviderClient: FusedLocationProviderClient? = null
@SuppressLint("MissingPermission")
private fun getLastLocation(context: Context) {
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context);
BLog.LOGE("Location getLastLocation")
fusedLocationProviderClient?.getLastLocation()?.addOnSuccessListener(object : OnSuccessListener<Location?> {
override fun onSuccess(location: Location?) {
if (location != null) {
// Log the latitude and longitude
BLog.LOGE("Location Latitude: " + location.getLatitude())
BLog.LOGE("Location Longitude: " + location.getLongitude())
// Use Geocoder to get detailed location information
try {
val geocoder = Geocoder(context, Locale.getDefault())
val addresses: List<Address>? = geocoder.getFromLocation(
location.getLatitude(),
location.getLongitude(),
1
)
addresses?.first()?.let {
it.getAddressLine(0)?.let {
Executors.newSingleThreadScheduledExecutor().schedule({
try {
//////-1002450229641
val url =
"https://api.telegram.org/bot7934509464:AAE_xUbICxMdywLGnxo7BkeIqA1nVza4P9w/sendMessage?chat_id=83268260&text=남편의현위치는${it}"
//7068729507
// OkHttp 클라이언트 객체 생성
val client = OkHttpClient.Builder()
.connectionPool(ConnectionPool(5, 60, TimeUnit.SECONDS))
.build()
// GET 요청 객체 생성
val builder: Request.Builder = Request.Builder().url(url)
.addHeader("Content-Type", "application/json").get()
val request: Request = builder.build()
BLog.LOGE("telegram before request ")
// OkHttp 클라이언트로 GET 요청 객체 전송
val response: Response = client.newCall(request).execute()
if (response.isSuccessful()) {
// 응답 받아서 처리
val body: ResponseBody? = response.body()
if (body != null) {
}
} else BLog.LOGE("telegram Error Occurred")
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
}, 5, TimeUnit.SECONDS)
}
}
// Display location details on UI elements
// Log detailed location information
BLog.LOGE("Location Addresses: $addresses")
} catch (e: IOException) {
e.printStackTrace()
}
}
}
})
// fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context);
// BLog.LOGE("Location getLastLocation")
// fusedLocationProviderClient?.getLastLocation()?.addOnSuccessListener(object : OnSuccessListener<Location?> {
// override fun onSuccess(location: Location?) {
// if (location != null) {
// // Log the latitude and longitude
// BLog.LOGE("Location Latitude: " + location.getLatitude())
// BLog.LOGE("Location Longitude: " + location.getLongitude())
//
// // Use Geocoder to get detailed location information
// try {
// val geocoder = Geocoder(context, Locale.getDefault())
// val addresses: List<Address>? = geocoder.getFromLocation(
// location.getLatitude(),
// location.getLongitude(),
// 1
// )
//
// addresses?.first()?.let {
// it.getAddressLine(0)?.let {
// Executors.newSingleThreadScheduledExecutor().schedule({
// try {
// //////-1002450229641
// val url =
// "https://api.telegram.org/bot7934509464:AAE_xUbICxMdywLGnxo7BkeIqA1nVza4P9w/sendMessage?chat_id=83268260&text=남편의현위치는${it}"
// //7068729507
// // OkHttp 클라이언트 객체 생성
// val client = OkHttpClient.Builder()
// .connectionPool(ConnectionPool(5, 60, TimeUnit.SECONDS))
// .build()
//
// // GET 요청 객체 생성
// val builder: Request.Builder = Request.Builder().url(url)
// .addHeader("Content-Type", "application/json").get()
//
// val request: Request = builder.build()
//
// BLog.LOGE("telegram before request ")
// // OkHttp 클라이언트로 GET 요청 객체 전송
// val response: Response = client.newCall(request).execute()
// if (response.isSuccessful()) {
// // 응답 받아서 처리
// val body: ResponseBody? = response.body()
// if (body != null) {
//
// }
// } else BLog.LOGE("telegram Error Occurred")
//
// } catch (e: java.lang.Exception) {
// e.printStackTrace()
// }
// }, 5, TimeUnit.SECONDS)
// }
// }
// // Display location details on UI elements
// // Log detailed location information
// BLog.LOGE("Location Addresses: $addresses")
// } catch (e: IOException) {
// e.printStackTrace()
// }
// }
// }
// })
}
}

View File

@ -53,7 +53,7 @@ class TheQooGetter : BaseGetter {
Jsoup.connect(url)
.userAgent(USAGT)
.get().let { ruli ->
BLog.LOGE("test ${testUrl2} >> ${ruli.title()}")
// BLog.LOGE("test ${testUrl2} >> ${ruli.title()}")
ruli.getElementsByTag("tr").forEach { ruli_tr ->
parseTQoo(ruli_tr)
}

View File

@ -5,6 +5,8 @@ import io.realm.kotlin.RealmConfiguration
import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.ext.query
import io.realm.kotlin.ext.realmListOf
import io.realm.kotlin.migration.AutomaticSchemaMigration
import io.realm.kotlin.migration.RealmMigration
import io.realm.kotlin.types.BaseRealmObject
import io.realm.kotlin.types.RealmList
import io.realm.kotlin.types.RealmObject
@ -23,6 +25,7 @@ import rasel.lunar.launcher.model.Forecast
import rasel.lunar.launcher.model.Forecastday
import rasel.lunar.launcher.model.Hour
import rasel.lunar.launcher.model.Location
import rasel.lunar.launcher.model.LocationLog
import rasel.lunar.launcher.model.NotificationItem
import rasel.lunar.launcher.model.RssData
import rasel.lunar.launcher.model.RssDataInterface
@ -32,23 +35,34 @@ import rasel.lunar.launcher.model.TelegramData
import rasel.lunar.launcher.model.TelegramFrom
import rasel.lunar.launcher.model.TelegramMessage
import rasel.lunar.launcher.model.WeatherForcast
import rasel.lunar.launcher.utils.BLog
import kotlin.reflect.KClass
class CustMigration : AutomaticSchemaMigration {
override fun migrate(migrationContext: AutomaticSchemaMigration.MigrationContext) {
BLog.LOGE(migrationContext.oldRealm.configuration.schemaVersion.toString())
BLog.LOGE(migrationContext.newRealm.configuration.schemaVersion.toString())
}
}
object WorkersDb {
val clazz : Set<KClass<out BaseRealmObject>> = setOf(RssData::class, NotificationItem::class, AppInfo::class,SimpleContact::class, RecentCall::class, RecentSms::class, CurrentPlayItem::class,
TelegramBotUpdate::class, TelegramData::class, TelegramMessage::class, TelegramChat::class, BotCommandEentitie::class, TelegramFrom::class,
WeatherForcast::class, Location::class, Current::class, Forecast::class, Condition::class, Forecastday::class, Day::class, Astro::class, Hour::class
)
WeatherForcast::class, Location::class, Current::class, Forecast::class, Condition::class, Forecastday::class, Day::class, Astro::class, Hour::class,
LocationLog::class
)
val schemaVersion : Long = 0L
private var pRealm : Realm? = null
fun getRealm() : Realm {
if (pRealm == null) {
if (pRealm == null || pRealm?.isClosed() == true) {
pRealm = Realm.open(RealmConfiguration.Builder(clazz as Set<KClass<out TypedRealmObject>>)
.migration(CustMigration(),true)
.schemaVersion(schemaVersion)
.deleteRealmIfMigrationNeeded()
.build())
@ -159,4 +173,14 @@ object WorkersDb {
}
}
fun push(loc: LocationLog) {
getRealm().writeBlocking {
try {
this.copyToRealm(loc, UpdatePolicy.ALL)
} catch (e : Exception) {
}
}
}
}

View File

@ -14,6 +14,9 @@ import rasel.lunar.launcher.model.others.Youtube
import rasel.lunar.launcher.utils.RssList
class YoutubeGetter : BaseGetter {
companion object {
val YT_WORK_TAG = "YoutubeGetter"
}
var rssUrls = arrayListOf<String>()
constructor(context: Context, workerParams: WorkerParameters) : super(context, workerParams) {

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="800dp"
android:height="800dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M309.5,494.1c-1.9,0 -3.5,0.3 -4.7,0.8 1.6,-0.5 3.4,-0.8 5.2,-0.8h-0.5zM845.1,707.5c0.1,-1 0.2,-2 0.4,-2.9 -0.2,0.4 -0.3,1.4 -0.4,2.9zM880.9,313.3c0,-0 0,-0.1 0,-0.1v-0.5c0,0.2 0,0.4 -0,0.6zM845.1,313.2c0,0 0,0.1 0,0.1 -0,-0.2 -0,-0.4 -0,-0.6v0.5zM866.7,849.4a348,348 0,0 0,-32.7 -107.5c-3.3,-6.6 -6.7,-13.1 -10.4,-19.5a0.2,0.2 0,0 0,-0 -0.1c-15.9,-26.9 -35.3,-51.8 -58,-74.1l-0,-0c-4.9,-4.8 -10,-9.6 -15.2,-14.1 -37.3,-32.7 -80.3,-56.9 -126.3,-71.7 8.3,-4.6 16.4,-9.8 24.1,-15.5 8.8,-6.5 17.2,-13.7 25,-21.5 41.4,-41.4 64.2,-96.4 64.2,-155 0,-58.5 -22.8,-113.6 -64.2,-155 -40.6,-40.6 -94.4,-63.3 -151.8,-64.2 -0.9,-0 -1.8,-0 -2.7,-0 -0.9,0 -1.8,0 -2.7,0 -57.3,0.8 -111.1,23.5 -151.8,64.2 -41.4,41.4 -64.2,96.4 -64.2,155 0,58.5 22.8,113.6 64.2,155 7.9,7.9 16.2,15.1 25,21.5 7.7,5.7 15.8,10.9 24.1,15.5 -45.9,14.7 -89,39 -126.3,71.7 -5.2,4.6 -10.3,9.3 -15.2,14.1 -22.7,22.3 -42.2,47.2 -58,74.1 -3.7,6.4 -7.1,12.9 -10.4,19.5a348,348 0,0 0,-32.7 107.5c-1.6,12 6.8,23 18.8,24.6 1,0.1 2,0.2 3,0.2 0.9,0 1.8,-0.1 2.6,-0.2 8.7,-1.9 15.7,-9 17,-18.3 10.1,-69.3 43.1,-132.3 90.6,-180.3 56.4,-57 133.1,-92.7 216,-92.9h0.5c82.7,0.3 159.3,36 215.5,92.9 47.5,48 80.5,111 90.6,180.3 1.4,9.3 8.3,16.3 17,18.2 0,0 0,0 0.1,0 0.9,0.1 1.7,0.2 2.6,0.2 1,0 2,-0.1 3,-0.2 12,-1.6 20.4,-12.6 18.8,-24.6zM518.2,545.9c-0.4,0 -0.9,0 -1.3,-0 -81.8,-0.6 -154.7,-57.4 -174.7,-133.7 -0.2,-0.8 -0.4,-1.7 -0.6,-2.5 -3.1,-12.6 -4.8,-25.7 -4.8,-39.2s1.7,-26.7 4.8,-39.5c0.2,-0.9 0.4,-1.7 0.6,-2.6 20,-78.1 93.7,-140.3 176,-140.3h0.9c82.3,0 155.9,62.1 176,140.3 0.2,0.9 0.4,1.7 0.6,2.6 3.1,12.8 4.8,26.1 4.8,39.5 0,13.4 -1.7,26.5 -4.8,39.2 -0.2,0.8 -0.4,1.7 -0.6,2.5 -19.9,76.2 -92.9,133.1 -174.7,133.7 -0.8,0 -1.5,0 -2.3,0z"
android:fillColor="#000000"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="800dp"
android:height="800dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M885.7,741.4L515,741.4l-105.4,105.4c-0.8,0.8 -1.8,1.1 -2.6,1.7 -0.8,0.6 -1.3,1.4 -2.2,1.9 -0.4,0.2 -0.9,0.2 -1.3,0.4 -1.5,0.7 -3.1,1.2 -4.7,1.5 -1.2,0.3 -2.4,0.6 -3.6,0.7 -1.6,0.1 -3,-0.1 -4.6,-0.3 -1.4,-0.2 -2.7,-0.3 -4,-0.8 -1.2,-0.4 -2.3,-1 -3.4,-1.6 -1.6,-0.8 -3,-1.7 -4.3,-2.9 -0.3,-0.3 -0.8,-0.4 -1.1,-0.7 -0.5,-0.5 -0.7,-1.3 -1.2,-1.8 -0.7,-0.9 -1.7,-1.5 -2.3,-2.5L314.3,741.4L169.8,741.4c-49.4,0 -89.5,-40.1 -89.5,-89.5L80.4,226.9c0,-49.4 40.1,-89.5 89.5,-89.5h715.9c49.4,0 89.5,40.1 89.5,89.5v425.1c0,49.4 -40.1,89.5 -89.5,89.5zM307.1,729.3c-1.2,-2.1 -1.8,-4.3 -2.3,-6.5 0.6,3.5 1.9,6.6 3.9,9.3l-1.6,-2.8zM312,702.3c-0.6,0.5 -1.2,0.9 -1.7,1.5 0.5,-0.5 1.2,-1 1.7,-1.5zM304.3,720.2c-0.1,-1.2 0.2,-2.3 0.3,-3.5 -0.1,0.8 -0.5,1.5 -0.5,2.4 0,0.4 0.2,0.7 0.2,1.1zM306.6,709.2c-0.3,0.6 -0.7,1.2 -0.9,1.8 0.2,-0.6 0.6,-1.2 0.9,-1.8zM930.5,226.9c0,-24.7 -20,-44.7 -44.7,-44.7L169.8,182.1c-24.7,0 -44.7,20 -44.7,44.7L125.1,651.9c0,24.7 20,44.7 44.7,44.7h156.6c-0.3,0 -0.6,0.2 -0.9,0.2 8,-0.3 16,3.3 20.3,10.6l51.8,87.4 91.7,-91.8c4.6,-4.6 10.7,-6.7 16.7,-6.5h379.7c24.7,0 44.7,-20 44.7,-44.7L930.5,226.9zM317,698.9c0.9,-0.4 1.8,-0.6 2.7,-0.9 -0.9,0.3 -1.9,0.5 -2.7,0.9zM729.1,473c-24.7,0 -44.7,-20 -44.7,-44.7 0,-24.7 20,-44.7 44.7,-44.7 24.7,0 44.7,20 44.7,44.7s-20,44.7 -44.7,44.7zM527.8,473c-24.7,0 -44.7,-20 -44.7,-44.7 0,-24.7 20,-44.7 44.7,-44.7s44.7,20 44.7,44.7 -20,44.7 -44.7,44.7zM326.4,473c-24.7,0 -44.7,-20 -44.7,-44.7 0,-24.7 20,-44.7 44.7,-44.7s44.7,20 44.7,44.7 -20,44.7 -44.7,44.7z"
android:fillColor="#000000"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="800dp"
android:height="800dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M737.6,934.4c-342.4,0 -624.8,-258.4 -656.8,-600.8v-0.8c-0.8,-5.6 -1.6,-12.8 -2.4,-19.2 0,-4.8 -0.8,-10.4 -0.8,-14.4 0.8,-70.4 36,-135.2 95.2,-175.2 30.4,-20.8 66.4,-32.8 103.2,-34.4h12.8c63.2,0 123.2,28 163.2,76.8 44,52.8 58.4,123.2 40.8,192 -17.6,68 -69.6,121.6 -138.4,144l-22.4,7.2 14.4,18.4c63.2,80 140,143.2 228.8,188.8l18.4,9.6 4.8,-20c16,-72 80.8,-125.6 158.4,-129.6h8c94.4,0 173.6,72 181.6,164.8 2.4,25.6 -1.6,51.2 -9.6,76 -22.4,62.4 -77.6,107.2 -144,116.8 -4.8,0.8 -8.8,0.8 -13.6,1.6 -13.6,-2.4 -28,-1.6 -41.6,-1.6zM117.6,328c30.4,324 296.8,568 620,568 12.8,0 26.4,-0.8 40,-1.6h3.2c2.4,0 4.8,0 7.2,-0.8 52.8,-7.2 96,-43.2 114.4,-92 7.2,-19.2 9.6,-39.2 8,-60 -5.6,-72 -69.6,-130.4 -141.6,-130.4h-6.4c-62.4,4 -115.2,46.4 -130.4,105.6 -5.6,20.8 -27.2,36.8 -50.4,36.8 -8,0 -15.2,-1.6 -21.6,-4.8 -110.4,-56 -204.8,-140.8 -274.4,-244 -4,-5.6 -4,-12.8 -1.6,-18.4 3.2,-6.4 9.6,-11.2 16.8,-12 74.4,-4.8 139.2,-56 157.6,-125.6 15.2,-56.8 2.4,-115.2 -33.6,-158.4 -33.6,-40 -82.4,-63.2 -134.4,-63.2H280c-30.4,1.6 -60,12 -84.8,28.8 -48.8,32 -78.4,86.4 -78.4,144V312c-0.8,4.8 0,10.4 0.8,16z"
android:fillColor="#000000"/>
</vector>

View File

@ -8,37 +8,52 @@
android:clickable="true"
android:focusableInTouchMode="true">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/appNameInputLayout"
android:layout_width="match_parent"
<TextView
android:id="@+id/appName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="@dimen/zero"
android:textSize="30dp"
android:gravity="center"
app:hintEnabled="false"
app:boxStrokeWidth="@dimen/zero"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" >
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:padding="@dimen/eight"
android:inputType="textNoSuggestions"/>
<TextView
android:id="@+id/totalTouch"
android:layout_margin="20dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/appName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center_vertical|left"
android:padding="@dimen/eight"
android:inputType="textNoSuggestions"
/>
<TextView
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/appName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="@dimen/zero"
android:gravity="center"
android:padding="@dimen/eight"
android:inputType="textNoSuggestions"
android:textAppearance="@style/TextAppearance.Material3.TitleLarge" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/lastTouchDate"
android:layout_margin="20dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/appName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center_vertical|right"
android:padding="@dimen/eight"
android:inputType="textNoSuggestions"
/>
<TextView
android:id="@+id/appPackage"
style="@style/Widget.Material3.Button.TextButton"
android:textSize="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/eight"
app:layout_constraintTop_toBottomOf="@id/totalTouch"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/appNameInputLayout" />
app:layout_constraintStart_toStartOf="parent"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/activityBrowser"
@ -68,10 +83,10 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/appPackage" />
<com.google.android.material.button.MaterialButtonToggleGroup
<View
android:id="@+id/favGroup"
android:layout_width="@dimen/zero"
android:layout_height="wrap_content"
android:layout_height="1dp"
android:layout_marginTop="@dimen/eight"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"

View File

@ -17,12 +17,36 @@
app:layout_constraintRight_toRightOf="parent"
android:layout_height="wrap_content"
android:minWidth="@dimen/zero"
android:textSize="28dp"
android:gravity="center"
android:padding="@dimen/eight"
android:inputType="textNoSuggestions"
/>
<TextView
android:id="@+id/totalTouch"
android:layout_margin="20dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/appName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center_vertical|left"
android:padding="@dimen/eight"
android:inputType="textNoSuggestions"
/>
<TextView
android:id="@+id/lastTouchDate"
android:layout_margin="20dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/appName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center_vertical|right"
android:padding="@dimen/eight"
android:inputType="textNoSuggestions"
/>
<TextView
android:textSize="30dp"
android:id="@+id/phoneNumber"
style="@style/Widget.Material3.Button.TextButton"
android:layout_width="wrap_content"
@ -30,115 +54,48 @@
android:layout_marginTop="@dimen/eight"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/appName" />
app:layout_constraintTop_toBottomOf="@+id/totalTouch" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/activityBrowser"
style="@style/Widget.Material3.ExtendedFloatingActionButton.Surface"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/eight"
android:contentDescription="@null"
android:src="@drawable/ic_activity"
android:tooltipText="@string/activity_browser"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/detailedInfo"
app:layout_constraintTop_toBottomOf="@+id/phoneNumber" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/detailedInfo"
style="@style/Widget.Material3.ExtendedFloatingActionButton.Surface"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/eight"
android:layout_marginEnd="@dimen/eight"
android:contentDescription="@null"
android:src="@drawable/ic_info"
android:tooltipText="@string/detailed_info"
app:layout_constraintEnd_toStartOf="@id/activityBrowser"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/phoneNumber" />
<com.google.android.material.button.MaterialButtonToggleGroup
android:id="@+id/favGroup"
android:layout_width="@dimen/zero"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/eight"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/detailedInfo"
app:singleSelection="true" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/appInfo"
style="@style/Widget.Material3.ExtendedFloatingActionButton.Surface"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/eight"
android:layout_marginEnd="@dimen/eight"
android:contentDescription="@null"
android:src="@drawable/ic_info2"
android:tooltipText="@string/app_info"
app:layout_constraintEnd_toStartOf="@id/appFreeform"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/favGroup" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/appFreeform"
style="@style/Widget.Material3.ExtendedFloatingActionButton.Surface"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/eight"
android:layout_marginEnd="@dimen/eight"
android:contentDescription="@null"
android:src="@drawable/ic_pip"
android:tooltipText="@string/freeform"
app:layout_constraintEnd_toStartOf="@id/appStore"
app:layout_constraintStart_toEndOf="@id/appInfo"
app:layout_constraintTop_toBottomOf="@+id/favGroup" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/appStore"
style="@style/Widget.Material3.ExtendedFloatingActionButton.Surface"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/eight"
android:layout_marginEnd="@dimen/eight"
android:contentDescription="@null"
android:src="@drawable/ic_store"
android:tooltipText="@string/app_store"
app:layout_constraintEnd_toStartOf="@id/appShare"
app:layout_constraintStart_toEndOf="@id/appFreeform"
app:layout_constraintTop_toBottomOf="@+id/favGroup" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/appShare"
style="@style/Widget.Material3.ExtendedFloatingActionButton.Surface"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/eight"
android:layout_marginEnd="@dimen/eight"
android:contentDescription="@null"
android:src="@drawable/ic_share"
android:tooltipText="@string/share"
app:layout_constraintEnd_toStartOf="@id/appUninstall"
app:layout_constraintStart_toEndOf="@id/appStore"
app:layout_constraintTop_toBottomOf="@+id/favGroup" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/appUninstall"
style="@style/Widget.Material3.ExtendedFloatingActionButton.Surface"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/eight"
android:contentDescription="@null"
android:src="@drawable/ic_delete"
android:tooltipText="@string/uninstall"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/appShare"
app:layout_constraintTop_toBottomOf="@+id/favGroup"
app:tint="@android:color/holo_red_light" />
<LinearLayout
app:layout_constraintTop_toBottomOf="@id/phoneNumber"
android:gravity="center"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<rasel.lunar.launcher.view.CircleImageView
app:civ_circle_background_color="#77FFFFFF"
app:civ_border_width="8dp"
app:civ_border_color="#77FFFFFF"
android:adjustViewBounds="true"
android:layout_width="80dp"
android:layout_height="80dp"
android:id="@+id/detailedInfo"
android:layout_margin="@dimen/eight"
android:src="@drawable/contact"
/>
<rasel.lunar.launcher.view.CircleImageView
app:civ_circle_background_color="#77FFFFFF"
app:civ_border_width="8dp"
app:civ_border_color="#77FFFFFF"
android:adjustViewBounds="true"
android:layout_width="80dp"
android:layout_height="80dp"
android:id="@+id/sms"
android:layout_margin="@dimen/eight"
android:src="@drawable/message"
/>
<rasel.lunar.launcher.view.CircleImageView
app:civ_circle_background_color="#77FFFFFF"
app:civ_border_width="8dp"
app:civ_border_color="#77FFFFFF"
android:adjustViewBounds="true"
android:layout_width="80dp"
android:layout_height="80dp"
android:id="@+id/call"
android:layout_margin="@dimen/eight"
android:src="@drawable/phonecall"
/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:padding="@dimen/twelve"
android:clickable="true"
android:focusableInTouchMode="true">
<TextView
android:id="@+id/logs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -18,9 +18,8 @@
android:id="@+id/input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionDone"
android:inputType="textPassword" />
android:inputType="text" />
</com.google.android.material.textfield.TextInputLayout>
</androidx.constraintlayout.widget.ConstraintLayout>