Compare commits

..

No commits in common. "405b8c8fede812999048a28fe4c8c0fe9db27576" and "3784f973ca736a3c1b6cacc6b286b5a962f94a5f" have entirely different histories.

65 changed files with 3006 additions and 5213 deletions

View File

@ -17,7 +17,6 @@ android {
targetSdk = 34
versionCode = 38
versionName = "2.8.2"
multiDexEnabled = true
}
buildTypes {
@ -65,17 +64,12 @@ android {
buildFeatures {
viewBinding = true
dataBinding = true
buildConfig = true
resValues = true
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
packagingOptions.resources.excludes.add("META-INF/*")
packagingOptions.resources.excludes.add("mozilla/*")
packagingOptions.resources.excludes.add("META-INF/*/*")
kotlinOptions {
jvmTarget = "1.8"
@ -91,7 +85,7 @@ dependencies {
implementation ("androidx.core:core-splashscreen:1.0.1")
implementation ("androidx.lifecycle:lifecycle-runtime-ktx:2.8.7")
implementation ("com.google.android.material:material:1.12.0")
implementation ("com.ibm.icu:icu4j:68.1")
implementation (kotlin("stdlib", version = kotlinVersion))
implementation ("com.github.cachapa:ExpandableLayout:2.9.2")
implementation ("com.squareup.picasso:picasso:2.71828")
@ -111,16 +105,7 @@ dependencies {
implementation("com.github.delight-im:Android-AdvancedWebView:v3.2.1")
implementation(project(":library"))
implementation(project(":utils"))
// implementation("org.mozilla.geckoview:geckoview:139.0.20250523173407")
// https://mvnrepository.com/artifact/org.mozilla.geckoview/geckoview
implementation("org.mozilla.geckoview:geckoview:139.0.20250523173407")
// implementation("org.opencv:opencv-android:4.11.0")
implementation ("androidx.media:media:1.7.0")
// implementation(project(":sdk"))
// implementation ("me.everything:providers-android:1.0.1")
// implementation ("me.everything:providers-core:1.0.1")
// implementation ("androidx.window:window:1.0.0")

View File

@ -78,12 +78,12 @@
android:windowSoftInputMode="adjustResize"
android:requestLegacyExternalStorage="true"
>
<!-- android:excludeFromRecents="true"-->
<activity
android:name=".LauncherActivity"
android:theme="@style/Theme.LunarLauncher.Starting"
android:launchMode="singleInstance"
android:excludeFromRecents="true"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|screenLayout|layoutDirection"
android:windowSoftInputMode="adjustResize"
android:exported="true">
@ -93,9 +93,9 @@
<data android:mimeType="*/*"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.MAIN"/>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
@ -109,11 +109,6 @@
<action android:name="android.intent.action.APPLICATION_PREFERENCES" />
</intent-filter>
</activity>
<!-- <activity-->
<!-- android:name=".PhotoFilter"-->
<!-- android:label="@string/lunar_settings"-->
<!-- android:exported="true">-->
<!-- </activity>-->
<activity
android:name=".feeds.Feeds"
android:label="@string/lunar_settings"
@ -198,20 +193,9 @@
android:configChanges="keyboardHidden|orientation|screenSize"
android:hardwareAccelerated="true"
android:launchMode="singleTask"
android:exported="true"
android:excludeFromRecents="true"
android:theme="@style/FinestWebViewTheme.Fullscreen" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file"/>
<data android:scheme="content"/>
<data android:mimeType="text/html"/>
<data android:mimeType="text/plain"/>
<data android:mimeType="text/xml"/>
<data android:mimeType="application/xhtml+xml"/>
<data android:mimeType="application/vnd.wap.xhtml+xml"/>
</intent-filter>
</activity>
<provider

View File

@ -45,7 +45,6 @@ import android.telephony.TelephonyManager
import android.view.KeyEvent
import android.view.KeyEvent.ACTION_UP
import android.view.KeyEvent.KEYCODE_BUTTON_A
import android.view.KeyEvent.KEYCODE_BUTTON_B
import android.view.KeyEvent.KEYCODE_BUTTON_SELECT
import android.view.KeyEvent.KEYCODE_BUTTON_START
import android.view.KeyEvent.KEYCODE_BUTTON_X
@ -76,6 +75,7 @@ import bums.lunatic.launcher.LauncherActivity.Companion.lActivity
import bums.lunatic.launcher.apps.AppDrawer
import bums.lunatic.launcher.common.CommonActivity
import bums.lunatic.launcher.databinding.LauncherActivityBinding
import bums.lunatic.launcher.feeds.Feeds
import bums.lunatic.launcher.feeds.WidgetHost
import bums.lunatic.launcher.helpers.BluetoothManager
import bums.lunatic.launcher.helpers.Constants.Companion.KEY_APPLICATION_THEME
@ -122,7 +122,6 @@ import bums.lunatic.launcher.workers.YoutubeGetter.Companion.YT_WORK_TAG
import com.google.android.material.color.DynamicColors
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import io.realm.kotlin.ext.query
import io.realm.kotlin.query.Sort
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@ -144,6 +143,7 @@ internal class LauncherActivity : CommonActivity() {
companion object {
private var mWorkManager: WorkManager? = null
var isOpendFold = false
val qDayPeriod = 60L * 8L
@ -152,30 +152,37 @@ internal class LauncherActivity : CommonActivity() {
@JvmStatic var appWidgetHost: WidgetHost? = null
fun refreshDeviceData()
{
Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(SMS_WORK_TAG)
mWorkManager?.enqueueUniquePeriodicWork(
SMS_WORK_TAG,
ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<RecentSmsGetter>(PrefLong.longTimePeriod.get(), TimeUnit.MINUTES)
.addTag(SMS_WORK_TAG)
.build())
}, 500, TimeUnit.MILLISECONDS)
Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(RecentCallGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork(
RecentCallGetter.TAG,
ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<RecentCallGetter>(PrefLong.longTimePeriod.get(), TimeUnit.MINUTES)
.addTag(RecentCallGetter.TAG)
.build())
}, 500, TimeUnit.MILLISECONDS)
mWorkManager?.cancelAllWorkByTag(SMS_WORK_TAG)
mWorkManager?.enqueueUniquePeriodicWork(
SMS_WORK_TAG,
ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<RecentSmsGetter>(PrefLong.longTimePeriod.get(), TimeUnit.MINUTES)
.addTag(SMS_WORK_TAG)
.build())
mWorkManager?.cancelAllWorkByTag(RecentCallGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork(
RecentCallGetter.TAG,
ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<RecentCallGetter>(PrefLong.longTimePeriod.get(), TimeUnit.MINUTES)
.addTag(RecentCallGetter.TAG)
.build())
mWorkManager?.cancelAllWorkByTag(ContactInfoGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork(
ContactInfoGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<ContactInfoGetter>(12, TimeUnit.HOURS)
.addTag(ContactInfoGetter.TAG)
.build())
mWorkManager?.enqueue(OneTimeWorkRequest.from(AppInfoGetter::class.java))
var delay = 3L
Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(ContactInfoGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork(
ContactInfoGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<ContactInfoGetter>(12, TimeUnit.HOURS)
.addTag(ContactInfoGetter.TAG)
.build())
}, delay, TimeUnit.SECONDS)
Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.enqueue(OneTimeWorkRequest.from(AppInfoGetter::class.java))
}, 5, TimeUnit.SECONDS)
}
@ -194,75 +201,109 @@ internal class LauncherActivity : CommonActivity() {
val defaultDelay = 10L
fun refreshFeeds() {
mWorkManager?.cancelAllWork()
mWorkManager?.cancelAllWorkByTag(RuliWebGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork(
RuliWebGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<RuliWebGetter>(PrefLong.midTimePeriod.get(), TimeUnit.MINUTES)
.addTag(RuliWebGetter.TAG)
.build())
var delay = defaultDelay
Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(FEDDS_WORK_TAG)
mWorkManager?.enqueueUniquePeriodicWork(
FEDDS_WORK_TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<NewsFeedsGetter>(PrefLong.shortTimePeriod.get(), TimeUnit.MINUTES)
.addTag(FEDDS_WORK_TAG)
.build())
}, delay, TimeUnit.SECONDS)
delay += defaultDelay
Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(YT_WORK_TAG)
mWorkManager?.enqueueUniquePeriodicWork(
YT_WORK_TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<YoutubeGetter>(PrefLong.longTimePeriod.get(), TimeUnit.MINUTES)
.addTag(YT_WORK_TAG)
.build())
}, delay, TimeUnit.SECONDS)
delay += defaultDelay
Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(REDDIT_WORK_TAG)
mWorkManager?.enqueueUniquePeriodicWork(
REDDIT_WORK_TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<RedditGetter>(PrefLong.midTimePeriod.get(), TimeUnit.MINUTES)
.addTag(REDDIT_WORK_TAG)
.build())
}, delay, TimeUnit.SECONDS)
delay += defaultDelay
Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(COMIC_WORK_TAG)
mWorkManager?.enqueueUniquePeriodicWork(
COMIC_WORK_TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<FmKoreaGetter>(PrefLong.midTimePeriod.get(), TimeUnit.MINUTES)
.addTag(COMIC_WORK_TAG)
.build())
}, delay, TimeUnit.SECONDS)
delay += defaultDelay
Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(COMIC2_WORK_TAG)
mWorkManager?.enqueueUniquePeriodicWork(
COMIC2_WORK_TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<DotaxGetter>(PrefLong.midTimePeriod.get(), TimeUnit.MINUTES)
.addTag(COMIC2_WORK_TAG)
.build())
}, delay, TimeUnit.SECONDS)
delay += defaultDelay
Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(ClienGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork(
ClienGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<ClienGetter>(PrefLong.midTimePeriod.get(), TimeUnit.MINUTES)
.addTag(ClienGetter.TAG)
.build())
}, delay, TimeUnit.SECONDS)
delay += defaultDelay
Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(DCGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork(
DCGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<DCGetter>(PrefLong.midTimePeriod.get(), TimeUnit.MINUTES)
.addTag(DCGetter.TAG)
.build())
}, delay, TimeUnit.SECONDS)
delay += defaultDelay
Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(RuliWebGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork(
RuliWebGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<RuliWebGetter>(PrefLong.midTimePeriod.get(), TimeUnit.MINUTES)
.addTag(RuliWebGetter.TAG)
.build())
}, delay, TimeUnit.SECONDS)
delay += defaultDelay
Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(TheQooGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork(
TheQooGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<TheQooGetter>(PrefLong.midTimePeriod.get(), TimeUnit.MINUTES)
.addTag(TheQooGetter.TAG)
.build())
}, delay, TimeUnit.SECONDS)
delay += defaultDelay
Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(ArcaGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork(
ArcaGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<ArcaGetter>(PrefLong.midTimePeriod.get(), TimeUnit.MINUTES)
.addTag(ArcaGetter.TAG)
.build())
}, delay, TimeUnit.SECONDS)
delay += defaultDelay
Executors.newSingleThreadScheduledExecutor().schedule({
mWorkManager?.cancelAllWorkByTag(LocationGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork(
LocationGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<LocationGetter>(PrefLong.locationTimePeriod.get(), TimeUnit.MINUTES)
.addTag(LocationGetter.TAG)
.build())
}, delay, TimeUnit.SECONDS)
mWorkManager?.cancelAllWorkByTag(FEDDS_WORK_TAG)
mWorkManager?.enqueueUniquePeriodicWork(
FEDDS_WORK_TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<NewsFeedsGetter>(PrefLong.shortTimePeriod.get(), TimeUnit.MINUTES)
.addTag(FEDDS_WORK_TAG)
.build())
mWorkManager?.cancelAllWorkByTag(YT_WORK_TAG)
mWorkManager?.enqueueUniquePeriodicWork(
YT_WORK_TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<YoutubeGetter>(PrefLong.longTimePeriod.get(), TimeUnit.MINUTES)
.addTag(YT_WORK_TAG)
.build())
mWorkManager?.cancelAllWorkByTag(REDDIT_WORK_TAG)
mWorkManager?.enqueueUniquePeriodicWork(
REDDIT_WORK_TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<RedditGetter>(PrefLong.midTimePeriod.get(), TimeUnit.MINUTES)
.addTag(REDDIT_WORK_TAG)
.build())
mWorkManager?.cancelAllWorkByTag(COMIC_WORK_TAG)
mWorkManager?.enqueueUniquePeriodicWork(
COMIC_WORK_TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<FmKoreaGetter>(PrefLong.midTimePeriod.get(), TimeUnit.MINUTES)
.addTag(COMIC_WORK_TAG)
.build())
mWorkManager?.cancelAllWorkByTag(COMIC2_WORK_TAG)
mWorkManager?.enqueueUniquePeriodicWork(
COMIC2_WORK_TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<DotaxGetter>(PrefLong.midTimePeriod.get(), TimeUnit.MINUTES)
.addTag(COMIC2_WORK_TAG)
.build())
mWorkManager?.cancelAllWorkByTag(ClienGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork(
ClienGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<ClienGetter>(PrefLong.midTimePeriod.get(), TimeUnit.MINUTES)
.addTag(ClienGetter.TAG)
.build())
mWorkManager?.cancelAllWorkByTag(DCGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork(
DCGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<DCGetter>(PrefLong.midTimePeriod.get(), TimeUnit.MINUTES)
.addTag(DCGetter.TAG)
.build())
mWorkManager?.cancelAllWorkByTag(TheQooGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork(
TheQooGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<TheQooGetter>(PrefLong.midTimePeriod.get(), TimeUnit.MINUTES)
.addTag(TheQooGetter.TAG)
.build())
mWorkManager?.cancelAllWorkByTag(ArcaGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork(
ArcaGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<ArcaGetter>(PrefLong.midTimePeriod.get(), TimeUnit.MINUTES)
.addTag(ArcaGetter.TAG)
.build())
mWorkManager?.cancelAllWorkByTag(LocationGetter.TAG)
mWorkManager?.enqueueUniquePeriodicWork(
LocationGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
PeriodicWorkRequestBuilder<LocationGetter>(PrefLong.locationTimePeriod.get(), TimeUnit.MINUTES)
.addTag(LocationGetter.TAG)
.build())
}
@ -290,7 +331,6 @@ internal class LauncherActivity : CommonActivity() {
var onExit = false
var lastAction = MotionEvent.ACTION_HOVER_EXIT
override fun dispatchKeyEvent(ev: KeyEvent): Boolean {
Blog.LOGE("dispatch ev?.device?.name >>> ${ev?.device?.name}")
if (ev?.device?.name?.contains("SM-031N Mouse") == true) {
@ -299,7 +339,6 @@ internal class LauncherActivity : CommonActivity() {
Blog.LOGE("dispatch dispatchKeyEvent>>> ${ev}")
when(ev.keyCode) {
KEYCODE_BUTTON_Y->{
CoroutineScope(Dispatchers.IO).launch {
String(Base64.getMimeDecoder().decode("aHR0cHM6Ly9qYXZtb3N0LnRvL2xhdGVzdC11cGRhdGVzCg==".toByteArray())).getJ().let { doc -> FeedParseManager.parse(doc){Blog.LOGE(it)} }
}
@ -311,7 +350,17 @@ internal class LauncherActivity : CommonActivity() {
}
}
KEYCODE_BUTTON_X->{
WorkersDb.getRealm().apply {
writeBlocking {
var ddd = copyFromRealm(WorkersDb.getRssQuery("", RssDataType.getAdts(),false).limit(100).find()).map { it.originPage() }
var origin = ddd.first()
RssViewBuilder(lActivity!!)
.setRssList(arrayListOf<String>().apply { this.addAll(ddd) })
.setRssId(origin)
.showIconClose(true).showIconBack(false).showProgressBar(true).backPressToClose(false).webViewMixedContentMode(1)
.show(origin)
}
}
}
KEYCODE_BUTTON_A->{
WorkersDb.getRealm().apply {
@ -326,13 +375,6 @@ internal class LauncherActivity : CommonActivity() {
}
}
}
KEYCODE_BUTTON_B->{
// RssViewBuilder(lActivity!!)
// .setRssId("https://jav.guru")
// .webViewJavaScriptEnabled(true)
// .showIconClose(true).showIconBack(false).showProgressBar(true).backPressToClose(false).webViewMixedContentMode(1)
// .show("https://jav.guru")
}
KEYCODE_DPAD_DOWN->{
}
@ -340,7 +382,7 @@ internal class LauncherActivity : CommonActivity() {
}
KEYCODE_BUTTON_START->{
onClickCenterButton()
onClickCenterButton()
}
KEYCODE_BUTTON_SELECT->{
WorkersDb.getRealm().apply {
@ -371,29 +413,16 @@ internal class LauncherActivity : CommonActivity() {
fun onClickCenterButton() {
WorkersDb.getRealm().apply {
writeBlocking {
delete(
query<RssData>()
.query("pubDate < $0",
bums.lunatic.launcher.utils.beforeDay(28)
)
.query("vote != $0", true).apply {
Blog.LOGE("onClickCenterButton DELETE >> ${this.description()}")
}.find()
)
var ddd = copyFromRealm(WorkersDb.getRssQuery("", RssDataType.getExcAdt(),false).limit(100).query("read == $0", 0).query("vote != $0", true).apply {
Blog.LOGE("onClickCenterButton SELECT >> ${this.description()}")
}.find()).map { it.originPage() }
var ddd = copyFromRealm(WorkersDb.getRssQuery("", RssDataType.getExcAdt(),false).limit(100).query("read == $0", 0).query("vote != $0", true).find()).map { it.originPage() }
var origin = ddd.first()
var jjjj = hashSetOf<String>()
jjjj.addAll(ddd)
RssViewBuilder(lActivity!!)
.setRssList(arrayListOf<String>().apply {
this.addAll(jjjj)})
var jjjj = hashSetOf<String>()
jjjj.addAll(ddd)
this.addAll(jjjj) })
.setRssId(origin)
// .webViewDesktopMode(true)
.showIconClose(true).showIconBack(false).showProgressBar(true).backPressToClose(false).webViewMixedContentMode(1)
.show(origin)
}
@ -545,7 +574,6 @@ internal class LauncherActivity : CommonActivity() {
@SuppressLint("NewApi", "MissingPermission")
override fun onCreate(savedInstanceState: Bundle?) {
installSplashScreen()
mWorkManager = WorkManager.getInstance(this)
DynamicColors.applyToActivityIfAvailable(this)
lActivity = this
@ -1037,9 +1065,9 @@ internal class LauncherActivity : CommonActivity() {
// }
// }
// fun switchFeeds() {
// startActivity(Intent(this,Feeds::class.java))
// }
fun switchFeeds() {
startActivity(Intent(this,Feeds::class.java))
}
// inner class MyJavaScriptInterface(val webView: WebView) {
// @JavascriptInterface
@ -1163,7 +1191,9 @@ fun openReddit(schemeString : String) {
var uri = schemeString.toUri()
val gmmIntentUri = Uri.parse(schemeString)
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
if(schemeString.contains("reddit")) {
if (uri != null && uri.host?.contains("facebook") == true) {
} else {
mapIntent.setPackage("com.reddit.frontpage")
}
lActivity?.startActivity(mapIntent)

View File

@ -1,108 +0,0 @@
//package bums.lunatic.launcher
//
//import bums.lunatic.launcher.common.CommonActivity
//import android.Manifest
//import android.app.Activity
//import android.content.Intent
//import android.content.pm.PackageManager
//import android.graphics.Bitmap
//import android.net.Uri
//import android.os.Build
//import android.os.Bundle
//import android.provider.MediaStore
//import android.widget.Button
//import android.widget.ImageView
//import androidx.activity.result.ActivityResultLauncher
//import androidx.activity.result.contract.ActivityResultContracts
//import androidx.annotation.RequiresApi
//import androidx.appcompat.app.AppCompatActivity
//import androidx.core.app.ActivityCompat
//import androidx.core.content.ContextCompat
//import bums.lunatic.launcher.utils.Blog
//
//
//class PhotoFilter : CommonActivity() {
//// private lateinit var originalImageView: ImageView
//// private lateinit var filteredImageView: ImageView
//// private lateinit var selectImageButton: Button
//// private val PICK_IMAGE_REQUEST = 1
//// private val PERMISSION_REQUEST_CODE = 200
////
//// init {
////
//// }
////
//// override fun onCreate(savedInstanceState: Bundle?) {
//// super.onCreate(savedInstanceState)
//// setContentView(R.layout.photo_filter)
////
//// originalImageView = findViewById(R.id.originalImageView)
//// filteredImageView = findViewById(R.id.filteredImageView)
//// selectImageButton = findViewById(R.id.selectImageButton)
////
//// selectImageButton.setOnClickListener {
//// Blog.LOGE("imagePickerLauncher checkPermission() ${checkPermission()}")
//// if (checkPermission()) {
//// openGallery()
//// } else {
//// requestPermission()
//// }
//// }
////
//// imagePickerLauncher = registerForActivityResult(
//// ActivityResultContracts.GetContent(),
//// {result ->
//// Blog.LOGE("imagePickerLauncher result ${result}")
//// if (result != null) {
//// // Handle the selected image
//// FilePathUri = result;
//// try {
//// var bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), FilePathUri)
//// Blog.LOGE("imagePickerLauncher result ${result} 2")
//// originalImageView.setImageBitmap(bitmap)
//// Blog.LOGE("imagePickerLauncher result ${result} 3")
//// val filteredBitmap = applyCartoonFilter(bitmap)
//// Blog.LOGE("imagePickerLauncher result ${result} 4")
//// filteredImageView.setImageBitmap(filteredBitmap)
//// } catch (e : Exception ) {
//// e.printStackTrace();
//// }
//// }
//// }
//// );
//// }
////
//// var FilePathUri : Uri? = null
////
//// private var imagePickerLauncher : ActivityResultLauncher<String>? = null
////
////
//// private fun openGallery() {
////// val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
////// startActivityForResult(intent, PICK_IMAGE_REQUEST)
////
//// imagePickerLauncher?.launch("image/*");
//// Blog.LOGE("imagePickerLauncher ")
////
//// }
////
////
//// @RequiresApi(Build.VERSION_CODES.TIRAMISU)
//// private fun checkPermission(): Boolean {
//// return ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_IMAGES) == PackageManager.PERMISSION_GRANTED
//// }
////
//// @RequiresApi(Build.VERSION_CODES.TIRAMISU)
//// private fun requestPermission() {
//// ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_MEDIA_IMAGES), PERMISSION_REQUEST_CODE)
//// }
////
//// override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
//// super.onRequestPermissionsResult(requestCode, permissions, grantResults)
//// if (requestCode == PERMISSION_REQUEST_CODE) {
//// if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//// openGallery()
//// }
//// }
//// }
//}

View File

@ -35,8 +35,6 @@ import android.view.inputmethod.InputMethodManager
import androidx.core.widget.doOnTextChanged
import androidx.recyclerview.widget.GridLayoutManager
import bums.lunatic.launcher.BuildConfig
import bums.lunatic.launcher.LauncherActivity
import bums.lunatic.launcher.LauncherActivity.Companion.lActivity
import bums.lunatic.launcher.common.CommonActivity
import bums.lunatic.launcher.common.letTrue
import bums.lunatic.launcher.databinding.AppDrawerBinding
@ -46,7 +44,6 @@ import bums.lunatic.launcher.helpers.Constants.Companion.PREFS_APP_NAMES
import bums.lunatic.launcher.helpers.Constants.Companion.PREFS_SETTINGS
import bums.lunatic.launcher.helpers.PrefBoolean
import bums.lunatic.launcher.helpers.PrefLong
import bums.lunatic.launcher.helpers.PrefString
import bums.lunatic.launcher.model.AppInfo
import bums.lunatic.launcher.utils.Blog
import bums.lunatic.launcher.utils.JamoUtils
@ -69,7 +66,7 @@ internal class AppDrawer : CommonActivity() {
private var isKeyboardShowing: Boolean = false
companion object {
lateinit var packageManager: PackageManager
private var appsAdapter: AppsAdapter? = null
private var contactAdapter : ContactAdapter? = null
private var packageList = mutableListOf<AppInfo>()
@ -77,14 +74,34 @@ internal class AppDrawer : CommonActivity() {
@JvmStatic var appNamesPrefs: SharedPreferences? = null
fun appName(resolver: ResolveInfo): String {
return resolver.loadLabel(packageManager).toString().apply {
appNamesPrefs?.edit()?.putString(resolver.activityInfo.packageName, this)?.apply()
}
}
fun getCategory(category : Int) : String {
return when(category) {
ApplicationInfo.CATEGORY_UNDEFINED -> "UNDEFINED"
ApplicationInfo.CATEGORY_GAME -> "GAME"
ApplicationInfo.CATEGORY_AUDIO -> "AUDIO"
ApplicationInfo.CATEGORY_VIDEO -> "VIDEO"
ApplicationInfo.CATEGORY_IMAGE -> "IMAGE"
ApplicationInfo.CATEGORY_SOCIAL -> "SOCIAL"
ApplicationInfo.CATEGORY_NEWS -> "NEWS"
ApplicationInfo.CATEGORY_MAPS -> "MAPS"
ApplicationInfo.CATEGORY_PRODUCTIVITY -> "PRODUCTIVITY"
ApplicationInfo.CATEGORY_ACCESSIBILITY -> "ACCESSIBILITY"
else -> {"UNKNOWN"}
}
}
}
fun getInputText() = binding.searchInput.text.toString()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// setStyle(STYLE_NO_TITLE, R.style.FilterFullScreenDialog)
// packageManager
// packageManager = lActivity?.packageManager!!
// }
// override fun onAttach(context: Context) {
@ -101,7 +118,7 @@ internal class AppDrawer : CommonActivity() {
appNamesPrefs = this.getSharedPreferences(PREFS_APP_NAMES, 0)
layoutType = settingsPrefs!!.getInt(KEY_APPS_LAYOUT, 0)
appsAdapter = AppsAdapter(packageManager!!, supportFragmentManager, binding.appsCount)
appsAdapter = AppsAdapter(layoutType, packageManager!!, supportFragmentManager, binding.appsCount)
contactAdapter = ContactAdapter(packageManager!!, supportFragmentManager)
binding.appsCount.visibility = if (settingsPrefs!!.getBoolean(KEY_APPS_COUNT, true)) VISIBLE else GONE
@ -141,7 +158,7 @@ internal class AppDrawer : CommonActivity() {
sendMsg()
}
binding.runTelegram.setOnClickListener {
sendMsg("tg://msg?text=${getInputText()}&to=${PrefString.telegramSendTarget.get()}","org.telegram.messenger")
sendMsg("tg://msg?text=${getInputText()}&to=","org.telegram.messenger")
}
binding.runKatalk.setOnClickListener {
sendMsg(pkg = "com.kakao.talk")
@ -162,8 +179,6 @@ internal class AppDrawer : CommonActivity() {
false
}
}
var packageManager = lActivity?.packageManager
binding.searchInput.setOnLongClickListener {
WorkersDb.getRealm().apply {
var newQ = query<AppInfo>()
@ -172,18 +187,10 @@ internal class AppDrawer : CommonActivity() {
if(it.size > 0) {
WorkersDb.getRealm().apply {
packageList.clear()
writeBlocking {
it.filter {
var installed = isPackageInstalled(it.pkgName ?: "fffffffail", packageManager!!)
// it.isInstalled = installed
installed
}.let { result ->
packageList.addAll(copyFromRealm(result))
binding.appsList.post { if (result.size > 0) {
appsAdapter?.updateData(packageList)
}}
}
}
packageList.addAll(copyFromRealm(it))
binding.appsList.post { if (packageList.size > 0) {
appsAdapter?.updateData(packageList)
} }
}
}
}
@ -212,14 +219,6 @@ internal class AppDrawer : CommonActivity() {
}
// return binding.root
}
fun isPackageInstalled( packageName : String, packageManager : PackageManager?) : Boolean{
try {
packageManager!!.getPackageInfo(packageName, 0)
return true;
} catch ( e : Exception) {
return false;
}
}
fun sendMsg(scheme : String? = null , pkg : String? = null) {
var postIntent : Intent? = null
@ -337,18 +336,10 @@ internal class AppDrawer : CommonActivity() {
if(it.size > 0) {
WorkersDb.getRealm().apply {
packageList.clear()
writeBlocking {
it.filter {
var installed = isPackageInstalled(it.pkgName ?: "fffffffail", packageManager!!)
// it.isInstalled = installed
installed
}.let { result ->
packageList.addAll(copyFromRealm(result))
binding.appsList.post { if (result.size > 0) {
appsAdapter?.updateData(packageList)
}}
}
}
packageList.addAll(copyFromRealm(it))
binding.appsList.post { if (packageList.size > 0) {
appsAdapter?.updateData(packageList)
} }
}
}
}
@ -505,3 +496,9 @@ internal class AppDrawer : CommonActivity() {
}
fun normalize(str: String): String {
val normalizedString =
Normalizer.normalize(str.replace("\\W".toRegex(), ""), Normalizer.Form.NFC)
val pattern = Pattern.compile("\\p{InCombiningDiacriticalMarks}+")
return pattern.matcher(normalizedString).replaceAll("").toLowerCase()
}

View File

@ -41,9 +41,10 @@ import kotlinx.coroutines.async
internal class AppsAdapter(
private val layoutType: Int,
private val packageManager: PackageManager,
private val fragmentManager: FragmentManager,
private val appsCount: TextView?) : RecyclerView.Adapter<AppsAdapter.AppsViewHolder>() {
private val appsCount: TextView) : RecyclerView.Adapter<AppsAdapter.AppsViewHolder>() {
private var oldList = mutableListOf<AppInfo>()
// private var appGravity: Int = Gravity.CENTER
@ -124,7 +125,7 @@ internal class AppsAdapter(
oldList.clear()
oldList.addAll(newList)
newList.size.let {
appsCount?.text = it.toString()
appsCount.text = it.toString()
appsSize = it
}
}

File diff suppressed because it is too large Load Diff

View File

@ -134,7 +134,7 @@ class BluetoothManager {
//블루투스 상태(켜짐 / 꺼짐 / 지원 불가 기기)
fun blueToothState(): String {
if (blueToothAdapter != null) {
if (blueToothAdapter?.isEnabled == true) {
if (blueToothAdapter!!.isEnabled) {
return BLUETOOTH_STATE.ENABLED.statestr
} else {
return BLUETOOTH_STATE.DISABLED.statestr
@ -167,6 +167,7 @@ class BluetoothManager {
val action = intent!!.action
if (context == null) return
if (ActivityCompat.checkSelfPermission(context!!, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) return
val device: BluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)!!
getPairedDevices()
}
}

View File

@ -2,7 +2,6 @@ package bums.lunatic.launcher.helpers
import android.content.SharedPreferences
import bums.lunatic.launcher.model.RssDataType
import bums.lunatic.launcher.utils.Blog
import kr.lunaticbum.utils.preferences.PrefJsonConvert
import kr.lunaticbum.utils.preferences.PrefKey
import kr.lunaticbum.utils.preferences.PreferencesHelper
@ -31,13 +30,7 @@ enum class PrefLong(val def : Long) : PrefKey<Long> {
midTimePeriod(30L),
maxQueryCount(18L);
override fun set(value : Long) { PrefHelper.putLong(this.name, value) }
override fun get(def : Long?) : Long {
val value = PrefHelper.getLong(this.name, def ?: this.def) ?: this.def
// Blog.LOGE("$name : $value")
return value
}
override fun get(def : Long?) : Long = PrefHelper.getLong(this.name, def as? Long ?: this.def) ?: 0L
override fun getKey() = this.name
}
@ -104,7 +97,7 @@ object PrefHelper : PreferencesHelper() {
fun getBoolean(key: String, def: Boolean) = get(getBooleanPrefix().plus(key), def)
fun putBoolean(key: String, value: Boolean) = put(getBooleanPrefix().plus(key), value)
fun getLong(key: String, def: Long) = get(getLongPrefix().plus(key), def)
fun putLong(key: String, value: Long) = put(getLongPrefix().plus(key), value)
fun putLong(key: String, value: Long) = put(getBooleanPrefix().plus(key), value)
fun getString(key: String, def: String) = get(getStringPrefix().plus(key), def)
fun putString(key: String, value: String) = put(getStringPrefix().plus(key), value)

View File

@ -1,473 +0,0 @@
package bums.lunatic.launcher.home
import android.content.Context
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.AttributeSet
import android.util.Log
import android.view.KeyEvent
import android.view.KeyEvent.ACTION_UP
import android.view.KeyEvent.KEYCODE_BUTTON_A
import android.view.KeyEvent.KEYCODE_BUTTON_B
import android.view.KeyEvent.KEYCODE_BUTTON_SELECT
import android.view.KeyEvent.KEYCODE_BUTTON_START
import android.view.KeyEvent.KEYCODE_BUTTON_X
import android.view.KeyEvent.KEYCODE_BUTTON_Y
import android.view.KeyEvent.KEYCODE_DPAD_DOWN
import android.view.KeyEvent.KEYCODE_DPAD_UP
import bums.lunatic.launcher.utils.Blog
import com.google.gson.Gson
import org.json.JSONObject
import org.mozilla.gecko.util.ThreadUtils
import org.mozilla.geckoview.ExperimentDelegate
import org.mozilla.geckoview.GeckoResult
import org.mozilla.geckoview.GeckoRuntime
import org.mozilla.geckoview.GeckoRuntimeSettings
import org.mozilla.geckoview.GeckoSession
import org.mozilla.geckoview.GeckoView
import org.mozilla.geckoview.MediaSession
import org.mozilla.geckoview.WebExtension
import org.mozilla.geckoview.WebExtension.MessageDelegate
import org.mozilla.geckoview.WebExtension.PortDelegate
import org.mozilla.geckoview.WebExtensionController.AddonManagerDelegate
import org.mozilla.geckoview.WebRequestError
class GeckoWeb : GeckoView {
constructor(context: Context?) : super(context) {
initWithContext(context)
}
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
initWithContext(context)
}
fun loadUrl(url: String) {
Blog.LOGE("url >>>> ${url}")
if (url.split("//").size > 1) {
url.replace("//","/").replace("https:/","https://").let {
Blog.LOGE("url >> ${url} , it >>> ${it}")
this.session?.loadUri(url)
}
} else {
this.session?.loadUri(url)
}
currentRetryCount = 0;
}
val handle = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
if (msg.what == 0) {
(msg.obj as? ReaderConfig)?.let {
}
}
}
}
var lastedUrl: String? = null
var canGoBack: Boolean? = null
var mPort: WebExtension.Port? = null
object WebExtensionInfo {
val mPortNam = "browser"
val extPath = "resource://android/assets/extensions/my_extension/"
val extId = "messaging@booktoki468.com"
}
var mExtension: WebExtension? = null
var mSession: GeckoSession? = null
val addonManagerDelegate = object : AddonManagerDelegate {
override fun onReady(extension: WebExtension) {
Blog.LOGE("onReady ${extension.id} from WebExtension")
mExtension = extension
}
override fun onEnabling(extension: WebExtension) {
Blog.LOGE("onEnabling ${extension.id} from WebExtension")
}
override fun onEnabled(extension: WebExtension) {
Blog.LOGE("onEnabled ${extension.id} from WebExtension")
mExtension = extension
}
}
private fun initWithContext(context: Context?) {
context?.let { context ->
initGeckoRuntime(context)
mSession = GeckoSession()
mSession?.contentDelegate = contentDelegate
mSession?.progressDelegate = progressDelegate
mSession?.navigationDelegate = navigationDelegate
sRuntime?.apply {
webExtensionController.setAddonManagerDelegate(addonManagerDelegate)
webExtensionController.ensureBuiltIn(WebExtensionInfo.extPath, WebExtensionInfo.extId)
.accept( // Register message delegate for background script
{ extension: WebExtension? ->
ThreadUtils.runOnUiThread(Runnable { mSession?.let{session-> extension?.let { session.webExtensionController.setMessageDelegate(it,messageDelegate,WebExtensionInfo.mPortNam) }} })
},
{ e: Throwable? -> Log.e("MessageDelegate", "Error registering WebExtension", e) })
mSession?.mediaDelegate = mediaDelegate
mSession?.mediaSessionDelegate = mediaSessionDelegate
mSession?.open(sRuntime!!)
}.let {
this.setSession(mSession!!)
this.loadUrl("https://booktoki468.com") // Or any other URL...
}
}
}
val mediaDelegate = object : GeckoSession.MediaDelegate {
override fun onRecordingStatusChanged(
session: GeckoSession,
devices: Array<out GeckoSession.MediaDelegate.RecordingDevice?>
) {
super.onRecordingStatusChanged(session, devices)
}
}
val mediaSessionDelegate = object : MediaSession.Delegate {
override fun onActivated(
session: GeckoSession,
mediaSession: MediaSession
) {
Blog.LOGE("onActivated")
super.onActivated(session, mediaSession)
}
override fun onDeactivated(
session: GeckoSession,
mediaSession: MediaSession
) {
Blog.LOGE("onDeactivated")
super.onDeactivated(session, mediaSession)
}
override fun onMetadata(
session: GeckoSession,
mediaSession: MediaSession,
meta: MediaSession.Metadata
) {
Blog.LOGE("onMetadata ${Gson().toJson(meta)}")
super.onMetadata(session, mediaSession, meta)
}
override fun onFeatures(
session: GeckoSession,
mediaSession: MediaSession,
features: Long
) {
Blog.LOGE("onFeatures $features")
super.onFeatures(session, mediaSession, features)
}
override fun onPlay(
session: GeckoSession,
mediaSession: MediaSession
) {
Blog.LOGE("onPlay")
super.onPlay(session, mediaSession)
}
override fun onPause(
session: GeckoSession,
mediaSession: MediaSession
) {
Blog.LOGE("onPause")
super.onPause(session, mediaSession)
}
override fun onStop(
session: GeckoSession,
mediaSession: MediaSession
) {
Blog.LOGE("onStop")
super.onStop(session, mediaSession)
}
override fun onPositionState(
session: GeckoSession,
mediaSession: MediaSession,
state: MediaSession.PositionState
) {
Blog.LOGE("onPositionState $state")
super.onPositionState(session, mediaSession, state)
}
override fun onFullscreen(
session: GeckoSession,
mediaSession: MediaSession,
enabled: Boolean,
meta: MediaSession.ElementMetadata?
) {
Blog.LOGE("onFullscreen $Boolean ${Gson().toJson(meta)}")
super.onFullscreen(session, mediaSession, enabled, meta)
}
}
private fun initGeckoRuntime(context : Context) {
if (sRuntime == null) {
try {
val settings: GeckoRuntimeSettings =
GeckoRuntimeSettings.Builder().extensionsProcessEnabled(true)
.extensionsWebAPIEnabled(true)
.experimentDelegate(experimentDelegate)
.remoteDebuggingEnabled(true).build()
sRuntime = GeckoRuntime.create(context, settings)
} catch (e: Exception) {
}
}
}
val experimentDelegate = object : ExperimentDelegate {
override fun onGetExperimentFeature(feature: String): GeckoResult<JSONObject?> {
Blog.LOGE("onGetExperimentFeature $feature")
return super.onGetExperimentFeature(feature)
}
override fun onRecordExposureEvent(feature: String): GeckoResult<Void?> {
Blog.LOGE("onRecordExposureEvent $feature")
return super.onRecordExposureEvent(feature)
}
override fun onRecordExperimentExposureEvent(
feature: String,
slug: String
): GeckoResult<Void?> {
Blog.LOGE("onRecordExperimentExposureEvent $feature , $slug")
return super.onRecordExperimentExposureEvent(feature, slug)
}
override fun onRecordMalformedConfigurationEvent(
feature: String,
part: String
): GeckoResult<Void?> {
Blog.LOGE("onRecordMalformedConfigurationEvent $feature , $part")
return super.onRecordMalformedConfigurationEvent(feature, part)
}
}
val contentDelegate = object : GeckoSession.ContentDelegate {
override fun onTitleChange(
session: GeckoSession,
title: String?
) {
Blog.LOGE("onTitleChange $title")
super.onTitleChange(session, title)
}
override fun onCrash(session: GeckoSession) {
Blog.LOGE("onCrash")
super.onCrash(session)
}
override fun onPaintStatusReset(session: GeckoSession) {
Blog.LOGE("onPaintStatusReset")
super.onPaintStatusReset(session)
}
override fun onFirstContentfulPaint(session: GeckoSession) {
Blog.LOGE("onFirstContentfulPaint")
super.onFirstContentfulPaint(session)
}
}
val progressDelegate = object : GeckoSession.ProgressDelegate {
override fun onSecurityChange(
session: GeckoSession,
securityInfo: GeckoSession.ProgressDelegate.SecurityInformation
) {
Blog.LOGE("onSecurityChange $securityInfo from WebExtension")
super.onSecurityChange(session, securityInfo)
}
override fun onSessionStateChange(
session: GeckoSession,
sessionState: GeckoSession.SessionState
) {
Blog.LOGE("onSessionStateChange $sessionState from WebExtension")
super.onSessionStateChange(session, sessionState)
}
override fun onPageStart(session: GeckoSession, url: String) {
super.onPageStart(session, url)
}
override fun onPageStop(session: GeckoSession, success: Boolean) {
Blog.LOGE("onPageStop $success from WebExtension")
super.onPageStop(session, success)
if (success && mPort != null) {
if (mPort == null) {
// No extension registered yet, let's ignore this message
return
}
}
}
}
val navigationDelegate = object : GeckoSession.NavigationDelegate {
override fun onLoadError(
session: GeckoSession,
uri: String?,
error: WebRequestError
): GeckoResult<String>? {
error.printStackTrace()
Blog.LOGE("onLoadError >>> ${uri} ::>> ${error.category} , ${error.code}")
if (error.code == WebRequestError.ERROR_NET_RESET) {
}
return super.onLoadError(session, uri, error)
}
override fun onNewSession(
session: GeckoSession,
uri: String
): GeckoResult<GeckoSession>? {
Blog.LOGE("GeckoView", "onNewSession: $session from WebExtension")
return super.onNewSession(session, uri)
}
override fun onLocationChange(
session: GeckoSession,
url: String?,
perms: MutableList<GeckoSession.PermissionDelegate.ContentPermission>,
hasUserGesture: Boolean
) {
// url이 현재 로드된 주소입니다.
Blog.LOGE("GeckoView", "현재 주소: $url")
Blog.LOGE("GeckoView", "현재 session: $session")
url?.let { url ->
if (url.split("//").size > 1) {
url.replace("//", "/").replace("https:/", "https://").let {
Blog.LOGE("url >> ${url} , it >>> ${it}")
lastedUrl = url
}
} else {
lastedUrl = url
}
}
}
override fun onCanGoBack(session: GeckoSession, canGoBack: Boolean) {
super.onCanGoBack(session, canGoBack)
this@GeckoWeb.canGoBack = canGoBack
if (canGoBack) {
}
}
}
val portDelegate: PortDelegate =
object : PortDelegate {
override fun onPortMessage(
message: Any, port: WebExtension.Port
) {
Blog.LOGE("PortDelegate", "Received message from extension: $message")
}
override fun onDisconnect(port: WebExtension.Port) {
// This port is not usable anymore.
if (port === mPort) {
mPort = null
}
}
}
val messageDelegate: MessageDelegate =
object : MessageDelegate {
override fun onConnect(port: WebExtension.Port) {
mPort = port
mPort!!.setDelegate(portDelegate)
}
override fun onMessage(
nativeApp: String,
message: Any,
sender: WebExtension.MessageSender
): GeckoResult<in Any>? {
Blog.LOGE(
"messageDelegate",
"onMessage from WebExtension: ${nativeApp} , $message , ${sender.webExtension.id}"
)
return super.onMessage(nativeApp, message, sender)
}
}
fun onStart() {
}
fun onResume() {
}
fun onDestroy() {
sRuntime = null
}
override fun dispatchKeyEvent(ev: KeyEvent): Boolean {
Blog.LOGE("dispatch ev?.device?.name >>> ${ev?.device?.name}")
if (ev?.device?.name?.contains("SM-031N Mouse") == true) {
when (ev.action) {
ACTION_UP -> {
Blog.LOGE("dispatch dispatchKeyEvent>>> ${ev}")
when (ev.keyCode) {
KEYCODE_BUTTON_Y -> {
}
KEYCODE_BUTTON_X -> {
}
KEYCODE_BUTTON_A -> {
}
KEYCODE_BUTTON_B -> {
}
KEYCODE_DPAD_DOWN -> {
}
KEYCODE_DPAD_UP -> {
}
KEYCODE_BUTTON_START -> {
}
KEYCODE_BUTTON_SELECT -> {
}
else -> {}
}
}
else -> {}
}
return true
}
return super.dispatchKeyEvent(ev)
}
companion object {
private const val TAG = "DualScreenStatus"
var sRuntime: GeckoRuntime? = null
var currentRetryCount = 0
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,250 +0,0 @@
package bums.lunatic.launcher.home
import android.content.Context
import android.content.Intent
import android.os.Environment
import android.webkit.CookieManager
import androidx.core.content.FileProvider
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kr.lunaticbum.awesomewebview.helpers.DownPicUtil
import kr.lunaticbum.awesomewebview.helpers.DownPicUtil.DownFinishListener
import kr.lunaticbum.utils.log.LogUtil
import org.jsoup.Jsoup
import org.jsoup.UnsupportedMimeTypeException
import java.io.BufferedWriter
import java.io.File
import java.io.FileWriter
import java.net.URL
import java.text.SimpleDateFormat
import java.util.Date
val defaultTime = 200L
class OfflineContents(val context: Context, val host : String, val cookie: String, val agent: String, val current: String, val newPath: String, val value: String, val autoCheck : Boolean, val mediaUrls : ArrayList<String>) {
val targetFile : File
val filePath = "index.html"
val path = File(
Environment.getExternalStorageDirectory(),
"bums"
)
val newFolder = File(path, newPath).apply { mkdirs() }
val newFile : File
var htmlString : StringBuffer
val urlPathMap : HashMap<String,String> = hashMapOf()
var reqCount = 0
var endOfLooPCheck = false
val lDownFinishListener = object : DownFinishListener {
override fun onDownFinish(url: String, path: String) {
LogUtil.e("Url >> ${url} path >> ${path}")
urlPathMap.put(url, path)
reqCount -= 1
if (reqCount == 0 && endOfLooPCheck) {
enofLoop()
}
}
override fun onError() {
reqCount -= 1
if (reqCount == 0 && endOfLooPCheck) {
enofLoop()
}
}
}
init {
targetFile = File(newFolder, filePath)
newFile = File(
path,
newPath.plus(SimpleDateFormat("yyyMMdd").format(Date())).plus(".html")
)
htmlString= trimHtnl(value, host)
}
var onItEndof = false
fun enofLoop() {
if (onItEndof) return
onItEndof = true
LogUtil.e("on it enofLoop")
urlPathMap.forEach { t, u ->
val file = File(u)
var contentsUriString = FileProvider.getUriForFile(
context,
"${context.packageName}.fileprovider",
file
).toString()
var targetString = t
var targetIdx = htmlString.indexOf(targetString)
if (targetIdx > 0) {
htmlString?.replace(
targetIdx,
targetIdx.plus(targetString.length),
contentsUriString
)
}
targetString = t.replace("&", "&amp;")
targetIdx = htmlString.indexOf(targetString)
if (targetIdx > 0) {
htmlString?.replace(
targetIdx,
targetIdx.plus(targetString.length),
contentsUriString
)
}
}
if (autoCheck) {
LogUtil.e("on it enofLoop autoCheck ${autoCheck}")
moveFile()
context.startActivity(Intent(context,RssViewerActivity::class.java).apply {
action = Intent.ACTION_VIEW
data = FileProvider.getUriForFile(
context,
"${context.packageName}.fileprovider",
newFile
)
})
} else {
moveFile()
}
}
fun moveFile() {
indexSave(htmlString, targetFile, host)
targetFile.copyTo(newFile)
if (targetFile.parentFile.isDirectory) {
targetFile.parentFile.listFiles().forEach {
it.delete()
}
targetFile.parentFile.delete()
}
targetFile.delete()
}
fun excute() {
CoroutineScope(Dispatchers.IO).launch {
LogUtil.e("onHtml value >> ${value}")
mediaUrls.forEach { url ->
var downPic = false
try {
LogUtil.e("try Jsoup.parse ${url}")
Jsoup.parse(URL(url), defaultTime.times(4).toInt()).let {
try {
LogUtil.e("onit Jsoup.parse ${it.title()}")
if (it.select("svg").size > 0) {
try {
downPic(url, agent, current!!, cookie!!, lDownFinishListener)
reqCount += 1
} catch (e : Exception) {
e.printStackTrace()
}
} else {
it.getElementsByTag("video")?.forEach {
it.attribute("src").value?.let {
var url = if (it.startsWith("http")) {
it
} else {
"https:".plus(it)
}
try {
downMp4(url, agent, current!!, cookie!!, lDownFinishListener)
reqCount += 1
} catch (e : Exception) {
e.printStackTrace()
}
}
}
}
} catch (e: UnsupportedMimeTypeException) {
LogUtil.e("e.message3 ${e.message}")
} catch (e: Exception) {
LogUtil.e("e.message4 ${e.message}")
}
}
} catch (e: UnsupportedMimeTypeException) {
LogUtil.e("e.message ${e.message}")
LogUtil.e("e.message ${e.localizedMessage}")
if (e.message?.contains("Must be text") == true) {
downPic = true
}
} catch (e: Exception) {
if (url.contains("dcimg") == true) {
downPic = true
}
LogUtil.e("e.message2 ${e.message}")
} finally {
if (downPic) {
try {
downPic(url, agent, current!!, cookie!!, lDownFinishListener)
reqCount += 1
} catch (e : Exception) {
e.printStackTrace()
}
}
}
delay(defaultTime)
}
LogUtil.e("END OF LOOP ${reqCount}")
endOfLooPCheck = true
delay(defaultTime.times(4))
if (reqCount <= 0) {
enofLoop()
}
}
}
fun indexSave(htmlString:StringBuffer, targetFile :File, host: String) {
BufferedWriter(FileWriter(targetFile)).use { writer ->
trimHtnl(htmlString.toString(), host)?.let { result ->
writer.write(result.toString())
}
}
}
fun trimHtnl(target : String, host : String) : StringBuffer {
var result = target.replace("\\\"","\"").replace("\\n\\t\\t\\t","").replace("\\n\\t\\t","").replace("\\n\\t","").replace("\\t", "").replace("\\n", "").replace("\"\"\"","").replace("href=\"//","href=\"https://").replace("src=\"//","src=\"https://").replace("url(\"//","url(\"https://").replace("url(&quot;//","url(&quot;https://")
if (host?.contains("clien") == true) {
result = result.replace("href=\"/service","href=\"https://m.clien.net/service").replace("href=\"\\&quot;/service","href=\"\\&quot;https://m.clien.net/service")
}
return StringBuffer(result)
}
fun downMp4(url : String, agent : String, current : String,cookie : String, listner :DownFinishListener) {
LogUtil.e("try imageFile down ${url}")
val path = File(
Environment.getExternalStorageDirectory(),
"bums"
)
DownPicUtil.downMp4(
File(
path,"private_mp4"
).path,
url,
agent,
current,
cookie,
listner
)
}
fun downPic( url : String, agent : String, current : String,cookie : String, listner :DownFinishListener) {
LogUtil.e("try imageFile down ${url}")
val cookieManager =
CookieManager.getInstance()
val cookie =
cookieManager.getCookie(current)
val path = File(
Environment.getExternalStorageDirectory(),
"bums"
)
DownPicUtil.downPic(
File(path, "private_img").path,
url,
agent,
current,
cookie,
listner)
}
}

View File

@ -1,16 +1,8 @@
package bums.lunatic.launcher.home
import android.content.ClipData
import android.content.ClipboardManager
import android.content.ComponentName
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.print.PDFPrint
import android.provider.AlarmClock
import android.util.Base64
import android.view.HapticFeedbackConstants
import android.view.KeyEvent
import android.view.KeyEvent.ACTION_UP
import android.view.KeyEvent.KEYCODE_BUTTON_A
@ -26,52 +18,21 @@ import android.view.KeyEvent.KEYCODE_DPAD_UP
import android.view.MotionEvent
import android.view.MotionEvent.ACTION_MOVE
import android.view.View
import android.webkit.CookieManager
import android.webkit.CookieSyncManager
import android.webkit.JavascriptInterface
import android.webkit.ValueCallback
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.core.net.toUri
import androidx.core.view.postDelayed
import bums.lunatic.launcher.LauncherActivity.Companion.lActivity
import bums.lunatic.launcher.behavior.Behavior
import bums.lunatic.launcher.helpers.Constants.Companion.BOTTOM_SHEET_TAG
import bums.lunatic.launcher.helpers.Constants.Companion.KEY_LOCK_METHOD
import bums.lunatic.launcher.helpers.UniUtils.Companion.expandNotificationPanel
import bums.lunatic.launcher.helpers.UniUtils.Companion.lockMethod
import bums.lunatic.launcher.model.CiliMagnet
import bums.lunatic.launcher.model.RssData
import bums.lunatic.launcher.qaccess.QuickAccess
import bums.lunatic.launcher.settings.SettingsActivity
import bums.lunatic.launcher.utils.Blog
import bums.lunatic.launcher.utils.SimpleFingerGestures
import bums.lunatic.launcher.workers.WorkersDb
import com.google.gson.Gson
import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.ext.query
import io.realm.kotlin.ext.realmListOf
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kr.lunaticbum.awesomewebview.AwesomeWebView
import kr.lunaticbum.awesomewebview.AwesomeWebView.Builder
import kr.lunaticbum.awesomewebview.AwesomeWebViewActivity
import kr.lunaticbum.awesomewebview.listeners.BroadCastManager
import kr.lunaticbum.awesomewebview.objects.CustomMenu
import kr.lunaticbum.utils.content.ContextUtil
import kr.lunaticbum.utils.log.LogUtil
import org.jsoup.Jsoup
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.FileInputStream
import java.io.IOException
import java.io.InputStream
import java.net.URLEncoder
import java.nio.charset.Charset
import java.security.MessageDigest
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
import kotlin.text.Charsets.UTF_8
class RssViewBuilder(context: Context) : AwesomeWebView.Builder(context) {
var rssId : String = ""
@ -100,142 +61,27 @@ class RssViewBuilder(context: Context) : AwesomeWebView.Builder(context) {
ContextUtil.startActivity(intent)
}
}
class RssViewerActivity : AwesomeWebViewActivity(), View.OnGenericMotionListener , View.OnTouchListener {
class RssViewerActivity : AwesomeWebViewActivity(), View.OnGenericMotionListener {
var actionButtonPressX = 0f
var actionButtonPressY = 0f
var rssId : String = ""
// var currentIdx = 0
var currentIdx = 0
var double = false
var rssList: MutableList<String> = ArrayList()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
LogUtil.e("intent >>>> ${intent}")
if (intent.action.equals(Intent.ACTION_VIEW)) {
intent.data.toString()?.let {
loadWithIntent = true
load(it)
}
} else {
loadWithIntent = false
}
webView?.setOnTouchListener(this)
}
private var startX = 0f
private var startY = 0f
private var startTime = 0L
// 임계값(앱에 맞게 조정)
private val swipeThreshold = 150 // 스와이프 최소 거리(px)
private val swipeTime = 300 // 스와이프 최대 시간(ms)
private val clickThreshold = 30 // 클릭으로 인정할 최대 이동 거리(px)
override fun onTouch(v: View?, event: MotionEvent): Boolean {
if(event.device.name.equals("JX-12",true)) {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
startX = event.x
startY = event.y
startTime = System.currentTimeMillis()
return true
}
MotionEvent.ACTION_UP -> {
val endX = event.x
val endY = event.y
val endTime = System.currentTimeMillis()
val dx = endX - startX
val dy = endY - startY
val duration = endTime - startTime
// 클릭: 거의 움직이지 않고 짧은 시간
if (Math.abs(dx) < clickThreshold && Math.abs(dy) < clickThreshold && duration < 250) {
onClick() // View의 기본 클릭 호출
return true
}
// 좌우 스와이프: 수평 이동이 크고, 빠르게
if (Math.abs(dx) > swipeThreshold && Math.abs(dx) > Math.abs(dy) && duration < swipeTime) {
if (dx > 0) {
onSwipeRight()
} else {
onSwipeLeft()
}
return true
}
Blog.LOGE("dy >>> $dy")
// 상하 스크롤: 수직 이동이 더 크고, 일정 거리 이상
// if (Math.abs(dy) > swipeThreshold && Math.abs(dy) > Math.abs(dx)) {
// if (dy > 0) {
// onScrollDown()
// } else {
// onScrollUp()
// }
// return true
// }
}
else -> return super.onTouchEvent(event)
}
}
return super.onTouchEvent(event)
}
private fun onClick() {
Blog.LOGE("onClick")
finish()
}
// 아래 메서드에 원하는 동작 구현
private fun onSwipeLeft() {
Blog.LOGE("onSwipeLeft")
vote()
}
private fun onSwipeRight() {
Blog.LOGE("onSwipeRight")
doNextPage()
}
private fun onScrollUp() {
Blog.LOGE("onScrollUp")
webView?.let {
it.scrollBy(0, (it.contentHeight / 100).coerceAtLeast(200) * -1)
}
}
private fun onScrollDown() {
Blog.LOGE("onScrollDown")
webView?.let {
it.scrollBy(0, (it.contentHeight / 100).coerceAtLeast(200) * 1)
}
}
override fun onResume() {
super.onResume()
webView?.setOnGenericMotionListener(this)
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
if (intent?.action?.equals(Intent.ACTION_VIEW) == true) {
intent?.data?.toString()?.let {
loadWithIntent = true
load(it)
}
} else {}
}
var lasteventTime = 0L
override fun onGenericMotion(p0: View?, ev: MotionEvent?): Boolean {
if (ev?.device?.name?.contains("SM-031N Mouse") == true) {
if(ev.action == ACTION_MOVE && ev.x != ev.y) {
val correctTime = (ev.eventTime - lasteventTime) > 2
if (correctTime) {
// Blog.LOGE("onGenericMotionEvent webviews ${p0} ev?.device?.name >>> ${ev?.device?.name} >> ${ev}")
Blog.LOGE("onGenericMotionEvent webviews ${p0} ev?.device?.name >>> ${ev?.device?.name} >> ${ev}")
if (ev.x <= -1.0f) {
leftClick()
} else if (ev.x >= 1.0f) {
@ -254,22 +100,19 @@ class RssViewerActivity : AwesomeWebViewActivity(), View.OnGenericMotionListene
}
return false
}
private var lastX = 0f
private var lastY = 0f
private var onDown = false
override fun onGenericMotionEvent(ev: MotionEvent?): Boolean {
if (ev?.device?.name?.contains("SM-031N Mouse") == true) {
// Blog.LOGE("onGenericMotionEvent ev?.device?.name >>> ${ev?.device?.name} >> ${ev}")
Blog.LOGE("onGenericMotionEvent ev?.device?.name >>> ${ev?.device?.name} >> ${ev}")
return true
}
return super.onGenericMotionEvent(ev)
}
override fun dispatchKeyEvent(ev: KeyEvent): Boolean {
// Blog.LOGE("dispatch ev?.device?.name >>> ${ev?.device?.name}")
Blog.LOGE("dispatch ev?.device?.name >>> ${ev?.device?.name}")
if (ev?.device?.name?.contains("SM-031N Mouse") == true) {
// Blog.LOGE("onGenericMotionEvent ev?.device?.name >>> ${ev?.device?.name} >> ${ev}")
Blog.LOGE("onGenericMotionEvent ev?.device?.name >>> ${ev?.device?.name} >> ${ev}")
when(ev.action) {
ACTION_UP -> {
when(ev.keyCode) {
@ -312,34 +155,25 @@ class RssViewerActivity : AwesomeWebViewActivity(), View.OnGenericMotionListene
}
fun vote(){
if (!loadWithIntent) {
Blog.LOGE("Arrow Center Click")
WorkersDb.getRealm().apply {
writeBlocking {
val result = query<RssData>().query("originPage == $0", rssId).find()
if (result.size > 0) {
result.forEach { it.vote = true }
}
Blog.LOGE("Arrow Center Click")
WorkersDb.getRealm().apply {
writeBlocking {
val result = query<RssData>().query("originPage == $0", rssId).find()
if(result.size > 0) {
result.forEach { it.vote = true }
}
}
doNextPage()
// webView?.evaluateJavascript("document.documentElement.outerHTML",
// object : ValueCallback<String> {
// override fun onReceiveValue(value: String?) {
// val html = value?.replace("\\u003C", "<")
// onHtml(html, false)
// }
// })
} else {
finish()
}
}
fun doNextPage() {
rssList.removeAll { it.equals(rssId) }
if (rssList.size > 0) {
rssId = rssList.removeAt(0)
rssList.remove(rssId)
if (currentIdx < rssList.size - 1) {
currentIdx += 1
rssId = rssList.get(currentIdx)
Blog.LOGE("Arrow Right Click ${currentIdx} ${rssId}")
load(rssId)
} else if (currentIdx > 0) {
currentIdx -= 1
rssId = rssList.get(currentIdx)
Blog.LOGE("Arrow Left Click ${currentIdx} ${rssId}")
load(rssId)
} else {
Toast.makeText(this, "없어 끄자", Toast.LENGTH_LONG).show()
@ -347,68 +181,71 @@ class RssViewerActivity : AwesomeWebViewActivity(), View.OnGenericMotionListene
}
registCancelSearch()
}
fun hideRss() {
if (!loadWithIntent) {
Blog.LOGE("make no show")
WorkersDb.getRealm().apply {
writeBlocking {
val result =
query<RssData>().query("originPage == $0", rssId)
.find()
if (result.size > 0) {
result.forEach { it.read += 5 }
}
Blog.LOGE("make no show")
WorkersDb.getRealm().apply {
writeBlocking {
val result =
query<RssData>().query("originPage == $0", rssId)
.find()
if (result.size > 0) {
result.forEach { it.read += 5 }
}
}
doNextPage()
}
rssList.remove(rssId)
if (currentIdx < rssList.size - 1) {
currentIdx += 1
rssId = rssList.get(currentIdx)
Blog.LOGE("Arrow Right Click ${currentIdx} ${rssId}")
load(rssId)
registCancelSearch()
} else if (currentIdx > 0) {
currentIdx -= 1
rssId = rssList.get(currentIdx)
Blog.LOGE("Arrow Left Click ${currentIdx} ${rssId}")
load(rssId)
registCancelSearch()
} else {
finish()
}
}
fun rightClick() {
doNextPage()
if (currentIdx < rssList.size - 1) {
currentIdx += 1
rssId = rssList.removeAt(currentIdx)
Blog.LOGE("Arrow Right Click ${currentIdx} ${rssId}")
load(rssId)
registCancelSearch()
} else {
Toast.makeText(this, "없어 끄자", Toast.LENGTH_LONG).show()
fast()
}
}
fun leftClick() {
hideRss()
if (currentIdx > 0) {
currentIdx -= 1
rssId = rssList.removeAt(currentIdx)
Blog.LOGE("Arrow Left Click ${currentIdx} ${rssId}")
load(rssId)
registCancelSearch()
} else {
Toast.makeText(this, "없어 끄자", Toast.LENGTH_LONG).show()
fast()
}
Blog.LOGE("Arrow Left Click")
}
fun getUnit() = ((webView?.height ?: 0) * 0.4).toInt()
fun scrollDown() {
try {
Blog.LOGE("Arrow Down Click")
registCancelSearch()
runOnUiThread {
webView?.scrollTo(webView?.scrollX?: 0,(webView?.scrollY?: 0) + getUnit())
}
} catch (e : Exception) {
e.printStackTrace()
}
Blog.LOGE("Arrow Down Click")
registCancelSearch()
webView?.scrollTo(webView?.scrollX ?: 0, (webView?.scrollY ?: 0) + getUnit())
}
override var pdfListner : PDFPrint.OnPDFPrintListener? = object : PDFPrint.OnPDFPrintListener {
override fun onSuccess(file: File?) {
LogUtil.e("file.absolutePath >>> ${file?.absolutePath}")
Toast.makeText(
applicationContext,
resources.getString(
stringResPhotoSavedTo
) + file?.absolutePath,
Toast.LENGTH_LONG
).apply {
}.show()
}
override fun onError(exception: Exception?) {
}
}
// val tika: Tika = Tika()
override fun dispatchGenericMotionEvent(ev: MotionEvent?): Boolean {
if (ev?.device?.name?.contains("BLE-M3") == true) {
Blog.LOGE("keyEvent >>>>> dispatchGenericMotionEvent ${ev}")
@ -480,33 +317,25 @@ class RssViewerActivity : AwesomeWebViewActivity(), View.OnGenericMotionListene
Blog.LOGE("Arrow Up Click")
registCancelSearch()
}
protected fun load(newUrl: String) {
newUrl?.let { it ->
var url = if(it.startsWith("http://")) {
"https://${it.replace("http://","")}"
} else it
// LogUtil.e("newUrl >>> ${url}")
url.toUri().host?.let {
val splits = it.replace("http://","").replace("https://","").split(".")
when(splits.size) {
1-> host = splits[0]
2-> host = splits[0]
3-> host = splits[1]
4-> host = splits[2]
else -> {
host = null
}
newUrl.toUri().host?.let {
val splits = it.replace("http://","").replace("https://","").split(".")
when(splits.size) {
1-> host = splits[0]
2-> host = splits[0]
3-> host = splits[1]
4-> host = splits[2]
else -> {
host = null
}
}
if (extraHeaders == null) {
webView!!.loadUrl(url)
} else {
webView!!.loadUrl(url, extraHeaders!!)
}
registCancelSearch()
}
if (extraHeaders == null) {
webView!!.loadUrl(newUrl!!)
} else {
webView!!.loadUrl(newUrl!!, extraHeaders!!)
}
registCancelSearch()
}
override fun initializeOptions() {
@ -518,405 +347,29 @@ class RssViewerActivity : AwesomeWebViewActivity(), View.OnGenericMotionListene
builder?.rssList?.let { this.rssList.addAll(it) }
Blog.LOGE("this.rssList >>>> ${this.rssList}")
}
override fun bindViews() {
super.bindViews()
if (this.rssId.contains(".guru")|| this.rssId.contains("bookto")) {
webView?.clearCache(true)
Blog.LOGE("this.webView >>>> ${this.rssId}")
Blog.LOGE("this.webView >>>> ${this.webView}")
if (this.rssId.contains(".guru")) webView?.alpha = 0.2f
webView?.addJavascriptInterface(gji, "GJI")
this.rssList.forEachIndexed { index, s ->
if (s.equals(rssId)) {
currentIdx = index
return@forEachIndexed}
}
}
fun ByteArray.toHex() = joinToString(separator = "") { byte -> "%02x".format(byte) }
fun hashString(str: String, algorithm: String): ByteArray =
MessageDigest.getInstance(algorithm).digest(str.toByteArray(UTF_8))
fun getBase64ImageData(fileName : String) : String {
val inputStream: InputStream =
FileInputStream(fileName) // You can get an inputStream using any I/O API
val bytes: ByteArray
val buffer = ByteArray(8192)
var bytesRead: Int
val output = ByteArrayOutputStream()
try {
while ((inputStream.read(buffer).also { bytesRead = it }) != -1) {
output.write(buffer, 0, bytesRead)
}
} catch (e: IOException) {
e.printStackTrace()
}
bytes = output.toByteArray()
return Base64.encodeToString(bytes, Base64.DEFAULT)
}
fun run(value : String, autoCheck : Boolean) {
webView!!.setOnScrollChangeListener(null)
var mediaUrls = arrayListOf<String>()
mediaUrls.addAll(this.mediaUrls)
CookieSyncManager.createInstance(applicationContext)
CookieSyncManager.getInstance().sync()
val cookieManager =
CookieManager.getInstance()
val cookie =
cookieManager.getCookie(webView!!.url)
val agent = webView!!.settings.userAgentString
val current = webView!!.url
val newPath = hashString(current!!, "MD5").toHex()
Executors.newSingleThreadScheduledExecutor().schedule({
OfflineContents(this@RssViewerActivity, host!!,cookie,agent,current,newPath,value,autoCheck,mediaUrls).excute()
}, defaultTime, TimeUnit.MILLISECONDS)
runOnUiThread {
hideBlock()
if (!autoCheck) {
doNextPage()
}
}
}
override fun onTrimMemory(level: Int) {
LogUtil.e("onTrimMemory >>> ${level} current ${url} current ${webView?.url ?: ""}")
super.onTrimMemory(level)
}
fun showDi(code : String, items : ArrayList<String>, links : ArrayList<String>) {
runOnUiThread {
registCancelSearch()
hideBlock()
val builder = AlertDialog.Builder(this@RssViewerActivity)
builder.setTitle("code : ${code}")
builder?.setItems(
items.toTypedArray()
) { dialog, which ->
LogUtil.e("hitTestResult.extra >>> ${dialog} ,${which}")
links?.get(which)?.let { link ->
(this.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager)?.let { mng ->
Blog.LOGE("link >>> ${link}")
mng.clearPrimaryClip()
mng.addPrimaryClipChangedListener {
mng.primaryClip?.getItemAt(0)?.text?.let {
if (it.length > 0 && it.startsWith("magnet:?xt=urn:")) {
Blog.LOGE("magnet >>>> $it")
try {
val launchIntent =
packageManager.getLaunchIntentForPackage("com.pikcloud.pikpak")
launchIntent?.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
startActivity(launchIntent)
}catch (e:Exception) {e.printStackTrace()}
}
}
}
mng.setPrimaryClip(ClipData.newPlainText("",link))
}
}
}
val dialog = builder?.create()
dialog?.show()
}
}
val gji = GJInterface(this)
inner class GJInterface(val context: Context) {
@JavascriptInterface
fun onResult(result : String?) {
registCancelSearch()
result.toString()?.replace("\\u003C","<")?.replace("\\&quot;","")?.let {
if (rssId.contains("guru")) {
Jsoup.parse(it)?.let { guru ->
Blog.LOGE("guru >>> ${guru.title()} ")
guru.getElementsByClass("row")?.forEach { row ->
row.getElementsByClass("grid1").first().getElementsByTag("a")?.first()
?.attr("title")?.let { title ->
Blog.LOGE("row >>> ${title.split("]")?.first()?.replace("[", "")}")
}
}
}
} else if(rssId.contains("book")){
Jsoup.parse(it)?.let { book ->
Blog.LOGE("book.title() >>> ${book.title()}")
}
}
}
}
@JavascriptInterface
fun onCode(code : String) {
Blog.LOGE("onCode ${code}")
registCancelSearch()
CoroutineScope(Dispatchers.IO).launch {
var temp = arrayListOf<CiliMagnet>()
Jsoup.connect("https://cili.site/search?q=${URLEncoder.encode(code, Charset.defaultCharset().name())}").get().let { cili ->
cili.getElementsByTag("tr").forEach { cili_tr ->
CiliMagnet().let { ciliMgn ->
ciliMgn.link = if(cili_tr.getElementsByTag("a").size > 0)cili_tr.getElementsByTag("a").get(0).attr("href") else ""
ciliMgn.title = if(cili_tr.getElementsByTag("p").size > 0)cili_tr.getElementsByTag("p").text() else ""
ciliMgn.size = if(cili_tr.getElementsByClass("td-size").size > 0)cili_tr.getElementsByClass("td-size").text() else ""
Blog.LOGE("ciliMgn.size >>>> ${ciliMgn.size}")
Blog.LOGE("ciliMgn.size >>>> ${ciliMgn.title}")
if(ciliMgn.isValid() && temp.size < 8 ) {
try {
Jsoup.connect(ciliMgn.getMagnetPageLink()).get()
.let { mgn_Page ->
if (mgn_Page.getElementsByClass("input-group magnet-box").size > 0) {
mgn_Page.getElementsByClass("input-group magnet-box")
.get(0)?.let { magnet_box ->
magnet_box.getElementById(
"input-magnet"
)?.let { input_magnet ->
Blog.LOGE("input_magnet >>> ${input_magnet}")
ciliMgn.magnetLink =
input_magnet.attr("value")
.replace("&amp;", "&")
}
}
}
}.apply {
temp.add(ciliMgn)
}
}catch (e:Exception) {}
}
}
if(temp.size > 3) {
return@forEach
}
}.apply {
if (temp.size > 0) {
showDi(
code,
temp.map {
it.title.plus(" | ").plus(it.size).plus(" | ")
} as ArrayList<String>, temp.map {
it.magnetLink
} as ArrayList<String>)
}
}
}
}.start()
}
}
override fun onHtml(value: String?, autoCheck : Boolean) {
vote()
// chechHandler.removeCallbacks(cancelSearch)
// if (loadWithIntent){
// return
// }
// showBlock()
//
// var count = (webView!!.contentHeight / (webView!!.height * 0.3).toInt())
// LogUtil.e("count >>>> ${count} webView!!.contentHeight >>>> ${webView!!.contentHeight} , webView!!.height >>>> ${webView!!.height} :: ${(webView!!.height * 0.3).toInt()}")
// chechHandler.postDelayed(pageDown, defaultTime)
// webView!!.setOnScrollChangeListener { v, scrollX, scrollY, oldScrollX, oldScrollY ->
// val measuredHeight: Int = v.measuredHeight
// LogUtil.e("OnScrollChange >>> ${scrollY} , ${oldScrollY}")
// if(measuredHeight + scrollY == webView!!.computeVerticalScrollRange()){
// chechHandler.removeCallbacks(scrollDown)
// chechHandler.removeCallbacks(pageDown)
// chechHandler.postDelayed({
// webView!!.evaluateJavascript("document.documentElement.outerHTML",object : ValueCallback<String> {
// override fun onReceiveValue(value: String?) {
// val html = value?.replace("\\u003C", "<")
// this@RssViewerActivity.run(html!!, autoCheck)
// }
// })
// },defaultTime.times(2))
// } else {
// chechHandler.removeCallbacks(cancelSearch)
// Blog.LOGE("onScrollChanged called PageDown")
//// chechHandler.removeCallbacks(scrollDown)
// if (switch) {
// chechHandler.removeCallbacks(pageDown)
// chechHandler.postDelayed(scrollDown, defaultTime)
// switch = false
// } else {
// switch = true
// chechHandler.removeCallbacks(scrollDown)
// chechHandler.postDelayed(pageDown, defaultTime)
// }
// }
//// else if (scrollY % 10 == 0 || oldScrollY % 10 == 0){
////// chechHandler.removeCallbacks(pageDown)
////// chechHandler.postDelayed(scrollDown, defaultTime)
//// }
// }
}
var switch = false
var scrollDown : Runnable = Runnable{
webView?.let {
var times = if (it.scrollY > 50) it.scrollY / 50 else 5
it.scrollTo(it.scrollX,times.plus(1).times(50))
}
}
var pageDown : Runnable = Runnable{
webView!!.pageDown(false)
}
var isFirst = true
override fun webviewOnPageFinished() {
if (rssId.contains(".guru")) {
registCancelSearch()
webView?.postDelayed(2000L,{
webView?.evaluateJavascript("try{GJI.log();}catch(e){console.log(e);}", {})
webView?.evaluateJavascript("try{GJI.onResult(document.documentElement.outerHTML);}catch(e){console.log(e);}", {})
webView?.evaluateJavascript("document.getElementsByClassName('banner-ad-wrapper')[0].remove()",{})
})
double = false
if(hasYoutubePlayer) {
LogUtil.e("hasYoutubePlayer >>> ${hasYoutubePlayer}")
}
else if(rssId.contains("booktoki")) {
registCancelSearch()
webView?.postDelayed(2000L,{
})
}
else {
double = false
registCancelSearch()
if (hasYoutubePlayer) {
LogUtil.e("hasYoutubePlayer >>> ${hasYoutubePlayer}")
}
WorkersDb.getRealm().apply {
writeBlocking {
val result =
query<RssData>().query("originPage == $0", rssId)
.find()
// if (result.size == 1) {
// result.first().read += 1
// } else {
WorkersDb.getRealm().apply {
writeBlocking {
val result =
query<RssData>().query("originPage == $0", rssId)
.find()
if (result.size == 1) {
result.first().read += 1
} else {
result.forEach { it.read += 1 }
// }
}
}
try {
val muted =
"try{" +
"var videos = document.getElementsByTagName('video');" +
"for (var i = 0; i < videos.length; i++) {" +
"videos[i].muted = true;" +
"}" +
"}catch(e){}"
webView?.evaluateJavascript(muted,{
Blog.LOGE("RESULT >> $it")
})
}catch (e : Exception) {e.printStackTrace()}
try {
val muted =
"try{" +
"var videos = document.getElementsByTagName('video');" +
"for (var i = 0; i < videos.length; i++) {" +
"videos[i].controlsList.remove('nodownload');"
"}" +
"}catch(e){}"
webView?.evaluateJavascript(muted,{
Blog.LOGE("RESULT >> $it")
})
}catch (e : Exception) {e.printStackTrace()}
webView?.postDelayed({
try {
val muted =
"try{" +
"var videos = document.getElementsByTagName('video');" +
"for (var i = 0; i < videos.length; i++) {" +
"videos[i].muted = true;" +
"}" +
"}catch(e){console.log(e);}"
webView?.evaluateJavascript(muted,{
Blog.LOGE("RESULT >> $it")
})
}catch (e : Exception) {e.printStackTrace()}
try {
val muted =
"try{" +
"var videos = document.getElementsByTagName('video');" +
"for (var i = 0; i < videos.length; i++) {" +
"videos[i].controlsList.remove('nodownload');"
"}" +
"}catch(e){console.log(e);}"
webView?.evaluateJavascript(muted,{
Blog.LOGE("RESULT >> $it")
})
}catch (e : Exception) {e.printStackTrace()}
},1000)
if (loadWithIntent) {
webView?.evaluateJavascript(
"try{document.querySelector('meta[name=viewport]').setAttribute('content','initial-scale=1.0')}catch(e){}",
null
)
webView?.evaluateJavascript(
"try{document.querySelector('meta[name=viewport]').setAttribute('content','initial-scale=1.0')}catch(e){}",
null
)
webView?.settings?.useWideViewPort = true
}
if (webView?.url?.contains("dcinside") == true) {
webView?.evaluateJavascript(
"try{document.querySelector('#div_adnmore_area').hidden = true;}catch(e){}",
null
)
} else if (webView?.url?.contains("fmkorea") == true) {
if (loadWithIntent) {
} else {
webView?.postDelayed({
webView?.evaluateJavascript(
"try{document.querySelector('.m_rd_nav_side').hidden = true;}catch(e){}",
null
)
webView?.evaluateJavascript(
"try{document.querySelector('[class*='bd bd_mobile ']').remove();}catch(e){}",
null
)
}, 500L)
}
}
}
registCancelSearch()
}
inner class BookHelper {
@JavascriptInterface
fun sendValueFromHtml(string: String) {
Jsoup.parse(string)?.let { html ->
val toon_intro = html.getElementsByClass("toon_index")?.first()
val view_padding = html.select("#bo_v_con")
if (toon_intro != null) {
}else if (view_padding.size > 0){
//
} else {
Blog.LOGE("finishedUrl >>> ${rssId} :::: ${html.title()}")
}
}
}
}
}
}

View File

@ -4,7 +4,8 @@ import android.util.Xml
import bums.lunatic.launcher.model.NewsData
import bums.lunatic.launcher.model.RssDataInterface
import bums.lunatic.launcher.model.others.Reddit
import bums.lunatic.launcher.utils.beforeOneDay
import bums.lunatic.launcher.utils.Blog
import bums.lunatic.launcher.utils.beforeDay
import com.google.gson.Gson
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
@ -13,13 +14,14 @@ import java.io.InputStream
import java.io.InputStreamReader
import java.net.URL
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
object RssFeedsParser {
var parseDateFormat: SimpleDateFormat = SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.ENGLISH)
var parseDateFormat2: SimpleDateFormat = SimpleDateFormat("E, dd MM yyyy HH:mm:ss ZZ", Locale.ENGLISH)
var limitDateTime = beforeOneDay()
var limitDateTime = beforeDay(Date(),3)
fun getFeeds(url : String) : List<RssDataInterface> {
var returnList = mutableListOf<RssDataInterface>()
try {
@ -32,7 +34,7 @@ object RssFeedsParser {
fun getReddit(url : String, nsfw : Boolean): List<RssDataInterface> {
var returnList = mutableListOf<RssDataInterface>()
var dateTime = beforeOneDay()
var dateTime = beforeDay(Date(),3)
try {
var mReddit = Gson().fromJson(InputStreamReader(getInputStream(url)!!), Reddit::class.java)
mReddit.data?.children?.forEach {

View File

@ -48,6 +48,7 @@ class WeatherHourlyAdapter(private val dataSet: ArrayList<Hour>): RecyclerView.A
override fun getItemCount(): Int = dataSet.size
fun update(li: Collection<Hour>) {
Blog.LOGE("${this.javaClass.simpleName} update")
li.toList()
this.dataSet.clear()
this.dataSet.addAll(li)

View File

@ -4,6 +4,43 @@ import bums.lunatic.launcher.beforeDay
import bums.lunatic.launcher.utils.JamoUtils
import java.util.Date
class MissD : RssDataInterface {
var link : String? = null
var title : String? = null
var thumb : String? = null
var desc : String? = null
override fun title(): String {
return title ?: ""
}
override fun thumbnailUrl(): String {
return thumb ?: ""
}
override fun originPage(): String {
return link ?: ""
}
override fun description(): String {
return desc ?: ""
}
override fun pubDate(): Long {
return beforeDay(Date())
}
override fun category(): RssDataType {
return RssDataType.GURU
}
override fun getCho(): String? {
return JamoUtils.split(title!!).joinToString("")
}
}
class MostItem : JGuru , RssDataInterface {

View File

@ -17,5 +17,4 @@ class AppInfo : RealmObject {
var lastUseDate : Long = 0L
var category : String? = null
var currentInstalled : Boolean = false
var isInstalled : Boolean = false
}

View File

@ -2,7 +2,7 @@ package bums.lunatic.launcher.model
import bums.lunatic.launcher.utils.JamoUtils
import bums.lunatic.launcher.utils.afterDay
import bums.lunatic.launcher.utils.beforeDayBy
import bums.lunatic.launcher.utils.beforeDay
import io.realm.kotlin.types.RealmObject
import io.realm.kotlin.types.annotations.Ignore
import io.realm.kotlin.types.annotations.PrimaryKey
@ -179,7 +179,7 @@ open class DcInside : RssDataInterface {
dateTiemL = cal.timeInMillis
dateTiemL
} else {
Date().time
0L
}
} else {
return dateTiemL
@ -232,7 +232,7 @@ class RssData : RealmObject, RssDataInterface {
}
else -> title ?: ""
}.apply {
chosung = JamoUtils.split(title).joinToString("")
chosung = JamoUtils.split(this).joinToString("")
}
}
@ -308,15 +308,15 @@ open class Dotax(var pageLink : String,
before = dayString.toInt()
if (dateDesc.contains("")) {
before = 365 * before
dateTime = if (isBefore) beforeDayBy(date, before) else afterDay(date, before)
dateTime = if (isBefore) beforeDay(date, before) else afterDay(date, before)
} else if (dateDesc.contains("")) {
before = 30 * before
dateTime = if (isBefore) beforeDayBy(date, before) else afterDay(date, before)
dateTime = if (isBefore) beforeDay(date, before) else afterDay(date, before)
} else if (dateDesc.contains("")) {
before = 7 * before
dateTime = if (isBefore) beforeDayBy(date, before) else afterDay(date, before)
dateTime = if (isBefore) beforeDay(date, before) else afterDay(date, before)
} else if (dateDesc.contains("")) {
dateTime = if (isBefore) beforeDayBy(date, before) else afterDay(date, before)
dateTime = if (isBefore) beforeDay(date, before) else afterDay(date, before)
} else if (dateDesc.contains("시간")) {
dateTime =
if (isBefore) dateTime.minus(before.times(1000L * 60L * 60L)) else dateTime.plus(

View File

@ -1,40 +0,0 @@
package bums.lunatic.launcher.model
import com.ibm.icu.util.ChineseCalendar
import io.realm.kotlin.types.RealmObject
import java.util.Calendar
import java.util.Date
class UserActionModel: RealmObject {
var actionType: String = ""
// var timestamp: Date = Realm()
var weekOfYear : Int = 0
var weekOfMonth : Int = 0
var dayOfWeek : Int = 0
var dayOfYear : Int = 0
var dayOfMonth : Int = 0
var hourOfDay : Int = 0
var month: Int = 0
var lunMonth : Int = 0
var lunDayOFMonth : Int = 0
var lunDayOfYear : Int = 0
init {
// val cal = Calendar.getInstance()
// cal.time = timestamp
// weekOfYear = cal.get(Calendar.WEEK_OF_YEAR)
// weekOfMonth = cal.get(Calendar.WEEK_OF_MONTH)
// dayOfWeek = cal.get(Calendar.DAY_OF_WEEK)
// hourOfDay = cal.get(Calendar.HOUR_OF_DAY)
// month = cal.get(Calendar.MONTH)
// dayOfYear = cal.get(Calendar.DAY_OF_YEAR)
// dayOfMonth = cal.get(Calendar.DAY_OF_MONTH)
// var cinCal = ChineseCalendar()
// cinCal.time = timestamp
// lunMonth = cinCal.get(ChineseCalendar.MONTH)
// lunDayOFMonth = cinCal.get(ChineseCalendar.DAY_OF_MONTH)
// lunDayOfYear = cinCal.get(ChineseCalendar.DAY_OF_YEAR)
}
}

View File

@ -4,7 +4,7 @@ import bums.lunatic.launcher.model.RssDataInterface
import bums.lunatic.launcher.model.RssDataType
import bums.lunatic.launcher.utils.JamoUtils
import bums.lunatic.launcher.utils.afterDay
import bums.lunatic.launcher.utils.beforeDayBy
import bums.lunatic.launcher.utils.beforeDay
import org.json.JSONObject
import java.util.Date
@ -1621,15 +1621,15 @@ open class VideoRenderer : RssDataInterface {
before = dayString.toInt()
if (dateDesc.contains("")) {
before = 365 * before
dateTime = if (isBefore) beforeDayBy(date, before) else afterDay(date, before)
dateTime = if (isBefore) beforeDay(date, before) else afterDay(date, before)
} else if (dateDesc.contains("")) {
before = 30 * before
dateTime = if (isBefore) beforeDayBy(date, before) else afterDay(date, before)
dateTime = if (isBefore) beforeDay(date, before) else afterDay(date, before)
} else if (dateDesc.contains("")) {
before = 7 * before
dateTime = if (isBefore) beforeDayBy(date, before) else afterDay(date, before)
dateTime = if (isBefore) beforeDay(date, before) else afterDay(date, before)
} else if (dateDesc.contains("")) {
dateTime = if (isBefore) beforeDayBy(date, before) else afterDay(date, before)
dateTime = if (isBefore) beforeDay(date, before) else afterDay(date, before)
} else if (dateDesc.contains("시간")) {
dateTime = if (isBefore)dateTime.minus(before.times(1000L * 60L * 60L)) else dateTime.plus(before.times(1000L * 60L * 60L))
} else if (dateDesc.contains("")) {

View File

@ -47,43 +47,38 @@ class NLService : NotificationListenerService() {
// sbn.notification.extras.keySet().forEach {
// BLog.LOGE("NLService********** keySet >> ${it} ${sbn.notification.extras.get(it)}")
// }
try {
if (sbn.id != 0 && (sbn.packageName.contains(".") || sbn.packageName.contains("android")) && sbn.packageName.length > 0) {
NotificationItem().apply {
notiId = sbn.id
pkgName = sbn.packageName
title = sbn.notification?.extras?.getString("android.title") ?: ""
subtext = sbn.notification?.extras?.getString("android.subText") ?: ""
selfDisplayName = sbn.notification?.extras?.getString("android.selfDisplayName") ?: ""
tikerMsg = sbn.notification?.tickerText?.toString() ?: ""
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}"
if (sbn.id != 0 && (sbn.packageName.contains(".") || sbn.packageName.contains("android")) && sbn.packageName.length > 0) {
NotificationItem().apply {
notiId = sbn.id
pkgName = sbn.packageName
title = sbn.notification?.extras?.getString("android.title") ?: ""
subtext = sbn.notification?.extras?.getString("android.subText") ?: ""
selfDisplayName = sbn.notification?.extras?.getString("android.selfDisplayName") ?: ""
tikerMsg = sbn.notification?.tickerText?.toString() ?: ""
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}")
}.apply {
if (skips.contains(pkgName)) {
}.apply {
if (skips.contains(pkgName)) {
} else {
// WorkersDb.insertNoti(this)
} else {
WorkersDb.insertNoti(this)
// BLog.LOGE("NLService********** onNotificationPosted ${Gson().toJson(this)}")
}
}
}
} catch (e : Exception) {
e.printStackTrace()
}
try {
if (sbn.packageName.contains("youtube")) {
val m = getSystemService<MediaSessionManager>()!!
val component = ComponentName(this, NLService::class.java)
val sessions = m.getActiveSessions(component)
sessions.forEach { session ->
WorkersDb.getRealm().writeBlocking {
// Blog.LOGE("session.playbackState >>> ${session.playbackState}")
Blog.LOGE("session.playbackState >>> ${session.playbackState}")
if (session.playbackState != null) {
if (session.playbackState?.isActive == true && session.playbackState?.state?.equals(
STATE_PLAYING
@ -116,8 +111,6 @@ class NLService : NotificationListenerService() {
}
}
}}catch (e : Exception) {
e.printStackTrace()
}
// val i = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
// i.putExtra("notification_event", "onNotificationPosted :" + sbn.packageName + "\n")
@ -125,19 +118,19 @@ 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)
// var uniq_id = "${sbn.id}_${sbn.packageName}"
// try {
// WorkersDb.getRealm()?.apply {
// this.writeBlocking {
//// delete(query<NotificationItem>().query("pkgName == $0", sbn.packageName).find())
// }
// }
// }catch (e : Exception){e.printStackTrace()}
//// val i = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
//// i.putExtra("notification_event", "onNotificationRemoved :" + sbn.packageName + "\n")
//// sendBroadcast(i)
// 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 {
this.writeBlocking {
// delete(query<NotificationItem>().query("pkgName == $0", sbn.packageName).find())
}
}
}catch (e : Exception){e.printStackTrace()}
// val i = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
// i.putExtra("notification_event", "onNotificationRemoved :" + sbn.packageName + "\n")
// sendBroadcast(i)
}
internal inner class NLServiceReceiver : BroadcastReceiver() {

View File

@ -30,7 +30,6 @@ import bums.lunatic.launcher.databinding.SettingsAppsBinding
import bums.lunatic.launcher.helpers.PrefBoolean
import bums.lunatic.launcher.helpers.PrefHelper
import bums.lunatic.launcher.helpers.PrefLong
import bums.lunatic.launcher.utils.Blog
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
@ -133,19 +132,16 @@ internal class Apps : BottomSheetDialogFragment() {
settingsChanged = true
PrefLong.shortTimePeriod.set(value.toLong())
binding.shortTimeTitle.text = getString(R.string.shortTimeTitle) +" [${value.toInt()}분 마다]"
Blog.LOGE("binding.shortTimeTitle.text >>> ${binding.shortTimeTitle.text}")
})
binding.middleTime.addOnChangeListener(Slider.OnChangeListener { _, value, _ ->
settingsChanged = true
PrefLong.midTimePeriod.set(value.toLong())
binding.middleTimeTitle.text = getString(R.string.middleTimeTitle) +" [${value.toInt()}분 마다]"
Blog.LOGE("binding.shortTimeTitle.text >>> ${binding.middleTimeTitle.text}")
})
binding.longTime.addOnChangeListener(Slider.OnChangeListener { _, value, _ ->
settingsChanged = true
PrefLong.longTimePeriod.set(value.toLong())
binding.longTimeTitle.text = getString(R.string.longTimeTitle) +" [${value.toInt()}]분 마다]"
Blog.LOGE("binding.shortTimeTitle.text >>> ${binding.longTimeTitle.text}")
})
binding.locationDistance.addOnChangeListener(Slider.OnChangeListener { _, value, _ ->

View File

@ -1,99 +0,0 @@
package bums.lunatic.launcher.utils
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.IOException
import java.io.InputStream
import java.io.OutputStream
import java.io.UnsupportedEncodingException
import java.util.zip.DeflaterOutputStream
import java.util.zip.InflaterInputStream
import kotlin.math.floor
object CompressStringUtil {
val charsetName: String = "UTF-8"
/**
* String 객체를 압축하여 String 으로 리턴한다.
* @param string
* @return
*/
@Synchronized
fun compressString(string: String): String? {
return byteToString(compress(string))
}
/**
* 압축된 스트링을 복귀시켜서 String 으로 리턴한다.
* @param compressed
* @return
*/
@Synchronized
fun decompressString(compressed: String?): String {
return decompress(hexToByteArray(compressed))
}
private fun byteToString(bytes: ByteArray?): String? {
val sb = StringBuilder()
try {
for (b in bytes!!) {
sb.append(String.format("%02X", b))
}
} catch (e: Exception) {
e.printStackTrace()
return null
}
return sb.toString()
}
private fun compress(text: String): ByteArray? {
val baos = ByteArrayOutputStream()
try {
val out: OutputStream = DeflaterOutputStream(baos)
out.write(text.toByteArray(charset(charsetName)))
out.close()
} catch (e: UnsupportedEncodingException) {
e.printStackTrace()
return null
} catch (e: IOException) {
e.printStackTrace()
return null
}
return baos.toByteArray()
}
private fun decompress(bytes: ByteArray): String {
val `in`: InputStream = InflaterInputStream(ByteArrayInputStream(bytes))
val baos = ByteArrayOutputStream()
try {
val buffer = ByteArray(8192)
var len: Int
while ((`in`.read(buffer).also { len = it }) > 0) baos.write(buffer, 0, len)
return String(baos.toByteArray(), charset(charsetName))
} catch (e: IOException) {
e.printStackTrace()
throw AssertionError(e)
}
}
/**
* 16 문자열을 byte 배열로 변환한다.
*/
private fun hexToByteArray(hex: String?): ByteArray {
if (hex == null || hex.length % 2 != 0) {
return byteArrayOf()
}
val bytes = ByteArray(hex.length / 2)
var i = 0
while (i < hex.length) {
val value = hex.substring(i, i + 2).toInt(16).toByte()
bytes[floor((i / 2).toDouble()).toInt()] = value
i += 2
}
return bytes
}
}

View File

@ -15,23 +15,7 @@ fun before30Min(date: Date): Long {
return cal.timeInMillis
}
fun beforeOneDay(): Long {
val cal: Calendar = Calendar.getInstance()
cal.setTime(Date())
// cal.add(Calendar.DAY_OF_YEAR, -1)
cal.add(Calendar.HOUR_OF_DAY, -4)
return cal.timeInMillis
}
fun beforeDay(day: Int): Long {
val cal: Calendar = Calendar.getInstance()
cal.setTime(Date())
cal.add(Calendar.DAY_OF_YEAR, Math.abs(day) * -1)
return cal.timeInMillis
}
fun beforeDayBy(date : Date, day: Int): Long {
fun beforeDay(date: Date?, day: Int): Long {
val cal: Calendar = Calendar.getInstance()
cal.setTime(date)
cal.add(Calendar.DAY_OF_YEAR, Math.abs(day) * -1)

View File

@ -414,6 +414,7 @@ class GestureAnalyser @JvmOverloads constructor(
}
}
///https://api.telegram.org/bot7934509464:AAE_xUbICxMdywLGnxo7BkeIqA1nVza4P9w/getUpdates
class SimpleFingerGestures : OnTouchListener {
private var debug = BuildConfig.DEBUG
@ -536,28 +537,28 @@ class SimpleFingerGestures : OnTouchListener {
1,
mGt.gestureDuration,
mGt.gestureDistance
).apply { consumeTouchEvents = this }
)
GestureAnalyser.SWIPE_1_DOWN -> onFingerGestureListener!!.onSwipeDown(
targetView,
1,
mGt.gestureDuration,
mGt.gestureDistance
).apply { consumeTouchEvents = this }
)
GestureAnalyser.SWIPE_1_LEFT -> onFingerGestureListener!!.onSwipeLeft(
targetView,
1,
mGt.gestureDuration,
mGt.gestureDistance
).apply { consumeTouchEvents = this }
)
GestureAnalyser.SWIPE_1_RIGHT -> onFingerGestureListener!!.onSwipeRight(
targetView,
1,
mGt.gestureDuration,
mGt.gestureDistance
).apply { consumeTouchEvents = this }
)
GestureAnalyser.SWIPE_2_UP -> onFingerGestureListener!!.onSwipeUp(
targetView,

View File

@ -2,21 +2,19 @@ package bums.lunatic.launcher.workers
import android.content.Context
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
import android.os.Build
import androidx.work.WorkerParameters
import bums.lunatic.launcher.BuildConfig
import bums.lunatic.launcher.LauncherActivity
import bums.lunatic.launcher.LauncherActivity.Companion.lActivity
import bums.lunatic.launcher.apps.AppDrawer.Companion.appNamesPrefs
import bums.lunatic.launcher.apps.AppDrawer.Companion.appName
import bums.lunatic.launcher.apps.AppDrawer.Companion.getCategory
import bums.lunatic.launcher.apps.normalize
import bums.lunatic.launcher.model.AppInfo
import bums.lunatic.launcher.utils.AlphabetToChosungMap
import bums.lunatic.launcher.utils.JamoUtils
import io.realm.kotlin.ext.query
import java.text.Normalizer
import java.util.regex.Pattern
class AppInfoGetter : BaseGetter {
companion object {
@ -63,32 +61,4 @@ class AppInfoGetter : BaseGetter {
} catch (e : Exception) {e.printStackTrace()}
return Result.success()
}
fun appName(resolver: ResolveInfo): String {
return resolver.loadLabel(lActivity?.packageManager!!).toString().apply {
appNamesPrefs?.edit()?.putString(resolver.activityInfo.packageName, this)?.apply()
}
}
fun getCategory(category : Int) : String {
return when(category) {
ApplicationInfo.CATEGORY_UNDEFINED -> "UNDEFINED"
ApplicationInfo.CATEGORY_GAME -> "GAME"
ApplicationInfo.CATEGORY_AUDIO -> "AUDIO"
ApplicationInfo.CATEGORY_VIDEO -> "VIDEO"
ApplicationInfo.CATEGORY_IMAGE -> "IMAGE"
ApplicationInfo.CATEGORY_SOCIAL -> "SOCIAL"
ApplicationInfo.CATEGORY_NEWS -> "NEWS"
ApplicationInfo.CATEGORY_MAPS -> "MAPS"
ApplicationInfo.CATEGORY_PRODUCTIVITY -> "PRODUCTIVITY"
ApplicationInfo.CATEGORY_ACCESSIBILITY -> "ACCESSIBILITY"
else -> {"UNKNOWN"}
}
}
fun normalize(str: String): String {
val normalizedString =
Normalizer.normalize(str.replace("\\W".toRegex(), ""), Normalizer.Form.NFC)
val pattern = Pattern.compile("\\p{InCombiningDiacriticalMarks}+")
return pattern.matcher(normalizedString).replaceAll("").toLowerCase()
}
}
}

View File

@ -7,14 +7,15 @@ import bums.lunatic.launcher.model.RssDataInterface
import bums.lunatic.launcher.model.RssDataType
import bums.lunatic.launcher.model.getRssData
import bums.lunatic.launcher.model.getT
import bums.lunatic.launcher.utils.beforeOneDay
//import bums.lunatic.launcher.workers.WorkersDb.blockKeyword
import bums.lunatic.launcher.utils.beforeDay
import bums.lunatic.launcher.workers.WorkersDb.blockKeyword
import org.jsoup.Jsoup
import org.jsoup.nodes.Element
import java.util.Date
class ArcaGetter : BaseGetter {
companion object {
val TAG = "ArcaGetter"
val TAG = "DCGetter"
}
constructor(context: Context, workerParams: WorkerParameters) : super(context, workerParams) {
@ -73,7 +74,7 @@ class ArcaGetter : BaseGetter {
var tumbnail = aracaLi.getElementsByTag("img").attr("src")
var link = "https://arca.live".plus(if(aracaLi.getElementsByClass("title hybrid-title").size > 0) aracaLi.getElementsByClass("title hybrid-title").get(0).attr("href") else if(aracaLi.getElementsByTag("a").size > 0) aracaLi.getElementsByTag("a").get(0).attr("href") else "")
if (title.length > 0 && link.length > 20) {
// if(blockKeyword.filter { desc.contains(it) }.size == 0) {
if(blockKeyword.filter { desc.contains(it) }.size == 0) {
Arca().apply {
this.link = link
this.title = title
@ -86,11 +87,11 @@ class ArcaGetter : BaseGetter {
this.dateTiem = dateTime
}.apply {
// BLog.LOGE("parseArcaLi >>>> ${this}")
if (this.pubDate() > beforeOneDay()) {
if (this.pubDate() > beforeDay(Date(), 3)) {
tempArray.add(this)
}
}
// }
}
}
return tempArray
}

View File

@ -1,46 +0,0 @@
package bums.lunatic.launcher.workers
import android.Manifest
import android.app.Service
import android.content.Intent
import android.media.AudioFormat
import android.media.AudioManager
import android.media.AudioRecord
import android.media.MediaRecorder
import android.os.IBinder
import androidx.annotation.RequiresPermission
class AudioRecordService : Service() {
override fun onBind(intent: Intent?): IBinder? {
TODO("Not yet implemented")
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
return super.onStartCommand(intent, flags, startId)
}
var sampleRate: Int = 44100 // 샘플링 레이트 (Hz)
var channelConfig: Int = AudioFormat.CHANNEL_IN_MONO // 채널 구성 (모노)
var audioFormat: Int = AudioFormat.ENCODING_PCM_16BIT // 오디오 포맷 (16비트 PCM)
var bufferSize: Int = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat)
var recorder: AudioRecord? = null
@RequiresPermission(Manifest.permission.RECORD_AUDIO)
fun startAudioRec() {
recorder = AudioRecord(
MediaRecorder.AudioSource.MIC,
sampleRate,
channelConfig,
audioFormat,
bufferSize
)
recorder?.registerAudioRecordingCallback({},object : AudioManager.AudioRecordingCallback() {
})
}
}

View File

@ -6,7 +6,6 @@ import androidx.work.Worker
import androidx.work.WorkerParameters
import bums.lunatic.launcher.model.RssData
import bums.lunatic.launcher.utils.beforeDay
import bums.lunatic.launcher.utils.beforeOneDay
import java.util.Calendar
import java.util.Date
@ -23,9 +22,9 @@ open abstract class BaseGetter : Worker {
}
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 limitDateTime = beforeOneDay()
val commicsDateTime = beforeDay(1)
val now = Date()
val limitDateTime = beforeDay(now,3)
val commicsDateTime = beforeDay(now,1)
val temp = arrayListOf<RssData>()
constructor(context: Context, workerParams: WorkerParameters) : super(context, workerParams) {

View File

@ -33,9 +33,6 @@ class ClienGetter : BaseGetter {
Clien().let { c ->
c.title = title
c.link = "https://www.clien.net".plus(link)
if (c.link?.contains("?") == true) {
try { c.link = c.link?.split("?")?.first() }catch (e : Exception) {}
}
c.desc = desc
c.dateTiem = timeStamp
if (c.pubDate() > limitDateTime) {

View File

@ -2,17 +2,13 @@ package bums.lunatic.launcher.workers
import android.annotation.SuppressLint
import android.content.Context
import androidx.core.net.toUri
import androidx.work.WorkerParameters
import bums.lunatic.launcher.helpers.PrefHelper
import bums.lunatic.launcher.model.DcInside
import bums.lunatic.launcher.model.RssData
import bums.lunatic.launcher.model.RssDataInterface
import bums.lunatic.launcher.model.RssDataType
import bums.lunatic.launcher.model.getRssData
import bums.lunatic.launcher.utils.Blog
import org.jsoup.Jsoup
import java.text.SimpleDateFormat
class DCGetter : BaseGetter {
companion object {
@ -24,9 +20,6 @@ class DCGetter : BaseGetter {
fun parseDcLi(dc_li : org.jsoup.nodes.Element) : ArrayList<RssDataInterface>{
var temp = arrayListOf<RssDataInterface>()
if (dc_li.html().contains("<ul class=>") && dc_li.html().contains("con_list img")) {
}
else if (dc_li.html().contains("<ul class=>") && dc_li.html().contains("con_list img")) {
dc_li.child(0).getElementsByTag("li").forEach {
parseDcLi(it)
}
@ -71,93 +64,31 @@ class DCGetter : BaseGetter {
}
return temp
}
val df = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
@SuppressLint("RestrictedApi")
override fun realWork(): Result {
// Blog.LOGE("${TAG} RssDataType.DCINSIDE.isOn >>>> ${PrefHelper.getBoolean(RssDataType.DCINSIDE.name,false)}")
RssDataType.DCINSIDE.isOn {
temp.clear()
// https://m.dcinside.com/board/singlebungle1472
var urls = arrayListOf(
"https://m.dcinside.com",
"https://m.dcinside.com/board/singlebungle1472",
"https://m.dcinside.com/board/programming",
"https://m.dcinside.com/board/cartoon",
"https://m.dcinside.com/board/reading",
"https://m.dcinside.com/board/hit",
"https://m.dcinside.com/board/dcbest"
)
try {
urls.forEach { testUrl2 ->
try {
// Blog.LOGE("${TAG} ${testUrl2} ")
Jsoup.connect(testUrl2)
.userAgent(USAGT)
.get().let { dc ->
// Blog.LOGE("${TAG} ${testUrl2} >> ${this}")
var tbody = dc.getElementsByTag("tbody")
if((tbody?.size ?: 0) == 1) {
var from = dc.getElementsByClass("page_head clear")?.first()?.getElementsByTag("a")?.first()?.text()
// Blog.LOGE("${TAG} ${from} ")
dc.getElementsByTag("tbody").first().children().forEach {
var title = it.getElementsByClass("gall_tit ub-word")?.first()?.text()
var date = it.getElementsByClass("gall_date")?.first()?.attr("title")
var link = it.getElementsByTag("a")?.first()?.attr("href")
if (link?.length ?: 0 > 10 && title?.length ?: 0 > 2 && date?.length ?: 0 > 1) {
// Blog.LOGE("${TAG} ${title} ")
// Blog.LOGE("${TAG} ${date} ${df.parse(date)}")
// Blog.LOGE("${TAG} ${link} ")
DcInside().apply {
"https://gall.dcinside.com".plus(
link?.replace(
"&amp;",
"&"
)
)?.toUri()?.apply {
link = "https://m.dcinside.com/board/".plus(getQueryParameter("id")).plus("/").plus(getQueryParameter("no"))
}
// this.link = "https://gall.dcinside.com".plus(
// link?.replace(
// "&amp;",
// "&"
// )
// )
this.link = link
// Blog.LOGE("${TAG} ${link} ")
// Blog.LOGE("${TAG} ${from} ")
this.title = title
this.desc = from
this.dateTiemL = df.parse(date).time
}.apply {
if (this.pubDate() > limitDateTime) {
temp.add(this.getRssData())
}
}
}
}
} else {
dc.getElementsByTag("li").forEach { dc_li ->
if (dc_li.html().contains("main_log") == true) {
parseDcLi(dc_li).apply {
this.forEach {
if (it.pubDate() > commicsDateTime) {
// Blog.LOGE("${TAG} ${it.title()}")
temp.add(it.getRssData())
}
}
}
val testUrl2 = "https://www.dcinside.com/"
Jsoup.connect(testUrl2)
.userAgent(USAGT)
.get().let { dc ->
// BLog.LOGE("test ${testUrl2} >> ${this}")
dc.getElementsByTag("li").forEach { dc_li ->
if (dc_li.html().contains("main_log") == true) {
parseDcLi(dc_li).apply {
this.forEach {
if (it.pubDate() > commicsDateTime) {
temp.add(it.getRssData())
}
}
}
}
}catch (e :Exception){e.printStackTrace()}
}
}
}
} catch (e: Exception) {
e.printStackTrace()
}

View File

@ -6,7 +6,6 @@ import androidx.work.WorkerParameters
import bums.lunatic.launcher.model.FmKorea
import bums.lunatic.launcher.model.RssDataType
import bums.lunatic.launcher.model.getRssData
import bums.lunatic.launcher.utils.Blog
import org.jsoup.Jsoup
import java.util.Date
@ -18,78 +17,47 @@ class FmKoreaGetter : BaseGetter {
}
fun extractDocumentSrl(url: String): String? {
val uri = java.net.URI(url)
val query = uri.query ?: return null // 쿼리 문자열이 없으면 null 반환
val params = query.split("&")
for (param in params) {
val parts = param.split("=")
if (parts.size == 2 && parts[0] == "document_srl") {
return "${uri.scheme}://${uri.host}${uri.path}?document_srl=${parts[1]}"
}
}
return null // document_srl 파라미터를 찾지 못하면 null 반환
}
@SuppressLint("RestrictedApi")
override fun realWork(): Result {
RssDataType.FMKORAE.isOn {
val now = Date()
try {
val fmkoreaUrls = arrayListOf("https://m.fmkorea.com","https://m.fmkorea.com/best","https://m.fmkorea.com/best2")
val fmkoreaUrls = arrayListOf("https://www.fmkorea.com/best","https://www.fmkorea.com/best2")
fmkoreaUrls.forEach {
try {
Jsoup.connect(it).userAgent(USAGT).timeout(5000).ignoreHttpErrors(true).get().let { fmkorea ->
if (it.contains("guru")) {
// Blog.LOGE("GURU -> ${fmkorea}")
} else {
fmkorea.getElementsByTag("li").forEach { fmkorea_li ->
if (fmkorea_li.getElementsByClass("title")
.text().length > 0 && fmkorea_li.getElementsByTag("a").size > 0 && fmkorea_li.getElementsByTag(
"a"
).get(0).attr("href").length > 0
Jsoup.connect(it).userAgent(USAGT).get().let { fmkorea ->
// BLog.LOGE("fmkorea >>> ${fmkorea.title()}")
fmkorea.getElementsByTag("li").forEach { fmkorea_li ->
if (fmkorea_li.getElementsByClass("title")
.text().length > 0 && fmkorea_li.getElementsByTag("a").size > 0 && fmkorea_li.getElementsByTag(
"a"
).get(0).attr("href").length > 0
) {
// BLog.LOGE("fmkorea_li >>> ${fmkorea_li}")
val title = fmkorea_li.getElementsByClass("title").text()
val tumb = "https://".plus(
fmkorea_li.getElementsByClass("thumb").attr("data-original")
)
val pageUrl = "https://www.fmkorea.com".plus(
fmkorea_li.getElementsByTag("a").get(0).attr("href")
)
val desc = fmkorea_li.getElementsByClass("category").text()
val date = fmkorea_li.getElementsByClass("regdate").text()
FmKorea(pageUrl, desc, date, title, tumb).apply {
if (desc?.contains("유머") == true || desc?.contains("음악") == true || desc?.contains(
"영화"
) == true ||
desc?.contains("TV") == true || desc?.contains("미스터리") == true || desc?.contains(
"역사"
) == true
) {
val title = fmkorea_li.getElementsByClass("title").text()
val tumb = "https://".plus(
fmkorea_li.getElementsByClass("thumb")
.attr("data-original")
)
var pageUrl = "https://www.fmkorea.com".plus(
fmkorea_li.getElementsByTag("a").get(0).attr("href")
)
try {
val originalUrl = pageUrl
val extractedUrl = extractDocumentSrl(originalUrl)
if (extractedUrl != null) {
pageUrl = extractedUrl
} else {
}
} catch (e: Exception) {}
val desc = fmkorea_li.getElementsByClass("category").text()
val date = fmkorea_li.getElementsByClass("regdate").text()
FmKorea(pageUrl, desc, date, title, tumb).apply {
if (desc?.contains("유머") == true || desc?.contains("음악") == true || desc?.contains(
"영화"
) == true ||
desc?.contains("TV") == true || desc?.contains("미스터리") == true || desc?.contains(
"역사"
) == true
) {
if (this.pubDate() > commicsDateTime && tumb.length > 10) {
temp.add(this.getRssData())
}
}
if (this.pubDate() > commicsDateTime && tumb.length > 10) {
temp.add(this.getRssData())
}
}
}
}
}
}catch (e:Exception){
e.printStackTrace()
}
}
} catch (e: Exception) {

View File

@ -152,7 +152,6 @@ class LocationUpdateService : Service(), LocationListener {
try{
locationManager = applicationContext
.getSystemService(LOCATION_SERVICE) as LocationManager
checkGPS = locationManager!!
.isProviderEnabled(LocationManager.GPS_PROVIDER)
checkNetwork = locationManager!!

View File

@ -24,10 +24,10 @@ class NewsFeedsGetter : BaseGetter {
feddsUrls.addAll(RssList.getFeedUrls())
for (url in feddsUrls) {
try {
for (it in RssFeedsParser.getFeeds(url)) { if (it.pubDate() >= limitDateTime) { try {temp.add(it.getRssData())}catch (e : Exception) {e.printStackTrace()} } }
}catch (e : Exception) {
e.printStackTrace()
for (it in RssFeedsParser.getFeeds(url)) {
if (it.pubDate() >= limitDateTime) {
temp.add(it.getRssData())
}
}
}

View File

@ -45,7 +45,7 @@ class OpenWeatherGetter(context: Context, workerParams: WorkerParameters) : Base
}
fun getWeather(latitude: Double, longitude: Double) {
Blog.LOGE("into getWeather ${PrefString.weatherApiKey.get()}")
Blog.LOGE("into getWeather")
///saved weatherForcast
Retrofit.Builder()
.baseUrl(URI_WEATHERAPI)

View File

@ -60,7 +60,7 @@ class RecentCallGetter : BaseGetter {
@SuppressLint("RestrictedApi")
override fun realWork(): Result {
var dateParam = beforeDay(dayRange).toString()
var dateParam = beforeDay(Date(),dayRange).toString()
var managedCursor = lActivity?.contentResolver?.query(
CallLog.Calls.CONTENT_URI, arrayOf(
CallLog.Calls.NUMBER,

View File

@ -22,6 +22,7 @@ import java.io.BufferedReader
import java.io.IOException
import java.io.InputStream
import java.io.InputStreamReader
import java.util.Date
class RecentSmsGetter : BaseGetter {
companion object {
@ -37,7 +38,7 @@ class RecentSmsGetter : BaseGetter {
@SuppressLint("RestrictedApi")
override fun realWork(): Result {
var dateParam = beforeDay(dayRange).toString()
var dateParam = beforeDay(Date(),dayRange).toString()
val managedCursor = lActivity?.contentResolver?.query(
Telephony.Sms.CONTENT_URI, arrayOf(
Telephony.Sms.THREAD_ID,
@ -339,7 +340,7 @@ internal class MmsQueryHelper(
fun convertData(cursor: Cursor?) {
cursor ?: return
val dateTime = beforeDay(dayRange)
val dateTime = beforeDay(Date(), dayRange)
cursor.use {
if (cursor.moveToFirst()) {
do {

View File

@ -7,7 +7,6 @@ import androidx.work.WorkerParameters
import bums.lunatic.launcher.model.RssDataType
import bums.lunatic.launcher.model.RuliWeb
import bums.lunatic.launcher.model.getRssData
import bums.lunatic.launcher.utils.Blog
import org.jsoup.Jsoup
class RuliWebGetter : BaseGetter {
@ -27,9 +26,7 @@ class RuliWebGetter : BaseGetter {
var dateTimeTxt = ""
if(ruli_tr.getElementsByTag("a").size > tagIdx) {
pageLink = aTags.get(tagIdx).attr("href").replace("&amp;","&")
if(aTags.get(tagIdx).attr("style").split("(").size > 1) {
thumbnailUrl = aTags.get(tagIdx).attr("style").split("(")[1].replace(");", "")
}
thumbnailUrl = aTags.get(tagIdx).attr("style").split("(")[1].replace(");","")
}
tagIdx = 1
if(ruli_tr.getElementsByTag("a").size > tagIdx) { title = aTags.get(tagIdx).text() }
@ -40,11 +37,11 @@ class RuliWebGetter : BaseGetter {
var timeClass = ruli_tr.getElementsByClass("time")
if(timeClass.size > 0) { dateTimeTxt = timeClass.get(0).text() }
// Blog.LOGE(TAG.plus("pageLink >>>> $pageLink "))
// Blog.LOGE(TAG.plus("thumbnailUrl >>>> $thumbnailUrl "))
// Blog.LOGE(TAG.plus("title >>>> $title "))
// Blog.LOGE(TAG.plus("desc >>>> $desc "))
// Blog.LOGE(TAG.plus("dateTimeTxt >>>> $dateTimeTxt "))
// BLog.LOGE("pageLink >>>> $pageLink ")
// BLog.LOGE("thumbnailUrl >>>> $thumbnailUrl ")
// BLog.LOGE("title >>>> $title ")
// BLog.LOGE("desc >>>> $desc ")
// BLog.LOGE("dateTimeTxt >>>> $dateTimeTxt ")
if (title.length > 0 && pageLink.length > 0) {
RuliWeb().let { ru ->
ru.title = title
@ -65,10 +62,10 @@ class RuliWebGetter : BaseGetter {
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")
testUrl2.forEach { url ->
Jsoup.connect(url).timeout(5000).ignoreHttpErrors(true)
Jsoup.connect(url)
.userAgent(USAGT)
.get().let { ruli ->
// Blog.LOGE(TAG.plus("test ${testUrl2} >> ${ruli.title()}"))
// BLog.LOGE("test ${testUrl2} >> ${ruli.title()}")
ruli.getElementsByTag("tr").forEach { ruli_tr ->
parseRuli(ruli_tr)
}

View File

@ -33,11 +33,6 @@ class TheQooGetter : BaseGetter {
TheQoo().let { tq ->
tq.title = title
tq.link = "https://theqoo.net".plus(pageLink)
if (tq.link?.contains("?") == true) {
try {
tq.link = tq.link?.split("?")?.first()
}catch (e:Exception){}
}
tq.dateTiem = dateTime
tq.desc = desc
if (tq.pubDate() > limitDateTime) {

View File

@ -24,22 +24,18 @@ import bums.lunatic.launcher.model.TelegramChat
import bums.lunatic.launcher.model.TelegramData
import bums.lunatic.launcher.model.TelegramFrom
import bums.lunatic.launcher.model.TelegramMessage
import bums.lunatic.launcher.model.UserActionModel
import bums.lunatic.launcher.model.WeatherForcast
import bums.lunatic.launcher.utils.Blog
import bums.lunatic.launcher.utils.JamoUtils
import bums.lunatic.launcher.utils.beforeDay
import bums.lunatic.launcher.utils.beforeOneDay
import io.realm.kotlin.Realm
import io.realm.kotlin.RealmConfiguration
import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.ext.query
import io.realm.kotlin.migration.AutomaticSchemaMigration
import io.realm.kotlin.query.RealmQuery
import io.realm.kotlin.query.Sort
import io.realm.kotlin.types.BaseRealmObject
import io.realm.kotlin.types.TypedRealmObject
import java.util.Calendar
import java.util.Date
import java.util.Locale
import java.util.regex.Pattern
@ -53,23 +49,13 @@ class CustMigration : AutomaticSchemaMigration {
}
object WorkersDb {
fun recommendApps() {
val cal = Calendar.getInstance()
cal.time = Date()
val weekOfYear = cal.get(Calendar.WEEK_OF_YEAR)
val weekOfMonth = cal.get(Calendar.WEEK_OF_MONTH)
val dayOfWeek = cal.get(Calendar.DAY_OF_WEEK)
getRealm().apply {
// this.query<UserActionModel>().query("weekOfYear == $0 OR weekOfMonth == $1 OR dayOfWeek == $2").limit()
}
}
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,
LocationLog::class
)
//,UserActionModel::class
val schemaVersion : Long = BuildConfig.BuildDateTime
@ -92,9 +78,7 @@ object WorkersDb {
getRealm().apply {
this.writeBlocking {
try {
if (query<RssData>("originPage == $0", rssData.originPage).find().isEmpty()) {
this.copyToRealm(rssData, UpdatePolicy.ERROR)
}
this.copyToRealm(rssData, UpdatePolicy.ERROR)
} catch (e : Exception) {
}
@ -102,25 +86,18 @@ object WorkersDb {
}
}
// val blockKeyword = arrayListOf<String>("붕괴 스타레일","붕괴 스타일","트릭컬 RE:VIVE","원신","메이플스토리","")
val blockKeyword = arrayListOf<String>("붕괴 스타레일","붕괴 스타일","트릭컬 RE:VIVE","원신","메이플스토리","")
fun insertBulkData(rssDatas: Collection<RssData>) {
rssDatas.forEach {
try {
getRealm().writeBlocking {
try {
rssDatas.forEach { t ->
if (query<RssData>("originPage == $0", t.originPage).find().isEmpty()) {
// val catfillters = arrayListOf<RssDataType>(RssDataType.THEQOO,RssDataType.RULIWEB,RssDataType.ARCA,RssDataType.CLIEN,RssDataType.FMKORAE,RssDataType.DOTAX,RssDataType.DCINSIDE)
// if(catfillters.contains(it.category()) && query<RssData>("chosung == $0",it.chosung).find().size == 0) {
this.copyToRealm(t, UpdatePolicy.ERROR)
// } else if(!catfillters.contains(it.category())){
// this.copyToRealm(it, UpdatePolicy.ERROR)
// } else {
//
// }
}
val catfillters = arrayListOf<RssDataType>(RssDataType.THEQOO,RssDataType.RULIWEB,RssDataType.ARCA,RssDataType.CLIEN,RssDataType.FMKORAE,RssDataType.DOTAX,RssDataType.DCINSIDE)
if(catfillters.contains(it.category()) && query<RssData>("chosung == $0",it.chosung).find().size == 0) {
this.copyToRealm(it, UpdatePolicy.ERROR)
} else {
this.copyToRealm(it, UpdatePolicy.ERROR)
}
} catch (e : Exception) {
}
@ -218,18 +195,13 @@ object WorkersDb {
}
}
fun getVotedRss() = getRealm().query<RssData>().query("vote == $0", true).distinct("originPage", "title")
fun getVotedRss() = getRealm().query<RssData>().query("vote == $0", true).distinct("originPage").distinct("title")
fun getDeleteQuery( ) : RealmQuery<RssData>{
var rQ = getRealm().query<RssData>()
rQ.query("pubDate > $0", beforeDay(14)).query("vote == $0", true)
return rQ
}
fun getRssQuery(keyword: String?,
category: Collection<String>? = arrayListOf(),
noLimit: Boolean = false) : RealmQuery<RssData>{
var rQ = getRealm().query<RssData>().sort("pubDate", Sort.DESCENDING)
if (!noLimit) rQ.query("pubDate > $0", beforeOneDay())
var rQ = getRealm().query<RssData>()
if (!noLimit) rQ.query("pubDate > $0", beforeDay(Date(), 3))
keyword?.isNotEmpty()?.letTrue {
if (JamoUtils.CHOSUNG.contains(keyword.split("")[0])) {
rQ = rQ.query("title CONTAINS $0 OR chosung CONTAINS $1 ", keyword, keyword)
@ -258,7 +230,7 @@ object WorkersDb {
if (keyword?.length ?: 0 == 0 && category?.size ?: 0 == 0) {
rQ = rQ.query("read < $0", 3).query("vote != $0", true)
}
return rQ.distinct("originPage", "title")
return rQ.distinct("originPage").distinct("title")
}
}

View File

@ -7,6 +7,12 @@
android:id="@+id/mainFragmentsContainer"
android:fitsSystemWindows="true">
<WebView
android:layout_margin="@dimen/default_layout_margin"
android:id="@+id/searcher_01"
android:layout_width="match_parent"
android:alpha="0"
android:layout_height="match_parent"/>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/home"
@ -14,6 +20,19 @@
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!-- <FrameLayout-->
<!-- android:id="@+id/feeds"-->
<!-- android:visibility="gone"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent" >-->
<!-- </FrameLayout>-->
<FrameLayout
android:visibility="gone"
android:id="@+id/app_drawer"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
</FrameLayout>

View File

@ -7,23 +7,306 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
<TextView
android:id="@+id/batteryProgress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/default_layout_margin"
android:indeterminate="false"
android:visibility="gone"
style="@style/normal"
android:text="빠떼뤼 ~> 0%"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<bums.lunatic.launcher.view.DateTimeView
android:layout_margin="@dimen/default_layout_margin"
android:id="@+id/infoList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
android:padding="@dimen/default_padding"
android:scrollbars="none"
android:visibility="visible"
android:layout_height="60dp"
android:background="@drawable/base_bg"
android:text="this is init sentence"
android:id="@+id/time"
android:visibility="gone"
android:gravity="center"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
app:layout_constraintTop_toBottomOf="@+id/batteryProgress"
tools:ignore="MissingConstraints" />
<ImageView
android:id="@+id/next_play"
android:src="@drawable/play_song"
app:layout_constraintRight_toRightOf="@id/time"
app:layout_constraintTop_toTopOf="@id/time"
app:layout_constraintBottom_toBottomOf="@id/time"
android:layout_width="wrap_content"
android:adjustViewBounds="true"
android:layout_margin="@dimen/default_layout_margin"
android:layout_height="40dp"/>
<bums.lunatic.launcher.view.CircleImageView
app:layout_constraintLeft_toLeftOf="@id/time"
app:layout_constraintTop_toTopOf="@id/time"
app:layout_constraintBottom_toBottomOf="@id/time"
android:layout_margin="@dimen/default_layout_margin"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:background="@null"
android:layout_width="wrap_content"
app:civ_border_width="1dp"
app:civ_border_color="#000000"
app:civ_label="택시"
android:visibility="gone"
android:layout_height="0dp"
android:src="@drawable/kakaot"
android:id="@+id/alchol_katalkT"/>
<!-- <com.google.android.material.textview.MaterialTextView-->
<!-- android:id="@+id/weather"-->
<!-- app:layout_goneMarginBottom="0dp"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:gravity="center"-->
<!-- android:maxLines="1"-->
<!-- android:textIsSelectable="false"-->
<!-- app:layout_constraintLeft_toLeftOf="parent"-->
<!-- app:layout_constraintRight_toRightOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@+id/time"-->
<!-- />-->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/current_music"
app:layout_constraintTop_toBottomOf="@id/time"
app:layout_constraintLeft_toLeftOf="parent"
android:background="@drawable/base_bg"
android:layout_margin="@dimen/default_layout_margin"
app:layout_goneMarginTop="0dp"
app:layout_goneMarginBottom="0dp"
android:padding="@dimen/default_padding"
android:visibility="gone"
app:layout_constraintRight_toRightOf="parent"
android:layout_width="match_parent"
android:layout_height="60dp">
<bums.lunatic.launcher.view.CircleImageView
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:id="@+id/album_art"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:layout_width="wrap_content"
android:layout_height="50dp"/>
<TextView
android:layout_margin="@dimen/default_layout_margin"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@id/album_art"
app:layout_constraintRight_toLeftOf="@id/next_btn"
android:gravity="left"
style="@style/small"
android:lines="1"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
android:layout_width="0dp"
android:id="@+id/artist"
android:layout_height="wrap_content"/>
<TextView
android:layout_margin="@dimen/default_layout_margin"
app:layout_constraintTop_toBottomOf="@id/artist"
android:id="@+id/title"
android:gravity="left"
style="@style/small"
android:lines="1"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
app:layout_constraintBottom_toBottomOf="@id/album_art"
app:layout_constraintLeft_toRightOf="@id/album_art"
app:layout_constraintRight_toLeftOf="@id/next_btn"
android:layout_width="0dp"
android:layout_height="wrap_content"/>
<ImageView
android:layout_margin="@dimen/default_layout_margin"
android:id="@+id/next_btn"
android:src="@drawable/next_song"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:layout_width="wrap_content"
android:layout_height="40dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<include
android:layout_margin="@dimen/default_layout_margin"
android:id="@+id/weathers"
layout="@layout/weather_book"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/current_music"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:layout_margin="@dimen/default_layout_margin"
android:id="@+id/summaryChoose"
android:layout_width="0dp"
android:gravity="center"
android:background="@drawable/base_bg"
app:layout_constraintLeft_toLeftOf="parent"
android:orientation="horizontal"
app:layout_constraintRight_toRightOf="parent"
android:layout_height="40dp"
app:layout_constraintTop_toBottomOf="@+id/weathers"
>
<TextView
style="@style/normal"
android:id="@+id/missedCalls"
android:gravity="center"
android:textColor="@color/tabs"
android:text="통화 목록"
android:background="@null"
android:checked="true"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
style="@style/normal"
android:id="@+id/otherCheck"
android:gravity="center"
android:background="@null"
android:text="글타래"
android:textColor="@color/tabs"
android:checked="false"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
style="@style/normal"
android:id="@+id/recentSms"
android:gravity="center"
android:background="@null"
android:text="문자 내역"
android:textColor="@color/tabs"
android:checked="false"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
style="@style/normal"
android:id="@+id/notice"
android:gravity="center"
android:background="@null"
android:text="알림"
android:textColor="@color/tabs"
android:checked="false"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@+id/summaryChoose"
app:layout_constraintBottom_toTopOf="@id/functionLayer"
>
<androidx.recyclerview.widget.RecyclerView
android:layout_margin="@dimen/default_layout_margin"
android:id="@+id/mainList"
android:layout_width="0dp"
android:layout_height="0dp"
android:overScrollMode="never"
android:padding="@dimen/default_padding"
android:visibility="gone"
android:background="@drawable/base_bg"
android:scrollbars="none"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="2"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
/>
<androidx.recyclerview.widget.RecyclerView
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="2"
android:layout_margin="@dimen/default_layout_margin"
android:id="@+id/smsList"
android:layout_width="0dp"
android:layout_height="0dp"
android:overScrollMode="never"
android:padding="@dimen/default_padding"
android:scrollbars="none"
android:visibility="gone"
android:background="@drawable/base_bg"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
/>
<androidx.recyclerview.widget.RecyclerView
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:layout_margin="@dimen/default_layout_margin"
android:id="@+id/infoList"
android:layout_width="0dp"
android:layout_height="0dp"
android:overScrollMode="never"
android:padding="@dimen/default_padding"
android:scrollbars="none"
android:visibility="gone"
android:background="@drawable/base_bg"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
/>
<androidx.recyclerview.widget.RecyclerView
android:layout_margin="@dimen/default_layout_margin"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:id="@+id/notiList"
android:layout_width="0dp"
android:layout_height="0dp"
android:overScrollMode="never"
android:padding="@dimen/default_padding"
android:scrollbars="none"
android:visibility="gone"
android:background="@drawable/base_bg"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
/>
</RelativeLayout>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_margin="@dimen/default_layout_margin"
android:id="@+id/functionLayer"
android:layout_width="@dimen/zero"
android:layout_height="40dp"
android:layout_marginTop="@dimen/default_layout_margin"
android:layout_marginBottom="@dimen/default_layout_margin"
android:background="@drawable/base_bg"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent" >
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,340 +0,0 @@
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:background="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/batteryProgress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/default_layout_margin"
android:indeterminate="false"
android:visibility="gone"
style="@style/normal"
android:text="빠떼뤼 ~> 0%"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<bums.lunatic.launcher.view.DateTimeView
android:layout_margin="@dimen/default_layout_margin"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="@drawable/base_bg"
android:text="this is init sentence"
android:id="@+id/time"
android:visibility="gone"
android:gravity="center"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/batteryProgress"
tools:ignore="MissingConstraints" />
<ImageView
android:id="@+id/next_play"
android:src="@drawable/play_song"
app:layout_constraintRight_toRightOf="@id/time"
app:layout_constraintTop_toTopOf="@id/time"
app:layout_constraintBottom_toBottomOf="@id/time"
android:layout_width="wrap_content"
android:adjustViewBounds="true"
android:layout_margin="@dimen/default_layout_margin"
android:layout_height="40dp"/>
<bums.lunatic.launcher.view.CircleImageView
app:layout_constraintLeft_toLeftOf="@id/time"
app:layout_constraintTop_toTopOf="@id/time"
app:layout_constraintBottom_toBottomOf="@id/time"
android:layout_margin="@dimen/default_layout_margin"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:background="@null"
android:layout_width="wrap_content"
app:civ_border_width="1dp"
app:civ_border_color="#000000"
app:civ_label="택시"
android:visibility="gone"
android:layout_height="0dp"
android:src="@drawable/kakaot"
android:id="@+id/alchol_katalkT"/>
<!-- <com.google.android.material.textview.MaterialTextView-->
<!-- android:id="@+id/weather"-->
<!-- app:layout_goneMarginBottom="0dp"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:gravity="center"-->
<!-- android:maxLines="1"-->
<!-- android:textIsSelectable="false"-->
<!-- app:layout_constraintLeft_toLeftOf="parent"-->
<!-- app:layout_constraintRight_toRightOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@+id/time"-->
<!-- />-->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/current_music"
app:layout_constraintTop_toBottomOf="@id/time"
app:layout_constraintLeft_toLeftOf="parent"
android:background="@drawable/base_bg"
android:layout_margin="@dimen/default_layout_margin"
app:layout_goneMarginTop="0dp"
app:layout_goneMarginBottom="0dp"
android:padding="@dimen/default_padding"
android:visibility="gone"
app:layout_constraintRight_toRightOf="parent"
android:layout_width="match_parent"
android:layout_height="60dp">
<bums.lunatic.launcher.view.CircleImageView
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:id="@+id/album_art"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:layout_width="wrap_content"
android:layout_height="50dp"/>
<TextView
android:layout_margin="@dimen/default_layout_margin"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@id/album_art"
app:layout_constraintRight_toLeftOf="@id/next_btn"
android:gravity="left"
style="@style/small"
android:lines="1"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
android:layout_width="0dp"
android:id="@+id/artist"
android:layout_height="wrap_content"/>
<TextView
android:layout_margin="@dimen/default_layout_margin"
app:layout_constraintTop_toBottomOf="@id/artist"
android:id="@+id/title"
android:gravity="left"
style="@style/small"
android:lines="1"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
app:layout_constraintBottom_toBottomOf="@id/album_art"
app:layout_constraintLeft_toRightOf="@id/album_art"
app:layout_constraintRight_toLeftOf="@id/next_btn"
android:layout_width="0dp"
android:layout_height="wrap_content"/>
<ImageView
android:layout_margin="@dimen/default_layout_margin"
android:id="@+id/next_btn"
android:src="@drawable/next_song"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:layout_width="wrap_content"
android:layout_height="40dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<include
android:layout_margin="@dimen/default_layout_margin"
android:id="@+id/weathers"
layout="@layout/weather_book"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/current_music"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:layout_margin="@dimen/default_layout_margin"
android:id="@+id/summaryChoose"
android:layout_width="0dp"
android:gravity="center"
android:background="@drawable/base_bg"
app:layout_constraintLeft_toLeftOf="parent"
android:orientation="horizontal"
app:layout_constraintRight_toRightOf="parent"
android:layout_height="40dp"
app:layout_constraintTop_toBottomOf="@+id/weathers"
>
<TextView
style="@style/normal"
android:id="@+id/missedCalls"
android:gravity="center"
android:textColor="@color/tabs"
android:text="통화 목록"
android:background="@null"
android:checked="true"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
style="@style/normal"
android:id="@+id/otherCheck"
android:gravity="center"
android:background="@null"
android:text="글타래"
android:textColor="@color/tabs"
android:checked="false"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
style="@style/normal"
android:id="@+id/favApps"
android:gravity="center"
android:background="@null"
android:text="앱스"
android:textColor="@color/tabs"
android:checked="false"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
style="@style/normal"
android:id="@+id/recentSms"
android:gravity="center"
android:background="@null"
android:text="문자 내역"
android:textColor="@color/tabs"
android:checked="false"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
style="@style/normal"
android:id="@+id/notice"
android:gravity="center"
android:background="@null"
android:text="알림"
android:textColor="@color/tabs"
android:checked="false"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@+id/summaryChoose"
app:layout_constraintBottom_toTopOf="@id/functionLayer"
>
<androidx.recyclerview.widget.RecyclerView
android:layout_margin="@dimen/default_layout_margin"
android:id="@+id/mainList"
android:layout_width="0dp"
android:layout_height="0dp"
android:overScrollMode="never"
android:padding="@dimen/default_padding"
android:visibility="gone"
android:background="@drawable/base_bg"
android:scrollbars="none"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="2"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
/>
<androidx.recyclerview.widget.RecyclerView
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="2"
android:layout_margin="@dimen/default_layout_margin"
android:id="@+id/smsList"
android:layout_width="0dp"
android:layout_height="0dp"
android:overScrollMode="never"
android:padding="@dimen/default_padding"
android:scrollbars="none"
android:visibility="gone"
android:background="@drawable/base_bg"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
/>
<androidx.recyclerview.widget.RecyclerView
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:layout_margin="@dimen/default_layout_margin"
android:id="@+id/infoList"
android:layout_width="0dp"
android:layout_height="0dp"
android:overScrollMode="never"
android:padding="@dimen/default_padding"
android:scrollbars="none"
android:visibility="gone"
android:background="@drawable/base_bg"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
/>
<androidx.recyclerview.widget.RecyclerView
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
android:layout_margin="@dimen/default_layout_margin"
android:id="@+id/appsList"
android:layout_width="0dp"
android:layout_height="0dp"
android:overScrollMode="never"
android:padding="@dimen/default_padding"
app:spanCount="3"
android:scrollbars="none"
android:visibility="gone"
android:background="@drawable/base_bg"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
/>
<androidx.recyclerview.widget.RecyclerView
android:layout_margin="@dimen/default_layout_margin"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:id="@+id/notiList"
android:layout_width="0dp"
android:layout_height="0dp"
android:overScrollMode="never"
android:padding="@dimen/default_padding"
android:scrollbars="none"
android:visibility="gone"
android:background="@drawable/base_bg"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
/>
</RelativeLayout>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_margin="@dimen/default_layout_margin"
android:id="@+id/functionLayer"
android:layout_width="@dimen/zero"
android:layout_height="40dp"
android:layout_marginTop="@dimen/default_layout_margin"
android:layout_marginBottom="@dimen/default_layout_margin"
android:background="@drawable/base_bg"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent" >
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<Button
android:id="@+id/selectImageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="이미지 선택" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<ImageView
android:id="@+id/originalImageView"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:scaleType="fitCenter" />
<ImageView
android:id="@+id/filteredImageView"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:scaleType="fitCenter" />
</LinearLayout>
</LinearLayout>

View File

@ -9,11 +9,9 @@ buildscript {
}
plugins {
id ("com.android.application") version "8.10.1" apply false
id ("com.android.library") version "8.10.1" apply false
id ("com.android.application") version "8.2.2" apply false
id ("com.android.library") version "8.2.2" apply false
id ("io.realm.kotlin") version "2.0.0" apply false
id("org.jetbrains.kotlin.android") version "2.0.0" apply false
}
tasks.register<Delete>("clean") {

View File

@ -22,5 +22,6 @@ android.useAndroidX=true
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
android.defaults.buildfeatures.buildconfig=true
android.nonFinalResIds=true
android.enableJetifier=true

View File

@ -38,11 +38,9 @@ dependencies {
implementation( "com.github.bumptech.glide:glide:4.11.0")
annotationProcessor ("com.github.bumptech.glide:compiler:4.11.0")
// implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation ("com.airbnb.android:lottie:5.2.0")
implementation ("androidx.annotation:annotation:1.9.1")
implementation ("androidx.appcompat:appcompat:1.7.0")
implementation ("com.google.android.material:material:1.12.0")
// implementation ("org.apache.tika:tika-parsers:1.24")
// implementation ("com.nineoldandroids:library:2.4.0")
implementation ("androidx.core:core-ktx:1.15.0")
implementation(project(":utils"))

View File

@ -11,7 +11,6 @@ import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.StateListDrawable
import android.net.MailTo
import android.net.Uri
import android.net.http.SslError
import android.os.Build
import android.os.Bundle
import android.os.Environment
@ -37,10 +36,8 @@ import android.webkit.CookieSyncManager
import android.webkit.DownloadListener
import android.webkit.GeolocationPermissions
import android.webkit.PermissionRequest
import android.webkit.SslErrorHandler
import android.webkit.ValueCallback
import android.webkit.WebChromeClient
import android.webkit.WebResourceError
import android.webkit.WebResourceRequest
import android.webkit.WebResourceResponse
import android.webkit.WebSettings
@ -61,13 +58,9 @@ import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import androidx.core.net.toUri
import androidx.lifecycle.ReportFragment.Companion.reportFragment
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kr.lunaticbum.awesomewebview.databinding.AwesomeWebViewBinding
import kr.lunaticbum.awesomewebview.enums.Position
import kr.lunaticbum.awesomewebview.helpers.BitmapHelper
@ -98,13 +91,10 @@ import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import kotlin.math.abs
import kotlin.random.Random
open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
Handler.Callback {
var loadWithIntent : Boolean = false
var mediaUrls = arrayListOf<String>()
protected var key: Int = 0
protected var rtl: Boolean = false
@ -263,7 +253,7 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
// protected var back: AppCompatImageButton? = null
// protected var forward: AppCompatImageButton? = null
// protected var more: AppCompatImageButton? = null
protected var webView: VideoEnabledWebView? = null
protected var webView: WebView? = null
protected var webChromeClient: WebChromeClient? = null
protected var webViewClient: WebViewClient? = null
// protected var gradient: View? = null
@ -556,7 +546,7 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
open fun bindViews() {
protected fun bindViews() {
binding.toolbarContent.close.setOnClickListener(this)
binding.toolbarContent.back.setOnClickListener(this)
binding.toolbarContent.forward.setOnClickListener(this)
@ -582,7 +572,7 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
fun fast() {
chechHandler.removeCallbacks(cancelSearch)
chechHandler.postDelayed(cancelSearch, 90000L)
chechHandler.postDelayed(cancelSearch, 6000L)
}
fun registCancelSearch() {
@ -801,21 +791,8 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
webView!!.setOnLongClickListener(OnLongClickListener {
val hitTestResult = webView!!.hitTestResult
LogUtil.e("hitTestResult.type >>> ${hitTestResult.type}")
LogUtil.e("hitTestResult.extra >>> ${hitTestResult.extra}")
LogUtil.e("hitTestResult >>> ${mediaUrls.size}")
if(hitTestResult.type==0) {
webView?.evaluateJavascript("document.documentElement.outerHTML",
object : ValueCallback<String> {
override fun onReceiveValue(value: String?) {
val html = value?.replace("\\u003C", "<")
onHtml(html, true)
}
})
}
else if (hitTestResult.type == HitTestResult.IMAGE_TYPE ||
// 如果是图片类型或者是带有图片链接的类型
if (hitTestResult.type == HitTestResult.IMAGE_TYPE ||
hitTestResult.type == HitTestResult.SRC_IMAGE_ANCHOR_TYPE
) {
if (!showMenuSavePhoto) {
@ -827,73 +804,68 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
val items = arrayOf(
resources.getString(stringResSavePhoto)
)
val url = hitTestResult.extra
if (webView?.url?.contains(".guru") == true) {
url?.split("/")?.last()?.let { last ->
var code = if(last.contains("_") && last.split("_")?.first()?.length ?: 0 > 2) {
last.split("_").first()
} else if(last.contains("-") && last.split("-")?.first()?.length ?: 0 > 2) {
last.split("-").first()
} else {
last
}
LogUtil.e("hitTestResult code >>> ${code}")
webView?.evaluateJavascript("try{GJI.onCode('${code}');}catch(e){console.log(e);}", {})
}
showBlock()
return@OnLongClickListener false
}
builder?.setItems(
items
) { dialog, which ->
LogUtil.e("hitTestResult.extra >>> ${dialog} ,${which}")
val url = hitTestResult.extra
PermissionHelper.CheckPermissions(
this@AwesomeWebViewActivity,
object : CheckPermissionListener {
override fun onAllGranted(sync: Boolean) {
val url = hitTestResult.extra
// 下载图片到本地
CookieSyncManager.createInstance(this@AwesomeWebViewActivity)
CookieSyncManager.getInstance().sync()
val cookieManager =
CookieManager.getInstance()
val cookie =
cookieManager.getCookie(webView!!.url)
DownPicUtil.downPic(
url,
webView!!.settings.userAgentString,
webView!!.url,
cookie,
object : DownFinishListener {
override fun onDownFinish(path: String) {
if (showToastPhotoSavedOrFailed) {
Toast.makeText(
this@AwesomeWebViewActivity,
resources.getString(
stringResPhotoSavedTo
) + path,
Toast.LENGTH_LONG
).show()
}
// 最后通知图库更新
applicationContext.sendBroadcast(
Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
Uri.parse("file://$path")
)
)
}
CookieSyncManager.createInstance(applicationContext)
CookieSyncManager.getInstance().sync()
val cookieManager =
CookieManager.getInstance()
val cookie =
cookieManager.getCookie(webView!!.url)
DownPicUtil.downPic(
File(Environment.getExternalStorageDirectory(),"bums").path,
url,
webView!!.settings.userAgentString,
webView!!.url,
cookie,
object : DownFinishListener {
override fun onDownFinish(url : String ,path: String) {
if (showToastPhotoSavedOrFailed) {
Toast.makeText(
applicationContext,
resources.getString(
stringResPhotoSavedTo
) + path,
Toast.LENGTH_LONG
).show()
}
// 最后通知图库更新
applicationContext.sendBroadcast(
Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
Uri.parse("file://$path")
)
)
override fun onError() {
if (showToastPhotoSavedOrFailed) {
Toast.makeText(
this@AwesomeWebViewActivity,
resources.getString(
stringResPhotoSaveFailed
),
Toast.LENGTH_LONG
).show()
}
}
})
}
override fun onError() {
if (showToastPhotoSavedOrFailed) {
Toast.makeText(
applicationContext,
resources.getString(
stringResPhotoSaveFailed
),
Toast.LENGTH_LONG
).show()
}
override fun onPartlyGranted(
permissionsDenied: List<String>,
sync: Boolean
) {
}
})
},
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
}
val dialog = builder?.create()
dialog?.show()
@ -902,27 +874,27 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
false
})
// webView!!.setOnTouchListener(object : OnTouchListener {
// private var xDown = 0f
// private var yDown = 0f
// private var timeDown: Long = 0
// override fun onTouch(v: View, event: MotionEvent): Boolean {
// if (v === webView && event.action == MotionEvent.ACTION_DOWN) {
// xDown = event.x
// yDown = event.y
// timeDown = System.currentTimeMillis()
// } else if (v === webView && event.action == MotionEvent.ACTION_UP) {
// if (abs((xDown - event.x).toDouble()) < 50 && abs(
// (yDown - event.y).toDouble()
// ) < 50 && System.currentTimeMillis() - timeDown < 200
// ) {
// // https://stackoverflow.com/a/5125620
// handler.sendEmptyMessageDelayed(MSG_CLICK_ON_WEBVIEW, 500)
// }
// }
// return false
// }
// })
webView!!.setOnTouchListener(object : OnTouchListener {
private var xDown = 0f
private var yDown = 0f
private var timeDown: Long = 0
override fun onTouch(v: View, event: MotionEvent): Boolean {
if (v === webView && event.action == MotionEvent.ACTION_DOWN) {
xDown = event.x
yDown = event.y
timeDown = System.currentTimeMillis()
} else if (v === webView && event.action == MotionEvent.ACTION_UP) {
if (abs((xDown - event.x).toDouble()) < 50 && abs(
(yDown - event.y).toDouble()
) < 50 && System.currentTimeMillis() - timeDown < 200
) {
// https://stackoverflow.com/a/5125620
handler.sendEmptyMessageDelayed(MSG_CLICK_ON_WEBVIEW, 500)
}
}
return false
}
})
val settings = webView!!.settings
@ -1267,31 +1239,7 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
}
}
open protected fun onHtml(value: String?, autoCheck : Boolean) {
}
protected fun showBlock() {
binding.blocking.visibility = View.VISIBLE
val ress = arrayListOf(R.raw.dlottie_001,R.raw.lt_lodaing_01,R.raw.dlottie_003,R.raw.lt_lodaing_02,R.raw.lt_lodaing_03,R.raw.dlottie_002)
var isEven = ((System.currentTimeMillis() % 2).toInt() == 0)
var firstSeed = Random(if(isEven)8739 else 7531)
var randomSeed_01 = Math.abs(firstSeed.nextInt()) % if(isEven) 879 else 56
var randomSeed_02 = Math.abs(firstSeed.nextInt()) % if(!isEven) 758 else 397
var randomSeed_03 = Math.abs(firstSeed.nextInt()) % if(!isEven) 353 else 49
var totalSeed = Math.abs((Math.abs(randomSeed_01) * Math.abs(randomSeed_02)) + Math.abs(randomSeed_03))
var randomResult = Math.abs(totalSeed % ress.size)
LogUtil.e("randomResult >>> randomSeed_01 {${randomSeed_01}} | randomSeed_02 {${randomSeed_02}} | randomSeed_03 {${randomSeed_03}} | resSize {${ress.size}} | ${randomResult}")
binding.lotti.setAnimation(ress[Math.abs(randomResult)])
binding.lotti.playAnimation()
}
protected fun hideBlock() {
binding.blocking.visibility = View.GONE
binding.lotti.pauseAnimation()
}
protected fun buildWebView(): VideoEnabledWebView {
protected fun buildWebView(): WebView {
return VideoEnabledWebView(this)
}
@ -1457,8 +1405,6 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
}
}
open protected var pdfListner : PDFPrint.OnPDFPrintListener? = null
override fun onClick(v: View) {
val viewId = v.id
if (viewId == R.id.close) {
@ -1497,23 +1443,16 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
if (path.exists() == false) {
path.mkdirs()
}
val file = File(path, fileName)
PDFPrint.generatePDFFromWebView(
file,
webView,
pdfListner ?: object : PDFPrint.OnPDFPrintListener {
override fun onSuccess(file: File?) {
LogUtil.e("file.absolutePath >>> ${file?.absolutePath ?: "fail"}")
}
override fun onError(exception: java.lang.Exception?) {
LogUtil.e("generatePDFFromWebView >>> fail")
exception?.printStackTrace()
}
PDFPrint.generatePDFFromWebView(file,webView,object :PDFPrint.OnPDFPrintListener {
override fun onSuccess(file: File?) {
LogUtil.e("file.absolutePath >>> ${file?.absolutePath ?: "fail"}")
}
)
override fun onError(exception: java.lang.Exception?) {
exception?.printStackTrace()
}
})
hideMenu()
} else if (viewId == R.id.menuFind) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) webView!!.showFindDialog(
@ -1910,7 +1849,6 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
return File.createTempFile(new_name, if (isVideo) ".mp4" else ".jpg", sd_directory)
}
var hasYoutubePlayer = false
open fun webviewOnPageFinished(){}
inner class MyWebViewClient : WebViewClient() {
@ -1918,62 +1856,38 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
view: WebView,
request: WebResourceRequest
): WebResourceResponse? {
if (host?.contains("booktoki") == true) {
return super.shouldInterceptRequest(view, request)
}
var skipResource =
(host != null) && ((request.url?.host?.contains(host!!) ?: true) == false)
if (skipResource && request.url.toString().contains("gif")) {
LogUtil.e("shouldInterceptRequest request block gif resource >>> ${request.url.toString()}")
return WebResourceResponse(
"text/plain", "utf-8",
ByteArrayInputStream("".toByteArray())
)
}
val url = request.url.toString()
if (url.contains("streamable.com") ||
url.contains("img-cdn.theqoo") ||
url.contains("embed/player/") ||
url.contains("dcinside.co.kr/viewimage") ||
url.contains("daumcdn.net/cafeattach") ||
url.toLowerCase(Locale.ROOT).contains(".jpg") ||
url.toLowerCase(Locale.ROOT).contains(".png") ||
url.toLowerCase(Locale.ROOT).contains(".gif") ||
url.toLowerCase(Locale.ROOT).contains(".svg") ||
url.toLowerCase(Locale.ROOT).contains(".webp")) {
mediaUrls.add(url)
// LogUtil.e("mediaUrls >>>>> add(${url})")
}
if(!hasYoutubePlayer) {
hasYoutubePlayer = url.toLowerCase(Locale.ROOT)
.contains("https://www.youtube.com/s/player".toLowerCase(Locale.ROOT))
}
//https://t1.daumcdn.net/cafeattach/mEr9/adc6e81a386099c4cc06f77f8b7eea15675de0d4
if (url.toLowerCase(Locale.ROOT)
.contains("ads".toLowerCase(Locale.ROOT))) {
// LogUtil.e("shouldInterceptRequest request url contains ads >>> ${request.url.toString()}")
LogUtil.e("shouldInterceptRequest request url contains ads >>> ${request.url.toString()}")
}
var callSupers = arrayListOf("google-analytics.com","analytics.google.com","api.dable.io")
var adblockKeyWords = arrayOf("adcr.naver.com","daumcdn.net/biz/ui/ad/adcm","imgad","ad.daum.net","cr.adsappier.com","ar-adview","adtrafficquality","criteo","adlib.nhnace.com","google.com/ads","googleads.","/pagead","/adpost/","ads/search","plugin.adplex")
val supers = callSupers.filter { url.toLowerCase(Locale.ROOT).contains(it.toLowerCase(Locale.ROOT)) }.size > 0
val adblock = adblockKeyWords.filter { url.toLowerCase(Locale.ROOT).contains(it.toLowerCase(Locale.ROOT)) }.size > 0
return if(adblock) {
try {
// LogUtil.e("shouldInterceptRequest request block adblockKeyWords resource >>> ${request.url.toString()}")
LogUtil.e("shouldInterceptRequest request block adblockKeyWords resource >>> ${request.url.toString()}")
WebResourceResponse("text/plain", "utf-8", ByteArrayInputStream("".toByteArray()))
} catch (e : Exception) {
super.shouldInterceptRequest(view, url)
}
} else if(supers) {
super.shouldInterceptRequest(view, url)
} else if(url.toLowerCase(Locale.ROOT).contains(".jpg") || url.toLowerCase(Locale.ROOT).contains(".jpeg")){
}else if(url.toLowerCase(Locale.ROOT).contains(".jpg") || url.toLowerCase(Locale.ROOT).contains(".jpeg")){
try {
val bitmap = Glide.with(this@AwesomeWebViewActivity).asBitmap().timeout(30000).diskCacheStrategy(DiskCacheStrategy.ALL).load(url).submit().get()
WebResourceResponse("image/jpg", "UTF-8",getBitmapInputStream(bitmap,Bitmap.CompressFormat.JPEG)).apply {
// LogUtil.e("shouldInterceptRequest request url down from Glide >>> ${request.url.toString()}")
LogUtil.e("shouldInterceptRequest request url down from Glide >>> ${request.url.toString()}")
}
} catch (e : Exception) {
super.shouldInterceptRequest(view, url)
@ -1982,7 +1896,7 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
try {
val bitmap = Glide.with(this@AwesomeWebViewActivity).asBitmap().timeout(30000).diskCacheStrategy(DiskCacheStrategy.ALL).load(url).submit().get()
WebResourceResponse("image/png", "UTF-8",getBitmapInputStream(bitmap,Bitmap.CompressFormat.PNG)).apply {
// LogUtil.e("shouldInterceptRequest request url down from Glide >>> ${request.url.toString()}")
LogUtil.e("shouldInterceptRequest request url down from Glide >>> ${request.url.toString()}")
}
} catch (e : Exception) {
super.shouldInterceptRequest(view, url)
@ -1992,7 +1906,7 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
try {
val bitmap = Glide.with(this@AwesomeWebViewActivity).asBitmap().timeout(30000).diskCacheStrategy(DiskCacheStrategy.ALL).load(url).submit().get()
WebResourceResponse("image/webp", "UTF-8",getBitmapInputStream(bitmap,Bitmap.CompressFormat.WEBP)).apply {
// LogUtil.e("shouldInterceptRequest request url down from Glide >>> ${request.url.toString()}")
LogUtil.e("shouldInterceptRequest request url down from Glide >>> ${request.url.toString()}")
}
} catch (e : Exception) {
super.shouldInterceptRequest(view, url)
@ -2014,8 +1928,6 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
// }
override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) {
mediaUrls.clear()
BroadCastManager.onPageStarted(this@AwesomeWebViewActivity, key, url)
if (!url.contains("docs.google.com") && url.endsWith(".pdf")) {
webView!!.loadUrl("http://docs.google.com/gview?embedded=true&url=$url")
@ -2039,9 +1951,7 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
BroadCastManager.onPageFinished(this@AwesomeWebViewActivity, key, url)
if (updateTitleFromHtml) binding.toolbarContent.title.text = view.title
try {
binding.toolbarContent.url.text = UrlParser.getHost(url)
}catch (e :Exception) {e.printStackTrace()}
binding.toolbarContent.url.text = UrlParser.getHost(url)
requestCenterLayout()
if (view.canGoBack() || view.canGoForward()) {
@ -2070,23 +1980,11 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
registCancelSearch()
}
@Deprecated("Deprecated in Java")
override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
handler.sendEmptyMessage(MSG_CLICK_ON_URL)
if (url.contains("booktoki")) {
return false
}
if (url.contains("http:")) {
var newUrl = url.replace("http:","https:")
LogUtil.e("is StartWith ${url} , ${newUrl}")
if (newUrl.length > 10) {
view.stopLoading()
view.loadUrl(newUrl)
}
return true
}
var skipResource = host!= null && ((url.contains(host!!) ?: true) == false) && (host!!.contains("google") == false)
if (skipResource || loadWithIntent) {
if (skipResource) {
LogUtil.e("shouldOverrideUrlLoading block url $url , host >>>> $host ")
val alertDialog = AlertDialog.Builder(view.context).create()
alertDialog.setCancelable(false)
@ -2173,22 +2071,6 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
override fun onPageCommitVisible(view: WebView, url: String) {
BroadCastManager.onPageCommitVisible(this@AwesomeWebViewActivity, key, url)
}
override fun onReceivedError(
view: WebView?,
request: WebResourceRequest?,
error: WebResourceError?
) {
super.onReceivedError(view, request, error)
}
override fun onReceivedSslError(
view: WebView?,
handler: SslErrorHandler?,
error: SslError?
) {
handler?.proceed()
}
}
protected fun parsePermission(resource: Array<String>): Array<String?> {

View File

@ -4,16 +4,9 @@ package kr.lunaticbum.awesomewebview.helpers;
* Created by wuzongheng on 2018/2/18.
*/
import static java.sql.DriverManager.println;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.Nullable;
import java.io.ByteArrayInputStream;
import java.io.File;
@ -24,11 +17,6 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import kr.lunaticbum.utils.log.LogUtil;
/**
* 图片下载的工具类
@ -40,86 +28,37 @@ public class DownPicUtil {
* @param url
*/
public static void downPic(String url, DownFinishListener downFinishListener){
downPic(null, url, null, null, null, downFinishListener);
downPic(url, null, null, null, downFinishListener);
}
/**
* Download the pic
* @param url
*/
public static void downPic(String path , String url, String userAgent, String referer, String cookie, DownFinishListener downFinishListener){
if(path == null) {
String filePath = Environment.getExternalStorageDirectory().getPath();
File file = new File(filePath + File.separator + Environment.DIRECTORY_DOWNLOADS);
if (!file.exists()) {
file.mkdirs();
}
loadPic(file.getPath(), url, userAgent, referer, cookie, downFinishListener, false);
} else {
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
loadPic(path, url, userAgent, referer, cookie, downFinishListener, false);
public static void downPic(String url, String userAgent, String referer, String cookie, DownFinishListener downFinishListener){
// 获取存储卡的目录
String filePath = Environment.getExternalStorageDirectory().getPath();
File file = new File(filePath + File.separator + Environment.DIRECTORY_DOWNLOADS);
if(!file.exists()){
file.mkdirs();
}
loadPic(file.getPath(), url, userAgent, referer, cookie, downFinishListener);
}
public static void downMp4(String path , String url, String userAgent, String referer, String cookie, DownFinishListener downFinishListener){
if(path == null) {
String filePath = Environment.getExternalStorageDirectory().getPath();
File file = new File(filePath + File.separator + Environment.DIRECTORY_DOWNLOADS);
if (!file.exists()) {
file.mkdirs();
}
loadPic(file.getPath(), url, userAgent, referer, cookie, downFinishListener, true);
} else {
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
loadPic(path, url, userAgent, referer, cookie, downFinishListener, true);
}
}
public static String toHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
public static byte[] hashString(String str, String algorithm) {
try {
MessageDigest digest = MessageDigest.getInstance(algorithm);
return digest.digest(str.getBytes(StandardCharsets.UTF_8));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
private static void loadPic(final String filePath, final String url, final String userAgent, final String referer, final String cookie, final DownFinishListener downFinishListener, boolean isMp4) {
private static void loadPic(final String filePath, final String url, final String userAgent, final String referer, final String cookie, final DownFinishListener downFinishListener) {
new AsyncTask<Void,Void,String>(){
String fileName;
InputStream is;
OutputStream out;
private String replaceDcUrl(String origin) {
String result = origin;
for (int i = 0; i < 20; i++) {
result = result.replace(String.format("dcimg%d.",i),"dcimg2.");
}
return result;
}
@Override
protected String doInBackground(Void... voids) {
// 原文件名
String[] split = url.split("/");
byte[] dd = hashString(url, "MD5");
fileName = dd == null ? split[split.length - 1] : toHex(dd);
fileName = split[split.length - 1];
// 创建目标文件使用时间戳作为临时文件名确保可以不重复
String now = String.valueOf(System.currentTimeMillis());
@ -133,13 +72,7 @@ public class DownPicUtil {
byte[] image = base64ImgHelper.decode();
is = new ByteArrayInputStream(image); //处理服务器的响应结果
} else {
URL picUrl = null;
if (url.contains("dcimg")) {
picUrl = new URL(replaceDcUrl(url));
} else {
picUrl = new URL(url);
}
URL picUrl = new URL(url);
//通过图片的链接打开输入流
HttpURLConnection httpURLConnection = (HttpURLConnection) picUrl.openConnection();
httpURLConnection.setConnectTimeout(10000); //设置连接超时时间
@ -148,26 +81,13 @@ public class DownPicUtil {
httpURLConnection.setDoOutput(false); //Get请求不需要DoOutPut
httpURLConnection.setRequestMethod("GET"); //设置以Get方式请求数据
httpURLConnection.setUseCaches(false); //不使用缓存
//设置请求体的类型是文本类型
// if (url.contains("dcimg")) {
//// httpURLConnection.setRequestProperty("authority", Uri.parse(url).getHost());
// httpURLConnection.setRequestProperty("Accept", "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8");
// httpURLConnection.setRequestProperty("Accept-encoding", "gzip, deflate, br, zstd");
// httpURLConnection.setRequestProperty("Sec-Fetch-Dest","image");
// httpURLConnection.setRequestProperty("Sec-Fetch-Mode","no-cors");
// httpURLConnection.setRequestProperty("Sec-Fetch-Site","cross-site");
// }
httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
if (!TextUtils.isEmpty(userAgent)) {
httpURLConnection.setRequestProperty("User-Agent", userAgent);
}
if (!TextUtils.isEmpty(referer)) {
httpURLConnection.setRequestProperty("Referer", referer);
println("referer>>>> " + referer);
}
if (!TextUtils.isEmpty(cookie)) {
httpURLConnection.setRequestProperty("Cookie", cookie);
@ -220,9 +140,6 @@ public class DownPicUtil {
} else {
newFileNameNoExtension = fileName;
}
if (isVideoFileByMetadata(picFile) && extension == null && isMp4) {
extension = "mp4";
}
// 重命名文件
if (extension == null) {
@ -234,24 +151,21 @@ public class DownPicUtil {
// 无拓展名整个文件名递增重命名
return renamePic(picFile, filePath, newFileNameNoExtension, null, MODE.MODE_INCREMENT);
}
} else {
return renamePic(picFile, filePath, newFileNameNoExtension, extension, MODE.MODE_IGNORE);
}
// 支持解析的格式使用md5文件名真实拓展名
// return picFile.getPath();
// String md5 = Md5Helper.getFileMD5ToString(picFile);
// if (TextUtils.isEmpty(md5)) {
// return renamePic(picFile, filePath, newFileNameNoExtension, extension, MODE.MODE_INCREMENT);
// } else {
// return renamePic(picFile, filePath, md5.substring(0, 16), extension, MODE.MODE_IGNORE);
// }
String md5 = Md5Helper.getFileMD5ToString(picFile);
if (TextUtils.isEmpty(md5)) {
return renamePic(picFile, filePath, newFileNameNoExtension, extension, MODE.MODE_INCREMENT);
} else {
return renamePic(picFile, filePath, md5.substring(0, 16), extension, MODE.MODE_IGNORE);
}
}
@Override
protected void onPostExecute(String path) {
super.onPostExecute(path);
if(path!=null){
downFinishListener.onDownFinish(url,path);
downFinishListener.onDownFinish(path);
} else {
downFinishListener.onError();
}
@ -274,26 +188,6 @@ public class DownPicUtil {
MODE_OVERRIDE
}
private static Boolean isVideoFileByMetadata(File file) {
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
try {
retriever.setDataSource(file.getAbsolutePath());
println("retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE) >>> " + retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE));
String duration = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
return duration != null;
} catch (Exception e) {
return false;
} finally {
try {
retriever.release();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static String renamePic(File picFile, String filePath, String newFileNameNoExtension, String extension, MODE mode) {
String extensionWithPoint = TextUtils.isEmpty(extension)? "": "." + extension;
String newFileName = newFileNameNoExtension + extensionWithPoint;
@ -348,7 +242,7 @@ public class DownPicUtil {
//下载完成回调的接口
public interface DownFinishListener{
void onDownFinish(String srcUrl ,String path);
void onDownFinish(String path);
void onError();
}
}

View File

@ -6,8 +6,6 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import kr.lunaticbum.utils.log.LogUtil;
public class FormatHelper {
private FormatHelper() {
@ -15,7 +13,6 @@ public class FormatHelper {
public static String getExtension(File file) {
try {
// long fileLength = file.length();
FileInputStream fileInputStream = new FileInputStream(file);
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
@ -84,34 +81,7 @@ public class FormatHelper {
start[5] == (byte) 0x61) {
return "gif";
}
bufferedInputStream.reset();
start = new byte[6];
bufferedInputStream.read(start);
if (start[0] == (byte) 0x47 &&
start[1] == (byte) 0x49 &&
start[2] == (byte) 0x46 &&
start[3] == (byte) 0x38 &&
start[4] == (byte) 0x37 &&
start[5] == (byte) 0x61) {
return "gif";
}
bufferedInputStream.reset();
start = new byte[100];
bufferedInputStream.read(start);
String xmlDeclaration = new String(start, 0, 100, "UTF-8");
LogUtil.INSTANCE.e("Path " + file.getAbsolutePath() + " ::: HEADE" + xmlDeclaration + ";");
if (xmlDeclaration.contains("<?xml version=\"1.0\" encoding=\"UTF-8\"?>") ||
xmlDeclaration.contains("http://www.w3.org/2000/svg")) {
return "svg";
}else if (xmlDeclaration.contains("iso") &&
xmlDeclaration.contains("mp4")) {
return "mp4";
}
bufferedInputStream.reset();
LogUtil.INSTANCE.e("Path " + file.getAbsolutePath() + " ::: HEADE" + start[0] + "," + start[1] + "," + start[2] + "," + start[3] + "," + start[4] + "," + start[5] + ";");
bufferedInputStream.close();
fileInputStream.close();
} catch (FileNotFoundException e) {

View File

@ -46,12 +46,33 @@ public class PermissionHelper {
public static void CheckPermissions(final Context context, final CheckPermissionListener checkPermissionListener, String... permissionName) {
// if (hasPermissions(context, permissionName)) {
if (hasPermissions(context, permissionName)) {
if (checkPermissionListener != null) {
checkPermissionListener.onAllGranted(true);
}
// }else {
// }
}else {
// AndPermission.with(context)
// .runtime()
// .permission(permissionName)
// .onGranted(new Action<List<String>>() {
// @Override
// public void onAction(List<String> permissions) {
// // 权限申请成功回调
// if (checkPermissionListener != null) {
// checkPermissionListener.onAllGranted(false);
// }
// }
// })
// .onDenied(new Action<List<String>>() {
// @Override
// public void onAction(List<String> permissions) {
// if (checkPermissionListener != null) {
// checkPermissionListener.onPartlyGranted(permissions, false);
// }
// }
// })
// .start();
}
}
}

View File

@ -97,54 +97,5 @@ public class VideoEnabledWebView extends WebView
videoJsHelper.addJavascriptInterface(this);
super.loadUrl(url, additionalHttpHeaders);
}
private boolean topReached = false;
private boolean bottomReached = false;
@Override
public int computeVerticalScrollRange() {
int readerViewHeight = getMeasuredHeight();
int verticalScrollRange = super.computeVerticalScrollRange();
if (readerViewHeight >= verticalScrollRange) {
topReached = true;
bottomReached = true;
}
return verticalScrollRange;
}
@Override
public void onScrollChanged(int newLeft, int newTop, int oldLeft, int oldTop) {
topReached = false;
bottomReached = false;
int readerViewHeight = getMeasuredHeight();
int contentHeight = getContentHeight();
if (newTop == 0) {
topReached = true;
} else if (newTop + readerViewHeight >= contentHeight) {
bottomReached = true;
}
super.onScrollChanged(newLeft, newTop, oldLeft, oldTop);
}
}

View File

@ -82,34 +82,6 @@
android:visibility="invisible" /> -->
</RelativeLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/blocking"
android:visibility="gone"
android:background="#99000000"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/lotti"
android:layout_width="match_parent"
android:layout_height="250dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:lottie_autoPlay="true"
app:lottie_loop="true"
app:lottie_rawRes="@raw/lt_lodaing_01"
app:lottie_repeatMode="reverse"
/>
<TextView
app:layout_constraintTop_toBottomOf="@id/lotti"
android:gravity="center"
android:textColor="#FFFFFF"
android:textSize="30dp"
android:text="저장을 위해\n리소스 모으는중..."
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -3,8 +3,6 @@ pluginManagement {
gradlePluginPortal()
google()
mavenCentral()
// jcenter()
maven (url = "https://maven.mozilla.org/maven2/")
}
}
@ -12,13 +10,12 @@ pluginManagement {
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
// jcenter()
google()
mavenCentral()
maven (url = "https://maven.mozilla.org/maven2/")
maven(url = "https://jitpack.io")
}
}
rootProject.name = "LunarLauncher"
include ("app","library","utils")
//annotations

View File

@ -0,0 +1,13 @@
package com.thefinestartist.utils;
import android.app.Application;
import android.test.ApplicationTestCase;
/**
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
*/
public class ApplicationTest extends ApplicationTestCase<Application> {
public ApplicationTest() {
super(Application.class);
}
}

View File

@ -0,0 +1,278 @@
package com.thefinestartist.utils.etc;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import kr.lunaticbum.Base;
import kr.lunaticbum.utils.preferences.PreferencesUtil;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
/**
* Tests of the {@link PreferencesUtil} class.
*
* @author Robin Gustafsson
*/
public class PreferencesUtilTest extends AndroidTestCase {
@Override
public void setUp() throws Exception {
super.setUp();
Base.initialize(getContext());
}
@SmallTest
public void testSetGetDefaultName() {
final String expected = "TEST_DEFAULT_NAME";
PreferencesUtil.setDefaultName(expected);
String actual = PreferencesUtil.getDefaultName();
assertEquals(expected, actual);
}
@SmallTest
public void testDifferentNames() {
final String name1 = "TEST_DIFFERENTNAMES_NAME1";
final String name2 = "TEST_DIFFERENTNAMES_NAME2";
final String key = "TEST_DIFFERENTNAMES_KEY";
final boolean value = true;
final boolean expected = false;
PreferencesUtil.put(name1, key, value);
boolean actual = PreferencesUtil.get(name2, key, expected);
assertEquals(expected, actual);
}
@SmallTest
public void testStoreBoolean() {
final String key = "TEST_BOOLEAN";
final boolean expected = true;
final boolean defValue = false;
PreferencesUtil.put(key, expected);
boolean actual = PreferencesUtil.get(key, defValue);
assertEquals(expected, actual);
}
@SmallTest
public void testStoreBooleanNamed() {
final String name = "TEST_NAMED";
final String key = "TEST_BOOLEAN";
final boolean expected = true;
final boolean defValue = false;
PreferencesUtil.put(name, key, expected);
boolean actual = PreferencesUtil.get(name, key, defValue);
assertEquals(expected, actual);
}
@SmallTest
public void testStoreInt() {
final String key = "TEST_INT";
final int expected = 321;
final int defValue = 0;
PreferencesUtil.put(key, expected);
int actual = PreferencesUtil.get(key, defValue);
assertEquals(expected, actual);
}
@SmallTest
public void testStoreIntNamed() {
final String name = "TEST_NAMED";
final String key = "TEST_INT";
final int expected = 321;
final int defValue = 0;
PreferencesUtil.put(name, key, expected);
int actual = PreferencesUtil.get(name, key, defValue);
assertEquals(expected, actual);
}
@SmallTest
public void testStoreFloat() {
final String key = "TEST_FLOAT";
final float expected = 12.3f;
final float defValue = 0.0f;
PreferencesUtil.put(key, expected);
float actual = PreferencesUtil.get(key, defValue);
assertEquals(expected, actual);
}
@SmallTest
public void testStoreFloatNamed() {
final String name = "TEST_NAMED";
final String key = "TEST_FLOAT";
final float expected = 12.3f;
final float defValue = 0.0f;
PreferencesUtil.put(name, key, expected);
float actual = PreferencesUtil.get(name, key, defValue);
assertEquals(expected, actual);
}
@SmallTest
public void testStoreLong() {
final String key = "TEST_LONG";
final long expected = 321L;
final long defValue = 0L;
PreferencesUtil.put(key, expected);
long actual = PreferencesUtil.get(key, defValue);
assertEquals(expected, actual);
}
@SmallTest
public void testStoreLongNamed() {
final String name = "TEST_NAMED";
final String key = "TEST_LONG";
final long expected = 321L;
final long defValue = 0L;
PreferencesUtil.put(name, key, expected);
long actual = PreferencesUtil.get(name, key, defValue);
assertEquals(expected, actual);
}
@SmallTest
public void testStoreString() {
final String key = "TEST_STRING";
final String expected = "Lorem ipsum";
final String defValue = null;
PreferencesUtil.put(key, expected);
String actual = PreferencesUtil.get(key, defValue);
assertEquals(expected, actual);
}
@SmallTest
public void testStoreStringNamed() {
final String name = "TEST_NAMED";
final String key = "TEST_STRING";
final String expected = "Lorem ipsum";
final String defValue = null;
PreferencesUtil.put(name, key, expected);
String actual = PreferencesUtil.get(name, key, defValue);
assertEquals(expected, actual);
}
@SmallTest
public void testStoreStringSet() {
final String key = "TEST_STRINGSET";
final Set<String> expected = new HashSet<>();
expected.add("Lorem ipsum");
expected.add("dolor sit amet");
expected.add("consectetur adipiscing elit");
final Set<String> defValue = null;
PreferencesUtil.put(key, expected);
Set<String> actual = PreferencesUtil.get(key, defValue);
assertEquals(expected, actual);
}
@SmallTest
public void testStoreStringSetNamed() {
final String name = "TEST_NAMED";
final String key = "TEST_STRINGSET";
final Set<String> expected = new HashSet<>();
expected.add("Lorem ipsum");
expected.add("dolor sit amet");
expected.add("consectetur adipiscing elit");
final Set<String> defValue = null;
PreferencesUtil.put(name, key, expected);
Set<String> actual = PreferencesUtil.get(name, key, defValue);
assertEquals(expected, actual);
}
@MediumTest
public void testStoreSerializable() {
final String key = "TEST_SERIALIZABLE";
final ArrayList<String> expected = new ArrayList<>();
expected.add("Lorem ipsum");
expected.add("dolor sit amet");
expected.add("consectetur adipiscing elit");
final ArrayList<String> defValue = new ArrayList<>();
defValue.add("Proin mollis dictum");
PreferencesUtil.put(key, expected);
ArrayList<String> actual = PreferencesUtil.get(key, defValue);
assertEquals(expected, actual);
}
@MediumTest
public void testStoreSerializableNamed() {
final String name = "TEST_NAMED";
final String key = "TEST_SERIALIZABLE";
final ArrayList<String> expected = new ArrayList<>();
expected.add("Lorem ipsum");
expected.add("dolor sit amet");
expected.add("consectetur adipiscing elit");
final ArrayList<String> defValue = new ArrayList<>();
defValue.add("Proin mollis dictum");
PreferencesUtil.put(name, key, expected);
ArrayList<String> actual = PreferencesUtil.get(name, key, defValue);
assertEquals(expected, actual);
}
@SmallTest
public void testRemove() {
final String key = "TEST_REMOVE";
final String expected = null;
PreferencesUtil.put(key, "Lorem ipsum");
PreferencesUtil.remove(key);
String actual = PreferencesUtil.get(key, expected);
assertEquals(expected, actual);
}
@SmallTest
public void testRemoveNamed() {
final String name = "TEST_NAMED";
final String key = "TEST_REMOVE";
final String expected = null;
PreferencesUtil.put(name, key, "Lorem ipsum");
PreferencesUtil.remove(name, key);
String actual = PreferencesUtil.get(name, key, expected);
assertEquals(expected, actual);
}
@SmallTest
public void testClear() {
final String[] keys = {"TEST_REMOVE_1", "TEST_REMOVE_2", "TEST_REMOVE_2"};
final String expected = null;
for (String key : keys) {
PreferencesUtil.put(key, "Lorem ipsum");
}
PreferencesUtil.clear();
for (String key : keys) {
String actual = PreferencesUtil.get(key, expected);
assertEquals(expected, actual);
}
}
@SmallTest
public void testClearNamed() {
final String name = "TEST_NAMED";
final String[] keys = {"TEST_REMOVE_1", "TEST_REMOVE_2", "TEST_REMOVE_2"};
final String expected = null;
for (String key : keys) {
PreferencesUtil.put(name, key, "Lorem ipsum");
}
PreferencesUtil.clear(name);
for (String key : keys) {
String actual = PreferencesUtil.get(name, key, expected);
assertEquals(expected, actual);
}
}
}

View File

@ -65,8 +65,7 @@ public class PDFPrint {
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", PrintAttributes.MediaSize.ISO_A4.getWidthMils(), PrintAttributes.MediaSize.ISO_A4.getWidthMils()))
.setDuplexMode(PrintAttributes.DUPLEX_MODE_NONE)
.setResolution(new PrintAttributes.Resolution("RESOLUTION_ID", "RESOLUTION_ID", 600, 600))
.setMinMargins(PrintAttributes.Margins.NO_MARGINS)
.build();

View File

@ -0,0 +1,15 @@
package com.thefinestartist.utils;
import static org.junit.Assert.*;
import org.junit.Test;
/**
* To work on unit tests, switch the Test Artifact in the Build Variants view.
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}