This commit is contained in:
lunaticbum 2024-09-10 17:40:52 +09:00
parent e250a06d39
commit 5929aee345
24 changed files with 864 additions and 263 deletions

View File

@ -34,6 +34,10 @@
tools:ignore="QueryAllPackagesPermission" /> tools:ignore="QueryAllPackagesPermission" />
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" /> <uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<queries> <queries>
<intent> <intent>
@ -64,7 +68,6 @@
android:name=".LauncherActivity" android:name=".LauncherActivity"
android:theme="@style/Theme.LunarLauncher.Starting" android:theme="@style/Theme.LunarLauncher.Starting"
android:launchMode="singleInstance" android:launchMode="singleInstance"
android:screenOrientation="portrait"
android:excludeFromRecents="true" android:excludeFromRecents="true"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|screenLayout|layoutDirection" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|screenLayout|layoutDirection"
android:windowSoftInputMode="adjustResize" android:windowSoftInputMode="adjustResize"
@ -151,5 +154,7 @@
<action android:name="android.provider.Telephony.MMS_RECEIVED" /> <action android:name="android.provider.Telephony.MMS_RECEIVED" />
</intent-filter> </intent-filter>
</receiver> </receiver>
</application> </application>
</manifest> </manifest>

View File

@ -0,0 +1,168 @@
package android.print;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class PDFPrint {
public static void generatePDFFromHTML(final Context context, final File file, final String htmlString, final OnPDFPrintListener onPDFPrintListener) {
final WebView mWebView = new WebView(context);
mWebView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
PrintAttributes printAttributes = new PrintAttributes.Builder()
.setMediaSize(PrintAttributes.MediaSize.ISO_A4)
.setResolution(new PrintAttributes.Resolution("RESOLUTION_ID", "RESOLUTION_ID", 600, 600))
.setMinMargins(PrintAttributes.Margins.NO_MARGINS)
.build();
final PrintDocumentAdapter documentAdapter = mWebView.createPrintDocumentAdapter(file.getName());
documentAdapter.onLayout(null, printAttributes, null, new PrintDocumentAdapter.LayoutResultCallback() {
@Override
public void onLayoutFinished(PrintDocumentInfo info, boolean changed) {
documentAdapter.onWrite(new PageRange[]{PageRange.ALL_PAGES}, getOutputFile(file), null, new PrintDocumentAdapter.WriteResultCallback() {
@Override
public void onWriteCancelled() {
super.onWriteCancelled();
onPDFPrintListener.onError(new Exception("PDF Write cancelled."));
}
@Override
public void onWriteFailed(CharSequence error) {
super.onWriteFailed(error);
onPDFPrintListener.onError(new Exception(error.toString()));
}
@Override
public void onWriteFinished(PageRange[] pages) {
super.onWriteFinished(pages);
onPDFPrintListener.onSuccess(file);
}
});
}
}, null);
}
});
mWebView.loadData(htmlString.replaceAll("#", "%23"), "text/HTML", "UTF-8");
}
public static void generatePDFFromWebView(final File file, final WebView webView, final OnPDFPrintListener onPDFPrintListener) {
PrintAttributes printAttributes = new PrintAttributes.Builder()
.setMediaSize(PrintAttributes.MediaSize.ISO_A4)
.setResolution(new PrintAttributes.Resolution("RESOLUTION_ID", "RESOLUTION_ID", 600, 600))
.setMinMargins(PrintAttributes.Margins.NO_MARGINS)
.build();
final PrintDocumentAdapter documentAdapter = webView.createPrintDocumentAdapter(file.getName());
documentAdapter.onLayout(null, printAttributes, null, new PrintDocumentAdapter.LayoutResultCallback() {
@Override
public void onLayoutFinished(PrintDocumentInfo info, boolean changed) {
documentAdapter.onWrite(new PageRange[]{PageRange.ALL_PAGES}, getOutputFile(file), null, new PrintDocumentAdapter.WriteResultCallback() {
@Override
public void onWriteCancelled() {
super.onWriteCancelled();
onPDFPrintListener.onError(new Exception("PDF Write cancelled."));
}
@Override
public void onWriteFailed(CharSequence error) {
super.onWriteFailed(error);
try {
if (error != null && error.toString().length() > 0) {
onPDFPrintListener.onError(new Exception(error.toString()));
} else {
onPDFPrintListener.onError(new Exception("Empty Page"));
}
}catch (Exception e) {e.printStackTrace();}
}
@Override
public void onWriteFinished(PageRange[] pages) {
super.onWriteFinished(pages);
onPDFPrintListener.onSuccess(file);
}
});
}
}, null);
}
private static ParcelFileDescriptor getOutputFile(File file) {
try {
if (!file.exists()) {
file.createNewFile();
}
return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static PrintJob printPDF(final Activity activity, final File pdfFileToPrint, final PrintAttributes printAttributes) {
PrintManager printManager = (PrintManager) activity.getSystemService(Context.PRINT_SERVICE);
String jobName = Long.valueOf(System.currentTimeMillis()).toString();
return printManager.print(jobName, new PrintDocumentAdapter() {
@Override
public void onWrite(PageRange[] pages, ParcelFileDescriptor destination, CancellationSignal cancellationSignal, WriteResultCallback callback) {
InputStream input = null;
OutputStream output = null;
try {
input = new FileInputStream(pdfFileToPrint);
output = new FileOutputStream(destination.getFileDescriptor());
byte[] buf = new byte[1024];
int bytesRead;
while ((bytesRead = input.read(buf)) > 0) {
output.write(buf, 0, bytesRead);
}
callback.onWriteFinished(new PageRange[]{PageRange.ALL_PAGES});
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
input.close();
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal, LayoutResultCallback callback, Bundle extras) {
if (cancellationSignal.isCanceled()) {
callback.onLayoutCancelled();
return;
}
PrintDocumentInfo pdi = new PrintDocumentInfo.Builder(pdfFileToPrint.getName()).setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).build();
callback.onLayoutFinished(pdi, true);
}
}, printAttributes);
}
public interface OnPDFPrintListener {
void onSuccess(File file);
void onError(Exception exception);
}
}

View File

@ -35,6 +35,9 @@ import android.net.Uri
import android.net.http.SslError import android.net.http.SslError
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Environment
import android.os.Environment.isExternalStorageManager
import android.print.PDFPrint
import android.provider.Settings import android.provider.Settings
import android.telephony.TelephonyManager import android.telephony.TelephonyManager
import android.view.View import android.view.View
@ -53,12 +56,13 @@ import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
import androidx.core.content.FileProvider
import androidx.core.net.toUri
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding import androidx.core.view.updatePadding
import androidx.lifecycle.ReportFragment.Companion.reportFragment
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2 import androidx.viewpager2.widget.ViewPager2
import androidx.work.ExistingPeriodicWorkPolicy import androidx.work.ExistingPeriodicWorkPolicy
@ -109,12 +113,15 @@ import rasel.lunar.launcher.workers.RuliWebGetter
import rasel.lunar.launcher.workers.TheQooGetter import rasel.lunar.launcher.workers.TheQooGetter
import rasel.lunar.launcher.workers.WorkersDb import rasel.lunar.launcher.workers.WorkersDb
import rasel.lunar.launcher.workers.YoutubeGetter import rasel.lunar.launcher.workers.YoutubeGetter
import java.io.File
import java.io.IOException
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Calendar import java.util.Calendar
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
import java.util.concurrent.Executors import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.random.Random
internal class LauncherActivity : AppCompatActivity() { internal class LauncherActivity : AppCompatActivity() {
@ -150,7 +157,7 @@ internal class LauncherActivity : AppCompatActivity() {
PeriodicWorkRequestBuilder<RecentSmsGetter>(longTimePeriod, TimeUnit.MINUTES) PeriodicWorkRequestBuilder<RecentSmsGetter>(longTimePeriod, TimeUnit.MINUTES)
.addTag(SMS_WORK_TAG) .addTag(SMS_WORK_TAG)
.build()) .build())
}, 2, TimeUnit.SECONDS) }, 1, TimeUnit.SECONDS)
} }
fun refreshCalls() { fun refreshCalls() {
Executors.newSingleThreadScheduledExecutor().schedule({ Executors.newSingleThreadScheduledExecutor().schedule({
@ -161,9 +168,10 @@ internal class LauncherActivity : AppCompatActivity() {
PeriodicWorkRequestBuilder<RecentCallGetter>(longTimePeriod, TimeUnit.MINUTES) PeriodicWorkRequestBuilder<RecentCallGetter>(longTimePeriod, TimeUnit.MINUTES)
.addTag(CALL_WORK_TAG) .addTag(CALL_WORK_TAG)
.build()) .build())
}, 2, TimeUnit.SECONDS) }, 1, TimeUnit.SECONDS)
} }
fun refreshFeeds() { fun refreshFeeds() {
var delay = 5L
Executors.newSingleThreadScheduledExecutor().schedule({ Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(FEDDS_WORK_TAG) mWorkManager?.cancelAllWorkByTag(FEDDS_WORK_TAG)
mWorkManager?.enqueueUniquePeriodicWork( mWorkManager?.enqueueUniquePeriodicWork(
@ -171,10 +179,8 @@ internal class LauncherActivity : AppCompatActivity() {
PeriodicWorkRequestBuilder<NewsFeedsGetter>(shortTimePeriod, TimeUnit.MINUTES) PeriodicWorkRequestBuilder<NewsFeedsGetter>(shortTimePeriod, TimeUnit.MINUTES)
.addTag(FEDDS_WORK_TAG) .addTag(FEDDS_WORK_TAG)
.build()) .build())
}, 2, TimeUnit.SECONDS) }, delay, TimeUnit.SECONDS)
} delay= delay + 5
fun refreshYoutube() {
Executors.newSingleThreadScheduledExecutor().schedule({ Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(YT_WORK_TAG) mWorkManager?.cancelAllWorkByTag(YT_WORK_TAG)
mWorkManager?.enqueueUniquePeriodicWork( mWorkManager?.enqueueUniquePeriodicWork(
@ -182,9 +188,8 @@ internal class LauncherActivity : AppCompatActivity() {
PeriodicWorkRequestBuilder<YoutubeGetter>(longTimePeriod, TimeUnit.MINUTES) PeriodicWorkRequestBuilder<YoutubeGetter>(longTimePeriod, TimeUnit.MINUTES)
.addTag(YT_WORK_TAG) .addTag(YT_WORK_TAG)
.build()) .build())
}, 2, TimeUnit.SECONDS) }, delay, TimeUnit.SECONDS)
} delay= delay + 5
fun refreshReddit() {
Executors.newSingleThreadScheduledExecutor().schedule({ Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(REDDIT_WORK_TAG) mWorkManager?.cancelAllWorkByTag(REDDIT_WORK_TAG)
mWorkManager?.enqueueUniquePeriodicWork( mWorkManager?.enqueueUniquePeriodicWork(
@ -192,10 +197,8 @@ internal class LauncherActivity : AppCompatActivity() {
PeriodicWorkRequestBuilder<RedditGetter>(midTimePeriod, TimeUnit.MINUTES) PeriodicWorkRequestBuilder<RedditGetter>(midTimePeriod, TimeUnit.MINUTES)
.addTag(REDDIT_WORK_TAG) .addTag(REDDIT_WORK_TAG)
.build()) .build())
}, 2, TimeUnit.SECONDS) }, delay, TimeUnit.SECONDS)
} delay= delay + 5
fun refreshComics() {
refreshComics3()
Executors.newSingleThreadScheduledExecutor().schedule({ Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(COMIC_WORK_TAG) mWorkManager?.cancelAllWorkByTag(COMIC_WORK_TAG)
mWorkManager?.enqueueUniquePeriodicWork( mWorkManager?.enqueueUniquePeriodicWork(
@ -203,10 +206,8 @@ internal class LauncherActivity : AppCompatActivity() {
PeriodicWorkRequestBuilder<FmKoreaGetter>(midTimePeriod, TimeUnit.MINUTES) PeriodicWorkRequestBuilder<FmKoreaGetter>(midTimePeriod, TimeUnit.MINUTES)
.addTag(COMIC_WORK_TAG) .addTag(COMIC_WORK_TAG)
.build()) .build())
refreshComics2() }, delay, TimeUnit.SECONDS)
}, 2, TimeUnit.SECONDS) delay= delay + 5
}
fun refreshComics2() {
Executors.newSingleThreadScheduledExecutor().schedule({ Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(COMIC2_WORK_TAG) mWorkManager?.cancelAllWorkByTag(COMIC2_WORK_TAG)
mWorkManager?.enqueueUniquePeriodicWork( mWorkManager?.enqueueUniquePeriodicWork(
@ -214,10 +215,8 @@ internal class LauncherActivity : AppCompatActivity() {
PeriodicWorkRequestBuilder<DotaxGetter>(midTimePeriod, TimeUnit.MINUTES) PeriodicWorkRequestBuilder<DotaxGetter>(midTimePeriod, TimeUnit.MINUTES)
.addTag(COMIC2_WORK_TAG) .addTag(COMIC2_WORK_TAG)
.build()) .build())
}, 2, TimeUnit.SECONDS) }, delay, TimeUnit.SECONDS)
} delay= delay + 5
fun refreshComics3() {
Executors.newSingleThreadScheduledExecutor().schedule({ Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(ClienGetter.TAG) mWorkManager?.cancelAllWorkByTag(ClienGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork( mWorkManager?.enqueueUniquePeriodicWork(
@ -225,9 +224,8 @@ internal class LauncherActivity : AppCompatActivity() {
PeriodicWorkRequestBuilder<ClienGetter>(midTimePeriod, TimeUnit.MINUTES) PeriodicWorkRequestBuilder<ClienGetter>(midTimePeriod, TimeUnit.MINUTES)
.addTag(ClienGetter.TAG) .addTag(ClienGetter.TAG)
.build()) .build())
refreshArca() }, delay, TimeUnit.SECONDS)
}, 2, TimeUnit.SECONDS) delay= delay + 5
Executors.newSingleThreadScheduledExecutor().schedule({ Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(DCGetter.TAG) mWorkManager?.cancelAllWorkByTag(DCGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork( mWorkManager?.enqueueUniquePeriodicWork(
@ -235,10 +233,8 @@ internal class LauncherActivity : AppCompatActivity() {
PeriodicWorkRequestBuilder<DCGetter>(midTimePeriod, TimeUnit.MINUTES) PeriodicWorkRequestBuilder<DCGetter>(midTimePeriod, TimeUnit.MINUTES)
.addTag(DCGetter.TAG) .addTag(DCGetter.TAG)
.build()) .build())
refreshArca() }, delay, TimeUnit.SECONDS)
}, 2, TimeUnit.SECONDS) delay= delay + 5
Executors.newSingleThreadScheduledExecutor().schedule({ Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(RuliWebGetter.TAG) mWorkManager?.cancelAllWorkByTag(RuliWebGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork( mWorkManager?.enqueueUniquePeriodicWork(
@ -246,9 +242,8 @@ internal class LauncherActivity : AppCompatActivity() {
PeriodicWorkRequestBuilder<RuliWebGetter>(midTimePeriod, TimeUnit.MINUTES) PeriodicWorkRequestBuilder<RuliWebGetter>(midTimePeriod, TimeUnit.MINUTES)
.addTag(RuliWebGetter.TAG) .addTag(RuliWebGetter.TAG)
.build()) .build())
refreshArca() }, delay, TimeUnit.SECONDS)
}, 2, TimeUnit.SECONDS) delay= delay + 5
Executors.newSingleThreadScheduledExecutor().schedule({ Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(TheQooGetter.TAG) mWorkManager?.cancelAllWorkByTag(TheQooGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork( mWorkManager?.enqueueUniquePeriodicWork(
@ -256,12 +251,8 @@ internal class LauncherActivity : AppCompatActivity() {
PeriodicWorkRequestBuilder<TheQooGetter>(midTimePeriod, TimeUnit.MINUTES) PeriodicWorkRequestBuilder<TheQooGetter>(midTimePeriod, TimeUnit.MINUTES)
.addTag(TheQooGetter.TAG) .addTag(TheQooGetter.TAG)
.build()) .build())
refreshArca() }, delay, TimeUnit.SECONDS)
}, 2, TimeUnit.SECONDS) delay= delay + 5
}
fun refreshArca() {
Executors.newSingleThreadScheduledExecutor().schedule({ Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(ArcaGetter.TAG) mWorkManager?.cancelAllWorkByTag(ArcaGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork( mWorkManager?.enqueueUniquePeriodicWork(
@ -270,7 +261,7 @@ internal class LauncherActivity : AppCompatActivity() {
.addTag(ArcaGetter.TAG) .addTag(ArcaGetter.TAG)
.build()) .build())
}, 2, TimeUnit.SECONDS) }, delay, TimeUnit.SECONDS)
} }
fun workmanager() : WorkManager? { fun workmanager() : WorkManager? {
@ -337,14 +328,7 @@ internal class LauncherActivity : AppCompatActivity() {
refreshSms() refreshSms()
refreshCalls() refreshCalls()
refreshFeeds() refreshFeeds()
refreshYoutube()
refreshReddit()
refreshComics()
// if (listItem.size < 2) {
// lActivity?.doWebParseStart(jGuruRanks) {
//
// }
// }
} }
override fun onDestroy() { override fun onDestroy() {
@ -370,7 +354,20 @@ internal class LauncherActivity : AppCompatActivity() {
val intent = Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS) val intent = Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS)
startActivity(intent) startActivity(intent)
} }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (!isExternalStorageManager()) {
try {
startActivityForResult(Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION).apply {
addCategory("android.intent.category.DEFAULT")
data = Uri.parse(String.format("package:%s", applicationContext.packageName))
}, 300)
} catch (e: Exception) {
startActivityForResult(Intent().apply {
action = Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION
}, 300)
}
}
}
} }
private fun welcomeDialog() { private fun welcomeDialog() {
@ -536,6 +533,146 @@ internal class LauncherActivity : AppCompatActivity() {
} }
} }
fun openDrive(gmmIntentUri : Uri, pakage : String? = null) {
val mapIntent = Intent(Intent.ACTION_MEDIA_SHARED, gmmIntentUri)
pakage?.let {
mapIntent.setPackage(pakage)
}
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)
}
}
}
var callBack : CommadCallabck? = null var callBack : CommadCallabck? = null
var isF = false var isF = false
fun doWebParseStart(url : String, callBack :CommadCallabck?) { fun doWebParseStart(url : String, callBack :CommadCallabck?) {

View File

@ -62,10 +62,7 @@ import rasel.lunar.launcher.CommadCallabck
import rasel.lunar.launcher.LauncherActivity.Companion.appWidgetHost import rasel.lunar.launcher.LauncherActivity.Companion.appWidgetHost
import rasel.lunar.launcher.LauncherActivity.Companion.appWidgetManager import rasel.lunar.launcher.LauncherActivity.Companion.appWidgetManager
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
import rasel.lunar.launcher.LauncherActivity.Companion.refreshComics
import rasel.lunar.launcher.LauncherActivity.Companion.refreshFeeds import rasel.lunar.launcher.LauncherActivity.Companion.refreshFeeds
import rasel.lunar.launcher.LauncherActivity.Companion.refreshReddit
import rasel.lunar.launcher.LauncherActivity.Companion.refreshYoutube
import rasel.lunar.launcher.R import rasel.lunar.launcher.R
import rasel.lunar.launcher.databinding.FeedsBinding import rasel.lunar.launcher.databinding.FeedsBinding
import rasel.lunar.launcher.feeds.rss.RssAdapter import rasel.lunar.launcher.feeds.rss.RssAdapter
@ -228,6 +225,9 @@ internal class Feeds : Fragment() , CommadCallabck {
if (input.text.toString().trim().contains(" ")) { if (input.text.toString().trim().contains(" ")) {
val cmd = input.text.toString().trim().split(" ") val cmd = input.text.toString().trim().split(" ")
when(cmd[0]) { when(cmd[0]) {
"s" -> {
home?.queryInfos(keyword = cmd[1])
}
"jf" -> { "jf" -> {
consoleLog("on Cmd JF") consoleLog("on Cmd JF")
GlobalScope.launch { excuteGetterMostByUrl("https://javmost.to/search/movie/${cmd[1]}") } GlobalScope.launch { excuteGetterMostByUrl("https://javmost.to/search/movie/${cmd[1]}") }
@ -284,6 +284,9 @@ internal class Feeds : Fragment() , CommadCallabck {
addAll(RssDataType.values()) addAll(RssDataType.values())
remove(RssDataType.GURU) remove(RssDataType.GURU)
remove(RssDataType.Most) remove(RssDataType.Most)
})
"all" -> home?.queryInfos(arrayListOf<RssDataType>().apply {
}) })
"onews" -> home?.queryInfos(arrayListOf<RssDataType>().apply { "onews" -> home?.queryInfos(arrayListOf<RssDataType>().apply {
addAll(RssDataType.values()) addAll(RssDataType.values())
@ -307,26 +310,12 @@ internal class Feeds : Fragment() , CommadCallabck {
} }
}.start() }.start()
} }
"ytb" -> {
refreshYoutube()
consoleLog("excute refreshYoutube()")
}
"reddit" -> { "req" -> {
refreshReddit()
consoleLog("excute refreshReddit()")
}
"fedd" -> {
refreshFeeds() refreshFeeds()
consoleLog("excute refreshFeeds()") consoleLog("excute refreshFeeds()")
} }
"comic" -> {
refreshComics()
consoleLog("excute refreshComics()")
}
"taxi" -> { "taxi" -> {
consoleLog("before run State home?.binding?.alcholKatalkT?.isVisible >> ${home?.binding?.alcholKatalkT?.isVisible}") consoleLog("before run State home?.binding?.alcholKatalkT?.isVisible >> ${home?.binding?.alcholKatalkT?.isVisible}")
home?.showAl() home?.showAl()

View File

@ -22,6 +22,7 @@ import android.annotation.SuppressLint
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
import android.content.ComponentName import android.content.ComponentName
import android.content.Context import android.content.Context
import android.content.DialogInterface
import android.content.Intent import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import android.content.SharedPreferences import android.content.SharedPreferences
@ -34,10 +35,17 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.View.OnScrollChangeListener import android.view.View.OnScrollChangeListener
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.EditText
import android.widget.RadioButton
import android.widget.RadioGroup
import android.widget.TableRow
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.biometric.BiometricPrompt import androidx.biometric.BiometricPrompt
import androidx.core.content.ContextCompat.RECEIVER_EXPORTED import androidx.core.content.ContextCompat.RECEIVER_EXPORTED
import androidx.core.content.ContextCompat.registerReceiver import androidx.core.content.ContextCompat.registerReceiver
import androidx.core.view.children
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.DividerItemDecoration
@ -45,6 +53,7 @@ import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.OnScrollListener import androidx.recyclerview.widget.RecyclerView.OnScrollListener
import com.google.gson.Gson
import io.realm.kotlin.ext.query import io.realm.kotlin.ext.query
import io.realm.kotlin.notifications.InitialResults import io.realm.kotlin.notifications.InitialResults
import io.realm.kotlin.notifications.ResultsChange import io.realm.kotlin.notifications.ResultsChange
@ -53,17 +62,17 @@ import io.realm.kotlin.query.RealmResults
import io.realm.kotlin.query.Sort import io.realm.kotlin.query.Sort
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONObject import org.json.JSONObject
import org.jsoup.Jsoup
import rasel.lunar.launcher.CommadCallabck
import rasel.lunar.launcher.LauncherActivity.Companion.CALL_WORK_TAG import rasel.lunar.launcher.LauncherActivity.Companion.CALL_WORK_TAG
import rasel.lunar.launcher.LauncherActivity.Companion.SMS_WORK_TAG import rasel.lunar.launcher.LauncherActivity.Companion.SMS_WORK_TAG
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
import rasel.lunar.launcher.LauncherActivity.Companion.refreshComics
import rasel.lunar.launcher.LauncherActivity.Companion.refreshFeeds import rasel.lunar.launcher.LauncherActivity.Companion.refreshFeeds
import rasel.lunar.launcher.LauncherActivity.Companion.refreshReddit
import rasel.lunar.launcher.LauncherActivity.Companion.refreshYoutube
import rasel.lunar.launcher.LauncherActivity.Companion.workmanager import rasel.lunar.launcher.LauncherActivity.Companion.workmanager
import rasel.lunar.launcher.R import rasel.lunar.launcher.R
import rasel.lunar.launcher.databinding.LauncherHomeBinding import rasel.lunar.launcher.databinding.LauncherHomeBinding
@ -76,6 +85,7 @@ import rasel.lunar.launcher.helpers.UniUtils.Companion.canAuthenticate
import rasel.lunar.launcher.helpers.UniUtils.Companion.expandNotificationPanel import rasel.lunar.launcher.helpers.UniUtils.Companion.expandNotificationPanel
import rasel.lunar.launcher.helpers.UniUtils.Companion.lockMethod import rasel.lunar.launcher.helpers.UniUtils.Companion.lockMethod
import rasel.lunar.launcher.home.weather.WeatherExecutor import rasel.lunar.launcher.home.weather.WeatherExecutor
import rasel.lunar.launcher.model.CiliMagnet
import rasel.lunar.launcher.model.NotificationItem import rasel.lunar.launcher.model.NotificationItem
import rasel.lunar.launcher.model.RssData import rasel.lunar.launcher.model.RssData
import rasel.lunar.launcher.qaccess.QuickAccess import rasel.lunar.launcher.qaccess.QuickAccess
@ -87,12 +97,15 @@ import rasel.lunar.launcher.todos.NotificationItemAdapter
import rasel.lunar.launcher.todos.RssItemAdapter import rasel.lunar.launcher.todos.RssItemAdapter
import rasel.lunar.launcher.todos.SmsLogsAdapter import rasel.lunar.launcher.todos.SmsLogsAdapter
import rasel.lunar.launcher.utils.BLog import rasel.lunar.launcher.utils.BLog
import rasel.lunar.launcher.utils.RssList.jGuruMain
import rasel.lunar.launcher.utils.SimpleFingerGestures import rasel.lunar.launcher.utils.SimpleFingerGestures
import rasel.lunar.launcher.utils.beforeDay import rasel.lunar.launcher.utils.beforeDay
import rasel.lunar.launcher.view.TableRadioGroup
import rasel.lunar.launcher.workers.RecentCall import rasel.lunar.launcher.workers.RecentCall
import rasel.lunar.launcher.workers.RecentSms import rasel.lunar.launcher.workers.RecentSms
import rasel.lunar.launcher.workers.WorkersDb import rasel.lunar.launcher.workers.WorkersDb
import java.net.URLEncoder import java.net.URLEncoder
import java.nio.charset.Charset
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Calendar import java.util.Calendar
import java.util.Date import java.util.Date
@ -143,16 +156,12 @@ internal class LauncherHome : Fragment() {
} }
val notiUpdate = Runnable { val notiUpdate = Runnable {
if (lastedNoti?.size ?: 0 > 0) { chooseAdpater()
binding.otherCheck.text = "최근 정보[${lasted!!.size}]"
mRssAdapter.updateData(lasted!!)
// binding.infoList.smoothScrollToPosition(0)
}
} }
var lasted : RealmResults<RssData>? = null var lasted : List<RssData>? = null
var lastedNoti : RealmResults<NotificationItem>? = null var lastedNoti : List<NotificationItem>? = null
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -188,6 +197,8 @@ internal class LauncherHome : Fragment() {
binding.infoList.adapter = mRssAdapter binding.infoList.adapter = mRssAdapter
binding.notiList.adapter = mNotiAdapter binding.notiList.adapter = mNotiAdapter
binding.favAppsGroup.setOnClickListener { searchData() }
try{binding.mainList.removeOnScrollListener(onScrChanged)}catch (e : Exception){e.printStackTrace()} try{binding.mainList.removeOnScrollListener(onScrChanged)}catch (e : Exception){e.printStackTrace()}
binding.mainList.addOnScrollListener(onScrChanged) binding.mainList.addOnScrollListener(onScrChanged)
try{binding.smsList.removeOnScrollListener(onScrChanged)}catch (e : Exception){e.printStackTrace()} try{binding.smsList.removeOnScrollListener(onScrChanged)}catch (e : Exception){e.printStackTrace()}
@ -265,10 +276,11 @@ internal class LauncherHome : Fragment() {
when (changes) { when (changes) {
is UpdatedResults -> { is UpdatedResults -> {
BLog.LOGE("ResultsChange onNotificationPosted") BLog.LOGE("ResultsChange onNotificationPosted")
lastedNoti = changes.list WorkersDb.getRealm().apply {
commandHandler.removeCallbacks(infoUpdate) lastedNoti = copyFromRealm(changes.list)
commandHandler.postDelayed(infoUpdate, UPDATE_DELAY) }
commandHandler.removeCallbacks(notiUpdate)
commandHandler.postDelayed(notiUpdate, UPDATE_DELAY)
} }
else -> { else -> {
@ -277,8 +289,6 @@ internal class LauncherHome : Fragment() {
} }
} }
} }
mNotificationResult?.let { mNotiAdapter?.updateData(it) }
noticeJob?.start() noticeJob?.start()
} }
@ -298,7 +308,8 @@ internal class LauncherHome : Fragment() {
filter!!.forEach { filter!!.forEach {
rQ = rQ.query("category != $0", it.name) rQ = rQ.query("category != $0", it.name)
} }
mRssDataResult = rQ.sort("pubDate ", Sort.DESCENDING).limit(1000).find() //limit(1000)
mRssDataResult = rQ.sort("pubDate ", Sort.DESCENDING).find()
BLog.LOGE("${this} ::::: queryInfos after query find >>>> ") BLog.LOGE("${this} ::::: queryInfos after query find >>>> ")
infosJob = CoroutineScope(Dispatchers.Default).launch { infosJob = CoroutineScope(Dispatchers.Default).launch {
mRssDataResult?.asFlow()?.collect { changes: ResultsChange<RssData> -> mRssDataResult?.asFlow()?.collect { changes: ResultsChange<RssData> ->
@ -307,7 +318,10 @@ internal class LauncherHome : Fragment() {
when (changes) { when (changes) {
is InitialResults -> { is InitialResults -> {
BLog.LOGE("${this} ::::: queryInfos after changes size >>>> ${changes.list.size}") BLog.LOGE("${this} ::::: queryInfos after changes size >>>> ${changes.list.size}")
lasted = changes.list WorkersDb.getRealm().apply {
lasted = copyFromRealm(changes.list)
}
commandHandler.postDelayed(infoUpdate, UPDATE_DELAY * 3) commandHandler.postDelayed(infoUpdate, UPDATE_DELAY * 3)
} }
is UpdatedResults -> { is UpdatedResults -> {
@ -319,11 +333,54 @@ internal class LauncherHome : Fragment() {
} }
} }
} }
mRssDataResult?.let { infosJob?.start()
BLog.LOGE("${this} ::::: queryInfos updateData >>>> ") }
// lasted = it
// commandHandler.postDelayed(infoUpdate, UPDATE_DELAY * 3) fun queryInfos(keyword : String, category : String? = null) {
mRssAdapter.updateData(it) BLog.LOGE("${this} ::::: queryInfos >>>> ${keyword}")
try { infosJob?.cancel() } catch (e:Exception) {e.printStackTrace()}
mRssDataResult = null
try {
System.gc()
}catch (e : Exception){e.printStackTrace()}
WorkersDb.getRealm().apply { writeBlocking {
delete(query<RssData>().query("pubDate < $0",beforeDay(Date(),3)).query("category != $0 || category != $1 ", RssDataType.GURU.name,RssDataType.Most.name).find())
}}
BLog.LOGE("${this} ::::: queryInfos after delete >>>> ")
var rQ = WorkersDb.getRealm().query<RssData>().query("pubDate > $0", beforeDay(Date(),3))
if(keyword.length > 0)
keyword.split("").forEach {
rQ = rQ.query("title CONTAINS $0 OR title CONTAINS $1", it.toUpperCase(), it.toLowerCase())
}
category?.let {
rQ = rQ.query("category == $0", it)
}
//limit(1000)
mRssDataResult = rQ.sort("pubDate ", Sort.DESCENDING).find()
BLog.LOGE("${this} ::::: queryInfos after query find >>>> ")
infosJob = CoroutineScope(Dispatchers.Default).launch {
mRssDataResult?.asFlow()?.collect { changes: ResultsChange<RssData> ->
commandHandler.removeCallbacks(infoUpdate)
when (changes) {
is InitialResults -> {
BLog.LOGE("${this} ::::: queryInfos after changes size >>>> ${changes.list.size}")
WorkersDb.getRealm().apply {
lasted = copyFromRealm(changes.list)
}
commandHandler.postDelayed(infoUpdate, UPDATE_DELAY * 3)
}
is UpdatedResults -> {
// lasted = changes.list
// commandHandler.postDelayed(infoUpdate, UPDATE_DELAY * 3)
}
else -> {
}
}
}
} }
infosJob?.start() infosJob?.start()
} }
@ -397,6 +454,7 @@ internal class LauncherHome : Fragment() {
binding.otherCheck.isSelected = false binding.otherCheck.isSelected = false
} else { } else {
queryInfos()
binding.otherCheck.isSelected = true binding.otherCheck.isSelected = true
views.remove(binding.infoList) views.remove(binding.infoList)
binding.infoList.scrollToPosition(0) binding.infoList.scrollToPosition(0)
@ -407,6 +465,7 @@ internal class LauncherHome : Fragment() {
if (binding.notice.isSelected ) { if (binding.notice.isSelected ) {
binding.notice.isSelected = false binding.notice.isSelected = false
} else { } else {
queryNotice()
binding.notice.isSelected = true binding.notice.isSelected = true
views.remove(binding.notiList) views.remove(binding.notiList)
binding.notiList.visibility = View.VISIBLE binding.notiList.visibility = View.VISIBLE
@ -426,16 +485,60 @@ internal class LauncherHome : Fragment() {
binding.otherCheck.setOnLongClickListener { binding.otherCheck.setOnLongClickListener {
queryInfos() queryInfos()
refreshYoutube()
refreshComics()
refreshFeeds() refreshFeeds()
refreshReddit()
true true
} }
} }
// https://www.youtube.com/results?search_query=sds // https://www.youtube.com/results?search_query=sds
fun searchData() {
val builder: AlertDialog.Builder = AlertDialog.Builder(requireContext())
builder.setTitle("Command Line")
val viewInflated: View = LayoutInflater.from(context)
.inflate(R.layout.search_layout, view as ViewGroup?, false)
val input = viewInflated.findViewById<View>(R.id.input) as EditText
val categoryz = viewInflated.findViewById<TableRadioGroup>(R.id.categoryz) as TableRadioGroup
categoryz.setMaxColumns(5)
categoryz.setMaxRows(5)
var idx = 0
RssDataType.values().reversed().toList().chunked(5).forEach {
var tb = TableRow(requireContext())
it.forEach { c ->
if(c.equals(RssDataType.NO_DATA) == false) {
tb.addView(RadioButton(requireContext()).apply {
this.tag = c.name
this.text = c.name
})
}
}
categoryz.addView(tb)
}
builder.setView(viewInflated)
builder.setPositiveButton(android.R.string.ok,
DialogInterface.OnClickListener { dialog, which ->
dialog.dismiss()
var category : String? = null
categoryz.children.forEach {
if(it is TableRow) {
it.children.forEach {
if (it is RadioButton && it.isChecked) {
(it.tag as? String)?.let { category = it }
}
}
}
}
queryInfos(keyword =input.text.toString(),category)
})
builder.setNegativeButton(android.R.string.cancel,
DialogInterface.OnClickListener { dialog, which -> dialog.cancel() })
builder.show()
}
fun showAl() { fun showAl() {
binding.alcholKatalkT.visibility = View.VISIBLE binding.alcholKatalkT.visibility = View.VISIBLE
binding.alcholKatalkT.setOnClickListener { binding.alcholKatalkT.setOnClickListener {
@ -465,61 +568,61 @@ internal class LauncherHome : Fragment() {
binding.infoList.visibility = View.INVISIBLE binding.infoList.visibility = View.INVISIBLE
binding.notiList.visibility = View.INVISIBLE binding.notiList.visibility = View.INVISIBLE
if (binding.missedCalls.isSelected) { if (binding.missedCalls.isSelected) {
if (recentCalls.size > 0 && isAdded && isResumed && isVisible) { if (recentCalls.size > 0) {
try { try {
callList.clear() callList.clear()
recentCalls.forEach { t, u -> recentCalls.forEach { t, u ->
callList.add(u) callList.add(u)
}.apply { }.apply {
callList.sortByDescending { it.date } callList.sortByDescending { it.date }
Handler(Looper.getMainLooper()).post { // Handler(Looper.getMainLooper()).post {
binding.mainList.visibility = View.VISIBLE binding.mainList.visibility = View.VISIBLE
mMissedCallsAdapter.updateData(callList) mMissedCallsAdapter.updateData(callList)
binding.recentSms.isSelected = false binding.recentSms.isSelected = false
binding.otherCheck.isSelected = false binding.otherCheck.isSelected = false
binding.notice.isSelected = false binding.notice.isSelected = false
} // }
} }
} catch (e : Exception) { } catch (e : Exception) {
} }
} }
} else if(binding.recentSms.isSelected){ } else if(binding.recentSms.isSelected){
if (smsList.size > 0 && isAdded && isResumed && isVisible) { if (smsList.size > 0) {
try { try {
smsList.sortByDescending { it.rcvDate } smsList.sortByDescending { it.rcvDate }
binding.smsList.visibility = View.VISIBLE binding.smsList.visibility = View.VISIBLE
Handler(Looper.getMainLooper()).post { // Handler(Looper.getMainLooper()).post {
binding.smsList.visibility = View.VISIBLE binding.smsList.visibility = View.VISIBLE
mSmsLogsAdapter.updateData(smsList) mSmsLogsAdapter.updateData(smsList)
binding.missedCalls.isSelected = false binding.missedCalls.isSelected = false
binding.otherCheck.isSelected = false binding.otherCheck.isSelected = false
binding.notice.isSelected = false binding.notice.isSelected = false
} // }
} catch (e : Exception) { } catch (e : Exception) {
} }
} }
} else if(binding.otherCheck.isSelected) { } else if(binding.otherCheck.isSelected) {
Handler(Looper.getMainLooper()).post { // Handler(Looper.getMainLooper()).post {
binding.missedCalls.isSelected = false binding.missedCalls.isSelected = false
binding.recentSms.isSelected = false binding.recentSms.isSelected = false
binding.notice.isSelected = false binding.notice.isSelected = false
binding.infoList.visibility = View.VISIBLE binding.infoList.visibility = View.VISIBLE
binding.otherCheck.text = "최근 정보[${lasted?.size ?: "-"}]" binding.otherCheck.text = "최근 정보[${lasted?.size ?: "-"}]"
lasted?.let { mRssAdapter.updateData(it) } lasted?.let { mRssAdapter.updateData(it) }
} // }
} }
else if(binding.notice.isSelected) { else if(binding.notice.isSelected) {
Handler(Looper.getMainLooper()).post { // Handler(Looper.getMainLooper()).post {
binding.missedCalls.isSelected = false binding.missedCalls.isSelected = false
binding.recentSms.isSelected = false binding.recentSms.isSelected = false
binding.otherCheck.isSelected = false binding.otherCheck.isSelected = false
binding.notiList.visibility = View.VISIBLE binding.notiList.visibility = View.VISIBLE
binding.notice.text = "알림 센터[${lastedNoti?.size ?: "-"}]" binding.notice.text = "알림 센터[${lastedNoti?.size ?: "-"}]"
lastedNoti?.let { mNotiAdapter.updateData(it)} lastedNoti?.let { mNotiAdapter.updateData(it)}
} // }
} }
commandHandler.postDelayed(hideListView, UPDATE_DELAY * 5) commandHandler.postDelayed(hideListView, UPDATE_DELAY * 5)
} }

View File

@ -1,6 +1,7 @@
package rasel.lunar.launcher.model package rasel.lunar.launcher.model
import io.realm.kotlin.types.RealmObject import io.realm.kotlin.types.RealmObject
import io.realm.kotlin.types.annotations.Ignore
import io.realm.kotlin.types.annotations.PrimaryKey import io.realm.kotlin.types.annotations.PrimaryKey
import org.jsoup.select.Elements import org.jsoup.select.Elements
import rasel.lunar.launcher.utils.BLog import rasel.lunar.launcher.utils.BLog
@ -191,9 +192,15 @@ class RssData : RealmObject, RssDataInterface {
var thumbnail : String? = null var thumbnail : String? = null
var pubDate : Long = 0L var pubDate : Long = 0L
var category : String? = null var category : String? = null
@Ignore
var mRssDataType : RssDataType? = null
override fun title(): String { override fun title(): String {
return title ?: "" return when(category()){
RssDataType.NewsFeed -> {
if(title?.length ?: 0 > 30) title?.substring(0,30).plus("...") else title ?: ""
}
else -> title ?: ""
}
} }
override fun thumbnailUrl(): String { override fun thumbnailUrl(): String {
@ -205,7 +212,16 @@ class RssData : RealmObject, RssDataInterface {
} }
override fun description(): String { override fun description(): String {
return description ?: ""
return when(category()){
RssDataType.YOUTUBE -> {
if(description?.contains("게시자") == true) description!!.split("게시자")[0] else description ?: ""
}
RssDataType.NewsFeed -> {
category().name
}
else -> description.plus(" / ").plus(category().name)
}
} }
override fun pubDate(): Long { override fun pubDate(): Long {
@ -213,7 +229,9 @@ class RssData : RealmObject, RssDataInterface {
} }
override fun category(): RssDataType { override fun category(): RssDataType {
return RssDataType.valueOf(category!!) if (mRssDataType == null)
mRssDataType = RssDataType.valueOf(category!!)
return mRssDataType!!
} }
} }

View File

@ -41,9 +41,98 @@ import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
fun openNews(schemeString : String) {
val gmmIntentUri = Uri.parse(schemeString)
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
mapIntent.setPackage("com.android.chrome")
lActivity?.startActivity(mapIntent)
}
fun openYouTube(schemeString : String) {
val gmmIntentUri = Uri.parse(schemeString)
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
mapIntent.setPackage("com.google.android.youtube")
lActivity?.startActivity(mapIntent)
}
fun openReddit(schemeString : String) {
val gmmIntentUri = Uri.parse(schemeString)
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
mapIntent.setPackage("com.reddit.frontpage")
lActivity?.startActivity(mapIntent)
}
fun openDotax(schemeString : String) {
val gmmIntentUri = Uri.parse(schemeString)
val mapIntent = Intent(Intent.ACTION_VIEW)
mapIntent.setPackage("net.daum.android.cafe")
mapIntent.setData(gmmIntentUri)
lActivity?.startActivity(mapIntent)
}
fun openOpera(schemeString : String) {
BLog.LOGE("openOpera ${schemeString}")
val gmmIntentUri = Uri.parse(schemeString)
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
mapIntent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
mapIntent.setPackage("com.opera.browser")
lActivity?.startActivity(mapIntent)
}
internal class RssItemAdapter ( internal class RssItemAdapter (
private val context: Context) : RecyclerView.Adapter<RssTag>() { private val context: Context) : RecyclerView.Adapter<RssTag>() {
private var rssDataItemLis: ArrayList<RssDataInterface> = arrayListOf() companion object {
@SuppressLint("SimpleDateFormat")
val dateFormat = SimpleDateFormat("a HH:mm / yy - MM - dd")
val emptyDate = " - "
val dateViewClick = View.OnClickListener { v ->
(v?.tag as? Int)?.let { idx ->
val rss = rssDataItemLis[idx]
when(rss.category()) {
RssDataType.GURU,RssDataType.Most,RssDataType.REDDIT_nsfw -> {
v.findViewById<ShapeableImageView>(R.id.circle_preview)?.let {
if (it.visibility == View.GONE) {
it.visibility = View.VISIBLE
it.postDelayed({
it.visibility = View.GONE
}, 2000L)
} else {
openOpera(rss.originPage())
}
}
}
RssDataType.REDDIT -> { openReddit(rss.originPage()) }
RssDataType.Dotax -> { openDotax(rss.originPage()) }
RssDataType.YOUTUBE -> { openYouTube(rss.originPage()) }
else -> { openNews(rss.originPage()) }
}
}
}
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
}
}
override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): RssTag { override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): RssTag {
val binding = ListItemWithBinding.inflate(LayoutInflater.from(viewGroup.context), viewGroup, false) val binding = ListItemWithBinding.inflate(LayoutInflater.from(viewGroup.context), viewGroup, false)
return RssTag(binding) return RssTag(binding)
@ -53,7 +142,7 @@ internal class RssItemAdapter (
return rssDataItemLis.size return rssDataItemLis.size
} }
val dateFormat = SimpleDateFormat("a HH:mm / yy - MM - dd")
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: RssTag, position: Int) { override fun onBindViewHolder(holder: RssTag, position: Int) {
@ -62,77 +151,35 @@ internal class RssItemAdapter (
if (rssData.pubDate() > 1000L) { if (rssData.pubDate() > 1000L) {
holder.view.date.text = dateFormat.format(Date(rssData.pubDate())) holder.view.date.text = dateFormat.format(Date(rssData.pubDate()))
} else { } else {
holder.view.date.text = "" holder.view.date.text = emptyDate
} }
holder.view.title.text = rssData.title() holder.view.title.text = rssData.title()
when(rssData.category()) { holder.view.desc.text = rssData.description()
RssDataType.YOUTUBE -> {
holder.view.desc.text = if(rssData.description().contains("게시자")) rssData.description().split("게시자")[0] else rssData.description()
}
RssDataType.NewsFeed -> {
holder.view.desc.text = rssData.category().name
holder.view.title.text = if(rssData.title().length > 30)rssData.title().substring(0,30).plus("...") else rssData.title()
}
RssDataType.NO_DATA -> {}
else -> {
holder.view.desc.text = rssData.description().plus(" ").plus(rssData.category().name)
}
}
var param = holder.view.circlePreview.layoutParams var param = holder.view.circlePreview.layoutParams
holder.view.circlePreview.layoutParams = ConstraintLayout.LayoutParams(rssData.category().defaultImgSize(), param.height) holder.view.circlePreview.layoutParams = ConstraintLayout.LayoutParams(rssData.category().defaultImgSize(), param.height)
holder.view.circlePreview.visibility = rssData.category().getDefaultVisibiliy() holder.view.circlePreview.visibility = rssData.category().getDefaultVisibiliy()
Picasso.get().cancelRequest(holder.view.circlePreview)
if(rssData.thumbnailUrl()?.length ?: 0 > 6) { if(rssData.thumbnailUrl()?.length ?: 0 > 6) {
Picasso.get().load(rssData.thumbnailUrl().replace("&amp;","&").toUri()).into(holder.view.circlePreview) Picasso.get().load(rssData.thumbnailUrl().replace("&amp;","&").toUri()).into(holder.view.circlePreview)
} else if (rssData.category().getResId() > 0 ) { } else if (rssData.category().getResId() > 0 ) {
holder.view.circlePreview.setImageResource(rssData.category().getResId()) holder.view.circlePreview.setImageResource(rssData.category().getResId())
} else { } else {
holder.view.circlePreview.setImageDrawable(null) holder.view.circlePreview.setImageDrawable(null)
Picasso.get().cancelRequest(holder.view.circlePreview)
} }
holder.view.root.tag = position holder.view.root.tag = position
holder.view.root.setOnClickListener(dateViewClick) holder.view.root.setOnClickListener(dateViewClick)
holder.view.root.setOnLongClickListener(mLongClickListener) holder.view.root.setOnLongClickListener(mLongClickListener)
} }
val dateViewClick = View.OnClickListener {
it.findViewById<ShapeableImageView>(R.id.circle_preview)?.let {
if (it.visibility == View.GONE) {
it.visibility = View.VISIBLE
it.postDelayed({
it.visibility = View.GONE
}, 1000L)
}
}
}
val mLongClickListener = View.OnLongClickListener { v ->
(v?.tag as? Int)?.let { idx ->
val rss = rssDataItemLis[idx]
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
}
fun openOpera(schemeString : String) {
BLog.LOGE("openOpera ${schemeString}")
val gmmIntentUri = Uri.parse(schemeString)
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
mapIntent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
mapIntent.setPackage("com.opera.browser")
lActivity?.startActivity(mapIntent)
}
fun updateData(newList: List<RssDataInterface>) { fun updateData(newList: List<RssDataInterface>) {
try { try {
BLog.LOGE("newList >> ${newList}") // BLog.LOGE("newList >> ${newList}")
DiffUtil.calculateDiff(RssItemDiffUtil(rssDataItemLis, newList)).apply { DiffUtil.calculateDiff(RssItemDiffUtil(rssDataItemLis, newList)).apply {
}.dispatchUpdatesTo(this).apply { }.dispatchUpdatesTo(this).apply {
@ -140,49 +187,13 @@ internal class RssItemAdapter (
} }
rssDataItemLis.clear() rssDataItemLis.clear()
rssDataItemLis.addAll(newList) rssDataItemLis.addAll(newList)
BLog.LOGE("rssDataItemLis >> ${rssDataItemLis}") // BLog.LOGE("rssDataItemLis >> ${rssDataItemLis}")
}catch ( e : Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
} }
} }
fun openNews(schemeString : String) {
val gmmIntentUri = Uri.parse(schemeString)
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
mapIntent.setPackage("com.android.chrome")
lActivity?.startActivity(mapIntent)
}
fun openYouTube(schemeString : String) {
val gmmIntentUri = Uri.parse(schemeString)
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
mapIntent.setPackage("com.google.android.youtube")
lActivity?.startActivity(mapIntent)
}
fun openReddit(schemeString : String) {
val gmmIntentUri = Uri.parse(schemeString)
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
mapIntent.setPackage("com.reddit.frontpage")
lActivity?.startActivity(mapIntent)
}
fun openDotax(schemeString : String) {
val gmmIntentUri = Uri.parse(schemeString)
val mapIntent = Intent(Intent.ACTION_VIEW)
mapIntent.setPackage("net.daum.android.cafe")
mapIntent.setData(gmmIntentUri)
lActivity?.startActivity(mapIntent)
}
} }
//fun dp2px(dp: Float): Float {
// val resources: Resources = this.getResources()
// val metrics = resources.displayMetrics
// val px = dp * (metrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
// return px
//}
internal class RssTag(var view: ListItemWithBinding) : RecyclerView.ViewHolder(view.root) {} internal class RssTag(var view: ListItemWithBinding) : RecyclerView.ViewHolder(view.root) {}
internal class RssItemDiffUtil( internal class RssItemDiffUtil(
var oldList: List<RssDataInterface>, var newList: List<RssDataInterface> var oldList: List<RssDataInterface>, var newList: List<RssDataInterface>

View File

@ -0,0 +1,128 @@
package rasel.lunar.launcher.view
import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.view.View.OnClickListener
import android.view.ViewGroup
import android.widget.RadioButton
import android.widget.TableLayout
import android.widget.TableRow
class TableRadioGroup : TableLayout {
var checkedRadioButtonId: Int = -1
private set
private var onCheckedChangeListener: OnCheckedChangeListener? = null
private var maxColumns = -1 // Maximum number of columns (-1 for unlimited)
private var maxRows = -1 // Maximum number of rows (-1 for unlimited)
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
fun setMaxColumns(maxColumns: Int) {
this.maxColumns = maxColumns
}
fun setMaxRows(maxRows: Int) {
this.maxRows = maxRows
}
override fun addView(child: View, index: Int, params: ViewGroup.LayoutParams) {
if (child is TableRow) {
val numChildren = child.childCount
for (i in 0 until numChildren) {
val view = child.getChildAt(i)
if (view is RadioButton) {
setupRadioButton(view)
}
}
}
super.addView(child, index, params)
// Adjust the number of rows and columns if necessary
adjustTableLayout()
}
private fun setupRadioButton(radioButton: RadioButton?) {
if (radioButton == null) {
return
}
radioButton.setOnClickListener(OnClickListener {
if (checkedRadioButtonId != -1) {
setCheckedStateForView(checkedRadioButtonId, false)
}
val id = radioButton.id
setCheckedStateForView(id, true)
checkedRadioButtonId = id
if (onCheckedChangeListener != null) {
onCheckedChangeListener!!.onCheckedChanged(
this@TableRadioGroup,
checkedRadioButtonId
)
}
})
}
private fun setCheckedStateForView(viewId: Int, checked: Boolean) {
val checkedView = findViewById<View>(viewId)
if (checkedView != null && checkedView is RadioButton) {
checkedView.isChecked = checked
}
}
fun setOnCheckedChangeListener(listener: OnCheckedChangeListener?) {
onCheckedChangeListener = listener
}
fun clearCheck() {
setCheckedStateForView(checkedRadioButtonId, false)
checkedRadioButtonId = -1
}
private fun adjustTableLayout() {
if (maxColumns > 0 && maxRows > 0) {
val childCount = childCount
var rowCount = 0
var currentRow: TableRow? = null
for (i in 0 until childCount) {
val child = getChildAt(i)
if (child is TableRow) {
currentRow = child
rowCount++
} else if (currentRow != null) {
val columnCount = currentRow.childCount
if (columnCount >= maxColumns) {
// Create a new row if the maximum column count is reached
if (rowCount < maxRows) {
val newRow = TableRow(context)
super.addView(newRow, getChildIndex(currentRow) + 1)
currentRow = newRow
rowCount++
} else {
// Remove extra children that exceed the maximum row count
removeView(child)
continue
}
}
}
}
}
}
private fun getChildIndex(child: View): Int {
val childCount = childCount
for (i in 0 until childCount) {
if (getChildAt(i) === child) {
return i
}
}
return -1
}
interface OnCheckedChangeListener {
fun onCheckedChanged(group: TableRadioGroup?, checkedId: Int)
}
}

View File

@ -19,7 +19,8 @@ class ArcaGetter : BaseGetter {
constructor(context: Context, workerParams: WorkerParameters) : super(context, workerParams) { constructor(context: Context, workerParams: WorkerParameters) : super(context, workerParams) {
} }
override fun doWork(): Result {
override fun realWork(): Result {
try { try {
val urls = arrayListOf( val urls = arrayListOf(
"https://arca.live/b/singbung?mode=best", "https://arca.live/b/singbung?mode=best",

View File

@ -1,13 +1,26 @@
package rasel.lunar.launcher.workers package rasel.lunar.launcher.workers
import android.content.Context import android.content.Context
import androidx.annotation.CallSuper
import androidx.work.Worker import androidx.work.Worker
import androidx.work.WorkerParameters import androidx.work.WorkerParameters
import rasel.lunar.launcher.model.RssData import rasel.lunar.launcher.model.RssData
import rasel.lunar.launcher.utils.before30Min
import rasel.lunar.launcher.utils.beforeDay import rasel.lunar.launcher.utils.beforeDay
import java.util.Calendar
import java.util.Date import java.util.Date
open class BaseGetter : Worker { open abstract class BaseGetter : Worker {
protected companion object {
var lastedUpdateTime = 0L
fun before10Min(): Long {
val cal: Calendar = Calendar.getInstance()
cal.setTime(Date())
cal.add(Calendar.MINUTE, -10)
return cal.timeInMillis
}
}
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" 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"
val now = Date() val now = Date()
val limitDateTime = beforeDay(now,3) val limitDateTime = beforeDay(now,3)
@ -17,7 +30,15 @@ open class BaseGetter : Worker {
constructor(context: Context, workerParams: WorkerParameters) : super(context, workerParams) { constructor(context: Context, workerParams: WorkerParameters) : super(context, workerParams) {
} }
@CallSuper
override fun doWork(): Result { override fun doWork(): Result {
TODO("Not yet implemented") val currentTime = before10Min()
if (lastedUpdateTime > 0L && currentTime > lastedUpdateTime) {
return Result.success().apply {
}
}
return realWork()
} }
abstract fun realWork() : Result
} }

View File

@ -67,7 +67,7 @@ class ClienGetter : BaseGetter {
} }
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")
override fun doWork(): Result { override fun realWork(): Result {
try { try {
val testUrl2 = arrayListOf("https://www.clien.net/service/group/community") val testUrl2 = arrayListOf("https://www.clien.net/service/group/community")

View File

@ -66,7 +66,7 @@ class DCGetter : BaseGetter {
} }
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")
override fun doWork(): Result { override fun realWork(): Result {
var tempArray = arrayListOf<RssData>() var tempArray = arrayListOf<RssData>()

View File

@ -18,7 +18,7 @@ class DotaxGetter : BaseGetter {
} }
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")
override fun doWork(): Result { override fun realWork(): Result {
try { try {
val dotaxUrls = arrayListOf("https://m.cafe.daum.net/dotax", val dotaxUrls = arrayListOf("https://m.cafe.daum.net/dotax",
"https://m.cafe.daum.net/dotax/_rec?page=2", "https://m.cafe.daum.net/dotax/_rec?page=2",

View File

@ -17,7 +17,7 @@ class FmKoreaGetter : BaseGetter {
} }
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")
override fun doWork(): Result { override fun realWork(): Result {
val now = Date() val now = Date()
try { try {
val fmkoreaUrls = arrayListOf("https://www.fmkorea.com", val fmkoreaUrls = arrayListOf("https://www.fmkorea.com",

View File

@ -17,7 +17,7 @@ class NewsFeedsGetter : BaseGetter {
} }
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")
override fun doWork(): Result { override fun realWork(): Result {
feddsUrls.clear() feddsUrls.clear()
feddsUrls.addAll(RssList.newsFeeds) feddsUrls.addAll(RssList.newsFeeds)
feddsUrls.addAll(RssList.getFeedUrls()) feddsUrls.addAll(RssList.getFeedUrls())

View File

@ -42,7 +42,7 @@ class RecentCallGetter : BaseGetter {
} }
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")
override fun doWork(): Result { override fun realWork(): Result {
var dateParam = beforeDay(Date(),3).toString() var dateParam = beforeDay(Date(),3).toString()
var managedCursor = lActivity?.contentResolver?.query( var managedCursor = lActivity?.contentResolver?.query(
@ -74,33 +74,13 @@ class RecentCallGetter : BaseGetter {
var dir: String = "" var dir: String = ""
val dircode = callType.toInt() val dircode = callType.toInt()
when (dircode) { when (dircode) {
CallLog.Calls.INCOMING_TYPE -> { CallLog.Calls.INCOMING_TYPE -> { dir = "INCOMING_TYPE" }
dir = "INCOMING_TYPE" CallLog.Calls.OUTGOING_TYPE -> { dir = "OUTGOING_TYPE" }
} CallLog.Calls.MISSED_TYPE -> { dir = "MISSED_TYPE" }
CallLog.Calls.VOICEMAIL_TYPE -> { dir = "VOICEMAIL_TYPE" }
CallLog.Calls.OUTGOING_TYPE -> { CallLog.Calls.REJECTED_TYPE -> { dir = "REJECTED_TYPE" }
dir = "OUTGOING_TYPE" CallLog.Calls.BLOCKED_TYPE -> { dir = "BLOCKED_TYPE" }
} CallLog.Calls.ANSWERED_EXTERNALLY_TYPE -> { dir = "ANSWERED_EXTERNALLY_TYPE" }
CallLog.Calls.MISSED_TYPE -> {
dir = "MISSED_TYPE"
}
CallLog.Calls.VOICEMAIL_TYPE -> {
dir = "VOICEMAIL_TYPE"
}
CallLog.Calls.REJECTED_TYPE -> {
dir = "REJECTED_TYPE"
}
CallLog.Calls.BLOCKED_TYPE -> {
dir = "BLOCKED_TYPE"
}
CallLog.Calls.ANSWERED_EXTERNALLY_TYPE -> {
dir = "ANSWERED_EXTERNALLY_TYPE"
}
} }
var missed: RecentCall = if (recentCalls.containsKey(phNumber)) { var missed: RecentCall = if (recentCalls.containsKey(phNumber)) {
recentCalls.get(phNumber)!!.apply { recentCalls.get(phNumber)!!.apply {

View File

@ -29,7 +29,7 @@ class RecentSmsGetter : BaseGetter {
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")
override fun doWork(): Result { override fun realWork(): Result {
var dateParam = beforeDay(Date(),3).toString() var dateParam = beforeDay(Date(),3).toString()
val managedCursor = lActivity?.contentResolver?.query( val managedCursor = lActivity?.contentResolver?.query(
Telephony.Sms.CONTENT_URI, arrayOf( Telephony.Sms.CONTENT_URI, arrayOf(

View File

@ -16,7 +16,7 @@ class RedditGetter : BaseGetter {
} }
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")
override fun doWork(): Result { override fun realWork(): Result {
val temp = arrayListOf<RssData>() val temp = arrayListOf<RssData>()
for (url in feedJsons) { for (url in feedJsons) {
for (it in RssFeedsParser.getReddit(url)) { for (it in RssFeedsParser.getReddit(url)) {

View File

@ -2,6 +2,7 @@ package rasel.lunar.launcher.workers
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import androidx.core.net.toUri
import androidx.work.WorkerParameters import androidx.work.WorkerParameters
import org.jsoup.Jsoup import org.jsoup.Jsoup
import rasel.lunar.launcher.model.DcInside import rasel.lunar.launcher.model.DcInside
@ -47,7 +48,7 @@ class RuliWebGetter : BaseGetter {
if (title.length > 0 && pageLink.length > 0) { if (title.length > 0 && pageLink.length > 0) {
RuliWeb().let { ru -> RuliWeb().let { ru ->
ru.title = title ru.title = title
ru.link = pageLink ru.link = pageLink.replace(pageLink.toUri().query ?: "","")
ru.desc = desc ru.desc = desc
ru.thumbnail = thumbnailUrl ru.thumbnail = thumbnailUrl
ru.dateTiem = dateTimeTxt.replace("날짜","").trim() ru.dateTiem = dateTimeTxt.replace("날짜","").trim()
@ -59,7 +60,7 @@ class RuliWebGetter : BaseGetter {
} }
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")
override fun doWork(): Result { override fun realWork(): Result {
try { try {
val testUrl2 = arrayListOf("https://bbs.ruliweb.com/best/humor_only","https://bbs.ruliweb.com/best/humor_only/now?m=humor_only&t=default&page=2") val testUrl2 = arrayListOf("https://bbs.ruliweb.com/best/humor_only","https://bbs.ruliweb.com/best/humor_only/now?m=humor_only&t=default&page=2")

View File

@ -45,7 +45,7 @@ class TheQooGetter : BaseGetter {
} }
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")
override fun doWork(): Result { override fun realWork(): Result {
try { try {
val testUrl2 = arrayListOf("https://theqoo.net/hot") val testUrl2 = arrayListOf("https://theqoo.net/hot")

View File

@ -44,7 +44,7 @@ object WorkersDb {
try { try {
getRealm().writeBlocking { getRealm().writeBlocking {
try { try {
this.copyToRealm(it, UpdatePolicy.ALL) this.copyToRealm(it, UpdatePolicy.ERROR)
} catch (e : Exception) { } catch (e : Exception) {
} }

View File

@ -23,7 +23,7 @@ class YoutubeGetter : BaseGetter {
} }
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")
override fun doWork(): Result { override fun realWork(): Result {
rssUrls.clear() rssUrls.clear()
rssUrls.addAll(RssList.youtubeUrls) rssUrls.addAll(RssList.youtubeUrls)
for (url in rssUrls) { for (url in rssUrls) {
@ -41,8 +41,6 @@ class YoutubeGetter : BaseGetter {
if(it.html().contains("var ytInitialData", false)) {/**/ if(it.html().contains("var ytInitialData", false)) {/**/
var ytInitialData = it.html().split("var ytInitialData = ")[1].split("</script>")[0].toString() var ytInitialData = it.html().split("var ytInitialData = ")[1].split("</script>")[0].toString()
var tempJSONObject : JSONObject? = null var tempJSONObject : JSONObject? = null
JSONObject(ytInitialData).apply{ JSONObject(ytInitialData).apply{
tempJSONObject = this tempJSONObject = this
val root = Gson().fromJson(tempJSONObject.toString(), Root::class.java) val root = Gson().fromJson(tempJSONObject.toString(), Root::class.java)

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<rasel.lunar.launcher.view.TableRadioGroup
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:id="@+id/categoryz"
android:maxRows="5"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</rasel.lunar.launcher.view.TableRadioGroup>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/colorInputLayout"
android:layout_width="@dimen/oneNinetySix"
android:layout_height="wrap_content"
android:hint="inpout text"
app:boxBackgroundColor="?attr/colorSurface"
app:endIconMode="clear_text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/categoryz"
>
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionDone"
android:inputType="textPassword" />
</com.google.android.material.textfield.TextInputLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,3 +1,4 @@
<paths> <paths>
<external-path name="apk_files" path="." /> <external-path name="apk_files" path="." />
<external-path name="external_files" path="." />
</paths> </paths>