...
This commit is contained in:
parent
f7f71ca195
commit
2f63f8550a
@ -120,7 +120,9 @@ dependencies {
|
||||
// implementation("org.opencv:opencv-android:4.11.0")
|
||||
// build.gradle에 추가
|
||||
// implementation ("com.github.aeonSolutions:FloatingActionButtonMenuDrag:1.1")
|
||||
|
||||
implementation("io.github.junkfood02.youtubedl-android:library:0.17.4")
|
||||
implementation("io.github.junkfood02.youtubedl-android:ffmpeg:0.17.4")
|
||||
implementation("io.github.junkfood02.youtubedl-android:aria2c:0.17.4")
|
||||
|
||||
|
||||
implementation ("androidx.media:media:1.7.0")
|
||||
|
||||
@ -79,6 +79,7 @@
|
||||
android:stateNotNeeded="true"
|
||||
android:enableOnBackInvokedCallback="true"
|
||||
android:largeHeap="true"
|
||||
android:extractNativeLibs="true"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:hardwareAccelerated="true"
|
||||
android:usesCleartextTraffic="true"
|
||||
@ -136,7 +137,7 @@
|
||||
<!-- </activity>-->
|
||||
|
||||
<service
|
||||
android:name=".helpers.BluetoothManager"
|
||||
android:name=".helpers.ForeGroundService"
|
||||
android:enabled="true"
|
||||
android:exported="false" />
|
||||
<service
|
||||
@ -169,16 +170,16 @@
|
||||
android:exported="true">
|
||||
|
||||
</activity>
|
||||
<!-- <activity-->
|
||||
<!-- android:name=".settings.SettingsActivity"-->
|
||||
<!-- android:label="@string/lunar_settings"-->
|
||||
<!-- android:launchMode="singleTask"-->
|
||||
<!-- android:excludeFromRecents="true"-->
|
||||
<!-- android:exported="true">-->
|
||||
<!-- <intent-filter>-->
|
||||
<!-- <action android:name="android.intent.action.APPLICATION_PREFERENCES" />-->
|
||||
<!-- </intent-filter>-->
|
||||
<!-- </activity>-->
|
||||
<activity
|
||||
android:name=".settings.SettingsActivity"
|
||||
android:label="@string/lunar_settings"
|
||||
android:launchMode="singleTask"
|
||||
android:excludeFromRecents="true"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.APPLICATION_PREFERENCES" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<!-- <activity-->
|
||||
<!-- android:name=".behavior.Behavior"-->
|
||||
<!-- android:label="@string/lunar_settings"-->
|
||||
@ -269,15 +270,17 @@
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_paths" />
|
||||
</provider>
|
||||
<!-- <service android:name=".receiver.NLService"-->
|
||||
<!-- android:label="@string/app_name"-->
|
||||
<!-- android:enabled="true"-->
|
||||
<!-- android:exported="true"-->
|
||||
<!-- android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">-->
|
||||
<!-- <intent-filter>-->
|
||||
<!-- <action android:name="android.service.notification.NotificationListenerService" />-->
|
||||
<!-- </intent-filter>-->
|
||||
<!-- </service>-->
|
||||
|
||||
<service android:name=".receiver.NLService"
|
||||
android:label="@string/app_name"
|
||||
android:enabled="true"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
|
||||
<intent-filter>
|
||||
<action android:name="android.service.notification.NotificationListenerService" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<!-- <service android:name="bums.lunatic.launcher.workers.LocationUpdateService" />-->
|
||||
|
||||
<!-- <receiver android:name=".LauncherActivity$EndCallReceiver"-->
|
||||
|
||||
@ -253,9 +253,16 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
if (port) {
|
||||
sendMessage({type: "MSG", msg: "connect prot"});
|
||||
time1 = setTimeout(autoScrollAndSave(false), 3500)
|
||||
|
||||
}
|
||||
})
|
||||
document.addEventListener('touchstart', function(e) {
|
||||
console.log('터치 시작');
|
||||
});
|
||||
|
||||
document.addEventListener('touchend', function(e) {
|
||||
autoScrollAndSave()
|
||||
});
|
||||
|
||||
function scrollToLazyImg(fastMode) {
|
||||
(function(autoScrollAndSave){
|
||||
@ -346,12 +353,16 @@ function isNewerThanOneDay(dateStr) {
|
||||
function autoScrollAndSave(senContents) {
|
||||
// 도메인에 맞는 handler 실행
|
||||
const matchedRule = domainRules.find(rule => rule.test(location.href));
|
||||
try {
|
||||
if (matchedRule) {
|
||||
matchedRule.handler();
|
||||
}
|
||||
}catch (e) { }
|
||||
|
||||
try {
|
||||
// 공통 광고 요소 제거는 항상 실행
|
||||
handleCommon();
|
||||
window.scrollTo({ top: 2, behavior: 'smooth' });
|
||||
}catch (e) { }
|
||||
if (mainContentsEl == null) {
|
||||
mainContentsEl = document.body.outerHTML
|
||||
}
|
||||
@ -545,7 +556,11 @@ function handleCommon() {
|
||||
|
||||
gotoNext()
|
||||
}
|
||||
window.scrollTo({ top: 2, behavior: 'smooth' });
|
||||
if (window.scrollY < 5) {
|
||||
console.log("window.scrollY >>> " + window.scrollY)
|
||||
window.scrollTo({ top: 5, behavior: 'smooth' });
|
||||
}
|
||||
|
||||
}
|
||||
function handleToreentZota() {
|
||||
if (location.href.search("torrentzota") > -1 && document.querySelectorAll('a')) {
|
||||
@ -759,13 +774,26 @@ function handleDoctorsnews() {
|
||||
}
|
||||
|
||||
function handleDcinside() {
|
||||
try {
|
||||
document.querySelectorAll(
|
||||
'[id^="view_btn_area"], [class^="trend-rank"], [class^="view-btm-con"], [class^="md-tit-box"], [class^="gall-detail-lst"], [class^="outside-search-box"], [class^="footer ftlong"], [class^="adv-group"], li[style^="cursor:default;"], [id^="div_adnmore_area"]'
|
||||
).forEach(e => e.remove());
|
||||
}catch (e) {
|
||||
|
||||
}
|
||||
try {
|
||||
document.querySelectorAll('div[class^="imgwrap"]').forEach(function (e) {
|
||||
try {e.style.backgroundColor = 'red';} catch (e) {}
|
||||
})
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
document.querySelectorAll('div[class^="imgwrap"]')[0].click()
|
||||
}catch (e) {
|
||||
|
||||
}
|
||||
mainContentsEl = document.querySelector('div[class="container"]');
|
||||
}
|
||||
|
||||
|
||||
@ -22,13 +22,11 @@ package bums.lunatic.launcher
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.SearchManager
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.Color
|
||||
import android.graphics.Rect
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
@ -49,89 +47,50 @@ import android.view.PointerIcon
|
||||
import android.view.View
|
||||
import android.view.WindowInsets
|
||||
import android.view.WindowManager
|
||||
import android.widget.Button
|
||||
import android.widget.HorizontalScrollView
|
||||
import android.widget.LinearLayout
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.work.ExistingPeriodicWorkPolicy
|
||||
import androidx.work.OneTimeWorkRequest
|
||||
import androidx.work.PeriodicWorkRequestBuilder
|
||||
import androidx.work.WorkManager
|
||||
import bums.lunatic.launcher.LauncherActivity.Companion.lActivity
|
||||
import bums.lunatic.launcher.apps.AppDrawer
|
||||
import bums.lunatic.launcher.tokiz.Novels
|
||||
import bums.lunatic.launcher.common.CommonActivity
|
||||
import bums.lunatic.launcher.databinding.LauncherActivityBinding
|
||||
import bums.lunatic.launcher.feeds.WidgetHost
|
||||
import bums.lunatic.launcher.helpers.BluetoothManager
|
||||
import bums.lunatic.launcher.helpers.Constants.Companion.KEY_STATUS_BAR
|
||||
import bums.lunatic.launcher.helpers.Constants.Companion.PREFS_SETTINGS
|
||||
import bums.lunatic.launcher.helpers.Constants.Companion.widgetHostId
|
||||
import bums.lunatic.launcher.helpers.ForeGroundService
|
||||
import bums.lunatic.launcher.helpers.HeadsetActionButtonReceiver
|
||||
import bums.lunatic.launcher.helpers.PrefHelper.putString
|
||||
import bums.lunatic.launcher.helpers.PrefLong
|
||||
import bums.lunatic.launcher.home.GeckoWeb
|
||||
import bums.lunatic.launcher.home.RssHome
|
||||
import bums.lunatic.launcher.home.RssViewBuilder
|
||||
import bums.lunatic.launcher.model.RssData
|
||||
import bums.lunatic.launcher.model.RssDataType
|
||||
import bums.lunatic.launcher.receiver.NLService
|
||||
import bums.lunatic.launcher.settings.SettingsActivity
|
||||
import bums.lunatic.launcher.tokiz.Comics
|
||||
import bums.lunatic.launcher.tokiz.Magnet
|
||||
import bums.lunatic.launcher.tokiz.Novels
|
||||
import bums.lunatic.launcher.tokiz.Perplexity
|
||||
import bums.lunatic.launcher.tokiz.Twitter
|
||||
import bums.lunatic.launcher.tokiz.Webtoons
|
||||
import bums.lunatic.launcher.tokiz.Zota
|
||||
import bums.lunatic.launcher.utils.Blog
|
||||
import bums.lunatic.launcher.utils.FeedParseManager
|
||||
import bums.lunatic.launcher.utils.getJ
|
||||
import bums.lunatic.launcher.workers.AppInfoGetter
|
||||
import bums.lunatic.launcher.workers.ArcaGetter
|
||||
import bums.lunatic.launcher.workers.CalendarGetter
|
||||
import bums.lunatic.launcher.workers.ClienGetter
|
||||
import bums.lunatic.launcher.workers.ContactInfoGetter
|
||||
import bums.lunatic.launcher.workers.DCGetter
|
||||
import bums.lunatic.launcher.workers.DotaxGetter
|
||||
import bums.lunatic.launcher.workers.DotaxGetter.Companion.COMIC2_WORK_TAG
|
||||
import bums.lunatic.launcher.workers.FmKoreaGetter
|
||||
import bums.lunatic.launcher.workers.FmKoreaGetter.Companion.FM_WORK_TAG
|
||||
import bums.lunatic.launcher.workers.LocationGetter
|
||||
import bums.lunatic.launcher.workers.NewsFeedsGetter
|
||||
import bums.lunatic.launcher.workers.NewsFeedsGetter.Companion.FEDDS_WORK_TAG
|
||||
import bums.lunatic.launcher.workers.RecentCallGetter
|
||||
import bums.lunatic.launcher.workers.RecentSmsGetter
|
||||
import bums.lunatic.launcher.workers.RecentSmsGetter.Companion.SMS_WORK_TAG
|
||||
import bums.lunatic.launcher.workers.RedditGetter
|
||||
import bums.lunatic.launcher.workers.RedditGetter.Companion.REDDIT_WORK_TAG
|
||||
import bums.lunatic.launcher.workers.RuliWebGetter
|
||||
import bums.lunatic.launcher.workers.TheQooGetter
|
||||
import bums.lunatic.launcher.workers.WorkersDb
|
||||
import bums.lunatic.launcher.workers.YoutubeGetter
|
||||
import bums.lunatic.launcher.workers.YoutubeGetter.Companion.YT_WORK_TAG
|
||||
import com.google.android.material.color.DynamicColors
|
||||
import com.yausername.ffmpeg.FFmpeg
|
||||
import com.yausername.youtubedl_android.YoutubeDL
|
||||
import com.yausername.youtubedl_android.YoutubeDLException
|
||||
import io.realm.kotlin.ext.query
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kr.lunaticbum.utils.ui.DisplayUtil
|
||||
import org.json.JSONObject
|
||||
import org.mozilla.geckoview.ExperimentDelegate
|
||||
import org.mozilla.geckoview.GeckoResult
|
||||
import org.mozilla.geckoview.GeckoRuntime
|
||||
import org.mozilla.geckoview.GeckoRuntimeSettings
|
||||
import java.util.Base64
|
||||
import java.util.Calendar
|
||||
import java.util.Date
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.jvm.java
|
||||
|
||||
|
||||
open class LauncherActivity : CommonActivity() {
|
||||
@ -209,7 +168,8 @@ open class LauncherActivity : CommonActivity() {
|
||||
Blog.LOGE("onConfigurationChanged newConfig?.screenWidthDp >> ${newConfig?.screenWidthDp}")
|
||||
Blog.LOGE("onConfigurationChanged newConfig?.screenHeightDp >> ${newConfig?.screenHeightDp}")
|
||||
isOpendFold = (newConfig.screenWidthDp * 1.1f) > newConfig.screenHeightDp
|
||||
|
||||
val nullCursor = PointerIcon.getSystemIcon(this, PointerIcon.TYPE_NULL)
|
||||
binding.root.setPointerIcon(nullCursor)
|
||||
}
|
||||
// override fun onKeyClick(keyCode: Int): Boolean {
|
||||
// when (keyCode) {
|
||||
@ -533,15 +493,24 @@ open class LauncherActivity : CommonActivity() {
|
||||
@SuppressLint("NewApi", "MissingPermission")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
installSplashScreen()
|
||||
super.onCreate(savedInstanceState)
|
||||
try {
|
||||
YoutubeDL.getInstance().init(this)
|
||||
FFmpeg.getInstance().init(this);
|
||||
} catch (e: YoutubeDLException) {
|
||||
Blog.LOGE("failed to initialize youtubedl-android", e)
|
||||
}
|
||||
val intent = Intent(this, ForeGroundService::class.java)
|
||||
this.startForegroundService(intent)
|
||||
|
||||
val nlService = Intent(this, NLService::class.java)
|
||||
this.startService(nlService)
|
||||
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
|
||||
lActivity = this
|
||||
|
||||
DynamicColors.applyToActivityIfAvailable(this)
|
||||
|
||||
|
||||
settingsPrefs = getSharedPreferences(PREFS_SETTINGS, 0)
|
||||
// AppCompatDelegate.setDefaultNightMode(settingsPrefs.getInt(KEY_APPLICATION_THEME, MODE_NIGHT_FOLLOW_SYSTEM))
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
|
||||
binding = LauncherActivityBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
@ -553,8 +522,8 @@ open class LauncherActivity : CommonActivity() {
|
||||
updateLocationService()
|
||||
|
||||
|
||||
val intent = Intent(this, BluetoothManager::class.java)
|
||||
ContextCompat.startForegroundService(this, intent)
|
||||
|
||||
|
||||
showContents(binding.feeds.id)
|
||||
binding.floatingActionMenu.setOnMenuButtonClickListener { v->
|
||||
Blog.LOGE("v >> ${v}")
|
||||
@ -622,6 +591,10 @@ open class LauncherActivity : CommonActivity() {
|
||||
.replace(R.id.fragment_container, Magnet())
|
||||
.commit()
|
||||
}
|
||||
R.id.setting ->{
|
||||
startActivity(Intent(this, SettingsActivity::class.java))
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
binding.floatingActionMenu.close(false)
|
||||
|
||||
@ -2,9 +2,9 @@ package bums.lunatic.launcher.helpers
|
||||
|
||||
import android.Manifest
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Notification
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.app.Service
|
||||
import android.bluetooth.BluetoothAdapter
|
||||
import android.bluetooth.BluetoothDevice
|
||||
@ -17,12 +17,13 @@ import android.os.Build
|
||||
import android.os.IBinder
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.work.ExistingPeriodicWorkPolicy
|
||||
import androidx.work.PeriodicWorkRequestBuilder
|
||||
import androidx.work.WorkManager
|
||||
import bums.lunatic.launcher.LauncherActivity
|
||||
import bums.lunatic.launcher.LauncherActivity.Companion.lActivity
|
||||
import bums.lunatic.launcher.R
|
||||
import bums.lunatic.launcher.home.GeckoWeb
|
||||
import bums.lunatic.launcher.utils.Blog
|
||||
import bums.lunatic.launcher.workers.ArcaGetter
|
||||
import bums.lunatic.launcher.workers.ClienGetter
|
||||
@ -51,8 +52,11 @@ import okhttp3.ResponseBody
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
|
||||
class BluetoothManager : Service() {
|
||||
|
||||
class ForeGroundService : Service() {
|
||||
companion object {
|
||||
val ACTION_SENDMSG = "ACTION_SEND_TO_LOVE"
|
||||
val EXTRA_MSGKEY = "SEND_MSG"
|
||||
}
|
||||
enum class BLUETOOTH_STATE(val statestr: String) {
|
||||
ENABLED("enabledBlutooth"),
|
||||
DISABLED("disableBlutooth"),
|
||||
@ -67,44 +71,71 @@ class BluetoothManager : Service() {
|
||||
super.onCreate()
|
||||
Blog.LOGE("onCreate")
|
||||
mWorkManager = WorkManager.getInstance(this)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
startForeground(NOTIF_ID, createNotification(this))
|
||||
}
|
||||
val filter = IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED)
|
||||
registerReceiver(bluetoothreceiver, filter)
|
||||
refreshFeeds()
|
||||
// GeckoWeb(applicationContext).apply {
|
||||
// loadUrl("https://arca.live/b/live")
|
||||
// }
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent?): IBinder? {
|
||||
Blog.LOGE("intent >>> ${intent}")
|
||||
return null
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
Blog.LOGE("onStartCommand >>> ${intent}")
|
||||
if (ACTION_SENDMSG.equals(intent?.action)) {
|
||||
intent?.getStringExtra(EXTRA_MSGKEY)?.let {
|
||||
sendToI(it)
|
||||
}
|
||||
}
|
||||
startForeGround()
|
||||
return START_STICKY
|
||||
}
|
||||
private val CHANNEL_ID = "ble_service_channel"
|
||||
private val CHANNEL_NAME = "BLE 서비스"
|
||||
|
||||
fun createNotification(context: Context): Notification {
|
||||
fun startForeGround() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val channel = NotificationChannel(
|
||||
CHANNEL_ID,
|
||||
CHANNEL_NAME,
|
||||
NotificationManager.IMPORTANCE_HIGH // 중요도 낮게 (필요시 변경)
|
||||
"BLE 서비스 채널",
|
||||
NotificationManager.IMPORTANCE_HIGH
|
||||
)
|
||||
val notificationManager =
|
||||
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
notificationManager.createNotificationChannel(channel)
|
||||
val manager = getSystemService(NotificationManager::class.java)
|
||||
manager.createNotificationChannel(channel)
|
||||
}
|
||||
return NotificationCompat.Builder(context, CHANNEL_ID)
|
||||
val intent = Intent(this, LauncherActivity::class.java).apply {
|
||||
flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||
}
|
||||
|
||||
val pendingIntent = PendingIntent.getActivity(
|
||||
this,
|
||||
0,
|
||||
intent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
|
||||
startForeground(NOTIF_ID, NotificationCompat.Builder(this, CHANNEL_ID)
|
||||
.setContentTitle("BLE 서비스")
|
||||
.setContentText("실행중입니다.")
|
||||
.setPriority(NotificationCompat.PRIORITY_MAX)
|
||||
.setSmallIcon(R.drawable.ic_b)
|
||||
.setContentIntent(pendingIntent)
|
||||
.addAction(android.R.drawable.ic_btn_speak_now,"퇴근", makeSendMsgAction(0,"돼지 퇴근했다요~!"))
|
||||
.addAction(android.R.drawable.ic_btn_speak_now,"버스 탐", makeSendMsgAction(1,"돼지 버스 탔다요~!"))
|
||||
.addAction(android.R.drawable.ic_btn_speak_now,"버스 내림", makeSendMsgAction(2,"돼지 버스 내린다요~!"))
|
||||
.setOngoing(true) // 사용자가 알림을 스와이프로 지울 수 없게 만듦
|
||||
.build()
|
||||
.build())
|
||||
}
|
||||
|
||||
fun makeSendMsgAction(code : Int, msg : String) : PendingIntent {
|
||||
val actionIntent = Intent(this, ForeGroundService::class.java).apply {
|
||||
action = ACTION_SENDMSG
|
||||
putExtra(EXTRA_MSGKEY, msg) // 전달할 데이터
|
||||
}
|
||||
return PendingIntent.getService(this, code, actionIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE )
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent?): IBinder? {
|
||||
Blog.LOGE("onBind intent >>> ${intent}")
|
||||
return null
|
||||
}
|
||||
private val CHANNEL_ID = "ble_service_channel"
|
||||
private val CHANNEL_NAME = "BLE 서비스"
|
||||
|
||||
|
||||
//페어링된 디바이스 정보 가져오기
|
||||
fun getPairedDevices() {
|
||||
@ -192,6 +223,14 @@ class BluetoothManager : Service() {
|
||||
PeriodicWorkRequestBuilder<LocationGetter>(PrefLong.locationTimePeriod.get(), TimeUnit.MINUTES)
|
||||
.addTag(LocationGetter.TAG)
|
||||
.build())
|
||||
mWorkManager?.cancelAllWorkByTag(ServiceWatchdogWorker.TAG)
|
||||
mWorkManager?.enqueueUniquePeriodicWork(
|
||||
ServiceWatchdogWorker.TAG,
|
||||
ExistingPeriodicWorkPolicy.REPLACE,
|
||||
PeriodicWorkRequestBuilder<ServiceWatchdogWorker>(15, TimeUnit.MINUTES)
|
||||
.addTag(ServiceWatchdogWorker.TAG)
|
||||
.build())
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -202,6 +241,21 @@ class BluetoothManager : Service() {
|
||||
return mWorkManager
|
||||
}
|
||||
|
||||
fun sendToI(msg: String) {
|
||||
if (PrefString.telegramSendTarget.get().length > 5) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
OkHttpClient.Builder()
|
||||
.connectionPool(ConnectionPool(5, 60, TimeUnit.SECONDS))
|
||||
.build().newCall(Request.Builder().url("https://api.telegram.org/bot7934509464:AAE_xUbICxMdywLGnxo7BkeIqA1nVza4P9w/sendMessage?chat_id=${PrefString.telegramSendTarget.get()}&text=${msg}")
|
||||
.addHeader("Content-Type", "application/json").get().build()).execute()?.let { response ->
|
||||
if (response.isSuccessful()) {
|
||||
val body: ResponseBody? = response.body()
|
||||
if (body != null) { }
|
||||
} else Blog.LOGE("sendToI telegram Error Occurred")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fun sendToI(boolean: Boolean) {
|
||||
if (PrefString.telegramSendTarget.get().length > 5) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
@ -251,6 +305,13 @@ class BluetoothManager : Service() {
|
||||
return BLUETOOTH_STATE.NOT_SUPPORT.statestr
|
||||
}
|
||||
|
||||
override fun stopService(name: Intent?): Boolean {
|
||||
Blog.LOGE("stopService ${name}")
|
||||
val intent = Intent(this, ForeGroundService::class.java)
|
||||
ContextCompat.startForegroundService(this, intent)
|
||||
return super.stopService(name)
|
||||
}
|
||||
|
||||
//add Receive action
|
||||
private fun addFilterAction(): IntentFilter {
|
||||
val stateFilter = IntentFilter()
|
||||
@ -0,0 +1,36 @@
|
||||
package bums.lunatic.launcher.helpers
|
||||
|
||||
import android.app.ActivityManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import androidx.work.Worker
|
||||
import androidx.work.WorkerParameters
|
||||
|
||||
class ServiceWatchdogWorker(
|
||||
private val context: Context,
|
||||
workerParams: WorkerParameters
|
||||
) : Worker(context, workerParams) {
|
||||
|
||||
companion object{
|
||||
val TAG = "ServiceWatchdogWorker"
|
||||
}
|
||||
|
||||
override fun doWork(): Result {
|
||||
val isServiceRunning = isServiceRunning(ForeGroundService::class.java)
|
||||
if (!isServiceRunning) {
|
||||
val intent = Intent(context, ForeGroundService::class.java)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
context.startForegroundService(intent)
|
||||
} else {
|
||||
context.startService(intent)
|
||||
}
|
||||
}
|
||||
return Result.success()
|
||||
}
|
||||
fun isServiceRunning(serviceClass: Class<*>): Boolean {
|
||||
val manager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
|
||||
return manager.getRunningServices(Int.MAX_VALUE)
|
||||
.any { it.service.className == serviceClass.name }
|
||||
}
|
||||
}
|
||||
@ -40,6 +40,7 @@ import androidx.core.net.toUri
|
||||
import androidx.core.view.isVisible
|
||||
import bums.lunatic.launcher.LauncherActivity.Companion.getRuntime
|
||||
import bums.lunatic.launcher.R
|
||||
import bums.lunatic.launcher.model.others.Button
|
||||
import bums.lunatic.launcher.tokiz.data.model.PortMessage
|
||||
import bums.lunatic.launcher.tokiz.view.BWebview
|
||||
import bums.lunatic.launcher.utils.Blog
|
||||
@ -47,6 +48,9 @@ import bums.lunatic.launcher.utils.CommonUtils
|
||||
import bums.lunatic.launcher.workers.WorkersDb
|
||||
import com.google.gson.Gson
|
||||
import com.vladsch.flexmark.html2md.converter.FlexmarkHtmlConverter
|
||||
import com.yausername.youtubedl_android.YoutubeDL
|
||||
import com.yausername.youtubedl_android.YoutubeDLRequest
|
||||
import com.yausername.youtubedl_android.YoutubeDLResponse
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@ -54,6 +58,7 @@ import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import kr.lunaticbum.utils.service.ServiceUtil.getSystemService
|
||||
import kr.lunaticbum.utils.service.ServiceUtil.layoutInflater
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import org.json.JSONException
|
||||
@ -61,6 +66,7 @@ import org.json.JSONObject
|
||||
import org.jsoup.Jsoup
|
||||
import org.jsoup.nodes.Document
|
||||
import org.mozilla.gecko.util.ThreadUtils
|
||||
import org.mozilla.gecko.util.ThreadUtils.runOnUiThread
|
||||
import org.mozilla.geckoview.ExperimentDelegate
|
||||
import org.mozilla.geckoview.GeckoResult
|
||||
import org.mozilla.geckoview.GeckoSession
|
||||
@ -76,6 +82,7 @@ import java.io.FileOutputStream
|
||||
import java.io.InputStream
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.UUID
|
||||
|
||||
class GeckoWeb : BWebview {
|
||||
constructor(context: Context?) : super(context) {
|
||||
@ -84,7 +91,7 @@ class GeckoWeb : BWebview {
|
||||
var decoViews = arrayListOf<View>()
|
||||
override fun setVisibility(visibility: Int) {
|
||||
super.setVisibility(visibility)
|
||||
decoViews.filter { it != null && it.id > -1 }.forEach { it.visibility = visibility }
|
||||
decoViews.filter { it != null && it.id > -1 && it.id != R.id.dl_video }.forEach { it.visibility = visibility }
|
||||
}
|
||||
interface OnSave {
|
||||
fun saved()
|
||||
@ -448,6 +455,153 @@ class GeckoWeb : BWebview {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun checkIfDownloadable(url: String) {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
runOnUiThread {
|
||||
decoViews.filter { it.id == R.id.dl_video }.firstOrNull()?.let {
|
||||
it.setOnClickListener {}
|
||||
it.visibility = View.GONE
|
||||
}}}
|
||||
Blog.LOGE("checkIfDownloadable ${url}")
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
try {
|
||||
val videoInfo = YoutubeDL.getInstance().getInfo(url)
|
||||
// videoInfo 가 null 아니고, 필요한 키(예: title, url 등)가 있으면 다운로드 가능
|
||||
Blog.LOGE("checkIfDownloadable ${url}\n videoInfo : ${videoInfo}")
|
||||
var canVideoDown = videoInfo != null && !videoInfo.title.isNullOrEmpty()
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
runOnUiThread {
|
||||
decoViews.filter { it.id == R.id.dl_video }.firstOrNull()?.let {
|
||||
it.setOnClickListener {
|
||||
videoDlownLoad(url)
|
||||
}
|
||||
it.visibility = if (canVideoDown){View.VISIBLE} else{View.GONE}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
Blog.LOGE("checkIfDownloadable ${url} ${e}")
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
runOnUiThread {
|
||||
decoViews.filter { it.id == R.id.dl_video }.firstOrNull()?.let {
|
||||
it.setOnClickListener {}
|
||||
it.visibility = View.GONE
|
||||
}}}
|
||||
}
|
||||
}
|
||||
}
|
||||
fun replaceDcUrl(origin: String): String {
|
||||
var result = origin
|
||||
for (i in 0..19) {
|
||||
result = result.replace(String.format("dcimg%d.", i), "dcimg2.")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun copyToClipboard(text: String?) {
|
||||
if (text == null) return
|
||||
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
val clip = ClipData.newPlainText("Media URL", text)
|
||||
clipboard.setPrimaryClip(clip)
|
||||
Toast.makeText(context, "주소가 복사되었습니다.", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
|
||||
suspend fun getFormatList(url: String): List<String> = withContext(Dispatchers.IO) {
|
||||
val command = YoutubeDLRequest(lastedUrl!!)
|
||||
command.addOption("--list-formats", url)
|
||||
val output = YoutubeDL.getInstance().execute(command)
|
||||
// output.stdout에 포맷 리스트가 문자열로 들어있음
|
||||
// 줄 단위로 분리 후 리턴
|
||||
Blog.LOGE("output.out >>> ${output.out}")
|
||||
return@withContext output.out.split("\n").filter { it.isNotBlank() }
|
||||
}
|
||||
|
||||
fun showFormatSelectionDialog(formats: List<String>, onFormatSelected: (String) -> Unit) {
|
||||
val builder = AlertDialog.Builder(context)
|
||||
builder.setTitle("포맷 선택")
|
||||
builder.setItems(formats.toTypedArray()) { _, which ->
|
||||
onFormatSelected(formats[which])
|
||||
}
|
||||
builder.setNegativeButton("취소", null)
|
||||
builder.show()
|
||||
}
|
||||
|
||||
|
||||
|
||||
lateinit var progressDialog: AlertDialog
|
||||
fun showProgressDialog() {
|
||||
val dialogView = layoutInflater.inflate(R.layout.progress_dialog, null)
|
||||
val progressBar = dialogView.findViewById<ProgressBar>(R.id.progressBar)
|
||||
val textProgress = dialogView.findViewById<TextView>(R.id.textProgress)
|
||||
val btn = dialogView.findViewById<android.widget.Button>(R.id.dl_cancel)
|
||||
progressDialog = AlertDialog.Builder(context)
|
||||
.setTitle("다운로드 중...")
|
||||
.setView(dialogView)
|
||||
.setCancelable(false)
|
||||
.create()
|
||||
progressDialog.show()
|
||||
|
||||
// UI 업데이트 함수 예 (나중에 실행)
|
||||
fun updateProgress(progress: Int, est : Long, str : String) {
|
||||
runOnUiThread {
|
||||
progressBar.progress = progress
|
||||
textProgress.text = "$progress%"
|
||||
}
|
||||
}
|
||||
}
|
||||
fun dismissProgressDialog() {
|
||||
progressDialog.dismiss()
|
||||
}
|
||||
|
||||
suspend fun downloadVideo(processId : String,url: String, updateProgress: (Float, Long, String) -> Unit) = withContext(Dispatchers.IO) {
|
||||
val youtubeDLDir = File(
|
||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
|
||||
"youtubedl-android"
|
||||
)
|
||||
val command = YoutubeDLRequest(url)
|
||||
command.addOption("-o", youtubeDLDir.getAbsolutePath() + "/%(title)s.%(ext)s");
|
||||
var process = YoutubeDL.getInstance().execute(command,processId) { progress, est , str ->
|
||||
updateProgress(progress, est, str)
|
||||
}
|
||||
return@withContext process
|
||||
}
|
||||
|
||||
fun videoDlownLoad(videoUrl : String) {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
try {
|
||||
showProgressDialog()
|
||||
var res: YoutubeDLResponse? = null
|
||||
val processId = UUID.randomUUID().toString()
|
||||
res = downloadVideo(processId, videoUrl) { progress , time , str->
|
||||
runOnUiThread {
|
||||
val pb =
|
||||
progressDialog.findViewById<ProgressBar>(R.id.progressBar)
|
||||
val tv =
|
||||
progressDialog.findViewById<TextView>(R.id.textProgress)
|
||||
pb?.progress = progress.toInt()
|
||||
val btn = progressDialog.findViewById<android.widget.Button>(R.id.dl_cancel)
|
||||
tv?.text = "$progress%\n$str"
|
||||
btn?.setOnClickListener {
|
||||
progressDialog?.dismiss()
|
||||
YoutubeDL.getInstance().destroyProcessById(processId);
|
||||
}
|
||||
}
|
||||
}
|
||||
dismissProgressDialog()
|
||||
Toast.makeText(context, "다운로드 완료", Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
progressDialog?.dismiss()
|
||||
Toast.makeText(context, "오류: ${e.message}", Toast.LENGTH_LONG)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var dialog : Dialog? = null
|
||||
fun getFilterF() = String(java.util.Base64.getMimeDecoder().decode("aHR0cHM6Ly9pamF2dG9ycmVudC5jb20=".toByteArray()))
|
||||
var currentTitle = ""
|
||||
@ -474,21 +628,7 @@ class GeckoWeb : BWebview {
|
||||
|
||||
super.onFirstContentfulPaint(session)
|
||||
}
|
||||
fun replaceDcUrl(origin: String): String {
|
||||
var result = origin
|
||||
for (i in 0..19) {
|
||||
result = result.replace(String.format("dcimg%d.", i), "dcimg2.")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun copyToClipboard(text: String?) {
|
||||
if (text == null) return
|
||||
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
val clip = ClipData.newPlainText("Media URL", text)
|
||||
clipboard.setPrimaryClip(clip)
|
||||
Toast.makeText(context, "주소가 복사되었습니다.", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
override fun onExternalResponse(session: GeckoSession, response: WebResponse) {
|
||||
Blog.LOGE("response >>> ${response.uri} ")
|
||||
@ -504,6 +644,7 @@ class GeckoWeb : BWebview {
|
||||
val client = OkHttpClient()
|
||||
val request = Request.Builder()
|
||||
.url(url)
|
||||
.addHeader("Referer", lastedUrl)
|
||||
.addHeader("User-Agent", "Mozilla/5.0")
|
||||
// 필요시 Referer, 쿠키 등 헤더 추가
|
||||
.build()
|
||||
@ -531,6 +672,7 @@ class GeckoWeb : BWebview {
|
||||
super.onExternalResponse(session, response)
|
||||
}
|
||||
|
||||
|
||||
override fun onContextMenu(
|
||||
session: GeckoSession,
|
||||
screenX: Int,
|
||||
@ -539,18 +681,11 @@ class GeckoWeb : BWebview {
|
||||
) {
|
||||
|
||||
if (element.baseUri?.contains("youtube") == true) {
|
||||
copyToClipboard(lastedUrl)
|
||||
loadUrl("https://ko.savefrom.net/227lt/#url=${lastedUrl}")
|
||||
// copyToClipboard(lastedUrl)
|
||||
// Dialog(context)?.let { dialog ->
|
||||
// val popupWebView = GeckoWeb(context).apply {
|
||||
// loadUrl(lastedUrl!!.replace("https://","https://ss"))
|
||||
// this.dialog = dialog
|
||||
// }
|
||||
// dialog.setCanceledOnTouchOutside(true)
|
||||
// dialog.setContentView(popupWebView)
|
||||
// dialog.show()
|
||||
// }
|
||||
lastedUrl?.let { videoUrl ->
|
||||
lastedUrl?.let {
|
||||
videoDlownLoad(it)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Blog.LOGE("onContextMenu:: x = ${x}, y = ${y} , element = ${Gson().toJson(element)}")
|
||||
if (element.type == GeckoSession.ContentDelegate.ContextElement.TYPE_IMAGE) {
|
||||
@ -723,6 +858,7 @@ class GeckoWeb : BWebview {
|
||||
} else {
|
||||
lastedUrl = url
|
||||
}
|
||||
checkIfDownloadable(url)
|
||||
}
|
||||
|
||||
|
||||
@ -735,6 +871,8 @@ class GeckoWeb : BWebview {
|
||||
it.tag = currentTitle
|
||||
it.text = url
|
||||
}
|
||||
}else if (it.id == R.id.reload) {
|
||||
it.setOnClickListener { session.reload() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -625,6 +625,8 @@ internal class RssHome : Fragment() {
|
||||
(activity as? LauncherActivity)?.let { activity ->
|
||||
binding.geckoWeb.decoViews.add(activity.findViewById<TextView>(R.id.current_address))
|
||||
binding.geckoWeb.decoViews.add(activity.findViewById<ImageButton>(R.id.back))
|
||||
binding.geckoWeb.decoViews.add(activity.findViewById<ImageButton>(R.id.reload))
|
||||
binding.geckoWeb.decoViews.add(activity.findViewById<ImageButton>(R.id.dl_video))
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package bums.lunatic.launcher.receiver
|
||||
|
||||
import android.app.Notification
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
@ -13,9 +14,11 @@ import android.service.notification.NotificationListenerService
|
||||
import android.service.notification.StatusBarNotification
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.content.getSystemService
|
||||
import bums.lunatic.launcher.helpers.ForeGroundService
|
||||
import bums.lunatic.launcher.model.CurrentPlayItem
|
||||
import bums.lunatic.launcher.model.NotificationItem
|
||||
import bums.lunatic.launcher.utils.BitmapConverter
|
||||
import bums.lunatic.launcher.utils.Blog
|
||||
import bums.lunatic.launcher.workers.WorkersDb
|
||||
import io.realm.kotlin.UpdatePolicy
|
||||
import io.realm.kotlin.ext.query
|
||||
@ -29,7 +32,6 @@ class NLService : NotificationListenerService() {
|
||||
super.onCreate()
|
||||
nlservicereciver = NLServiceReceiver()
|
||||
val filter = IntentFilter()
|
||||
// filter.addAction("com.kpbird.nlsexample.NOTIFICATION_LISTENER_SERVICE_EXAMPLE")
|
||||
registerReceiver(nlservicereciver, filter)
|
||||
}
|
||||
|
||||
@ -38,130 +40,54 @@ class NLService : NotificationListenerService() {
|
||||
unregisterReceiver(nlservicereciver)
|
||||
}
|
||||
|
||||
val skips = arrayListOf("com.wssyncmldm")
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.S)
|
||||
override fun onNotificationPosted(sbn: StatusBarNotification) {
|
||||
// BLog.LOGE("NLService********** onNotificationPosted")
|
||||
// BLog.LOGE("NLServiceID :" + sbn.id + "\t${sbn.notification.tickerText}\t" + sbn.packageName)
|
||||
// sbn.notification.extras.keySet().forEach {
|
||||
// BLog.LOGE("NLService********** keySet >> ${it} ${sbn.notification.extras.get(it)}")
|
||||
// }
|
||||
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}"
|
||||
// BLog.LOGE("NLService********** enqueue TelegramBotGetter ${true == "bumssavor".equals(title)}")
|
||||
// BLog.LOGE("NLService********** enqueue TelegramBotGetter ${(true == "org.telegram.messenger".equals(pkgName))}")
|
||||
// BLog.LOGE("NLService********** enqueue TelegramBotGetter ${sbn.notification?.extras?.getString("android.text")?.startsWith("/") == true}")
|
||||
}.apply {
|
||||
if (skips.contains(pkgName)) {
|
||||
|
||||
} else {
|
||||
// WorkersDb.insertNoti(this)
|
||||
// BLog.LOGE("NLService********** onNotificationPosted ${Gson().toJson(this)}")
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e : Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
Blog.LOGE("onNotificationPosted ${sbn}")
|
||||
val notification = sbn.notification
|
||||
val extras = notification.extras
|
||||
when (sbn.packageName){
|
||||
"com.kakao.talk" -> {
|
||||
|
||||
|
||||
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}")
|
||||
if (session.playbackState != null) {
|
||||
if (session.playbackState?.isActive == true && session.playbackState?.state?.equals(
|
||||
STATE_PLAYING
|
||||
) == true
|
||||
) {
|
||||
session.playbackState?.state
|
||||
val result = query<CurrentPlayItem>().find()
|
||||
var current: CurrentPlayItem? = null
|
||||
if (result.size > 0) {
|
||||
current = result.first()
|
||||
} else {
|
||||
current = CurrentPlayItem()
|
||||
copyToRealm(current, UpdatePolicy.ALL)
|
||||
}
|
||||
if (session?.metadata?.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ART) == true) {
|
||||
current.albumArt = BitmapConverter.BitmapToString(
|
||||
session.metadata?.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART)
|
||||
)
|
||||
} else {
|
||||
current.albumArt = ""
|
||||
}
|
||||
current.title =
|
||||
session?.metadata?.getString(MediaMetadata.METADATA_KEY_TITLE)
|
||||
current.artists =
|
||||
session?.metadata?.getString(MediaMetadata.METADATA_KEY_ARTIST)
|
||||
} else {
|
||||
delete(query<CurrentPlayItem>().find())
|
||||
}
|
||||
}
|
||||
}
|
||||
val title = extras.getString(Notification.EXTRA_TITLE) ?: ""
|
||||
val text = extras.getCharSequence(Notification.EXTRA_TEXT)?.toString() ?: ""
|
||||
val bigText = extras.getCharSequence(Notification.EXTRA_BIG_TEXT)?.toString() ?: ""
|
||||
val extraInfo = extras.getCharSequence(Notification.EXTRA_INFO_TEXT)?.toString() ?: ""
|
||||
val subText = extras.getCharSequence(Notification.EXTRA_SUB_TEXT)?.toString() ?: ""
|
||||
val conversationTitle = extras.getCharSequence(Notification.EXTRA_CONVERSATION_TITLE)?.toString() ?: ""
|
||||
val summaryText = extras.getCharSequence(Notification.EXTRA_SUMMARY_TEXT)?.toString() ?: ""
|
||||
val verificationText = extras.getCharSequence(Notification.EXTRA_VERIFICATION_TEXT)?.toString() ?: ""
|
||||
|
||||
Blog.LOGE("title >> ${title} text >> ${text} bigText >> ${bigText} extraInfo >> ${extraInfo} subText >> ${subText} conversationTitle >> ${conversationTitle} summaryText >> ${summaryText} verificationText >> ${verificationText}")
|
||||
|
||||
}
|
||||
}}catch (e : Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
// val i = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
|
||||
// i.putExtra("notification_event", "onNotificationPosted :" + sbn.packageName + "\n")
|
||||
// sendBroadcast(i)
|
||||
}
|
||||
|
||||
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("onNotificationPosted ${sbn}")
|
||||
if (sbn.packageName == "bums.lunatic.launcher" && sbn.id == 830721) {
|
||||
// 포그라운드 알림이 사라짐 감지
|
||||
Blog.LOGE("NotificationListener", "포그라운드 알림 제거 감지")
|
||||
|
||||
// 서비스 재시작 시도
|
||||
val intent = Intent(this, ForeGroundService::class.java)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
startForegroundService(intent)
|
||||
} else {
|
||||
startService(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal inner class NLServiceReceiver : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, intent: Intent) {
|
||||
// BLog.LOGE("NLService intent >>> ${intent.action}")
|
||||
if (intent.getStringExtra("command") == "clearall") {
|
||||
this@NLService.cancelAllNotifications()
|
||||
} else if (intent.getStringExtra("command") == "list") {
|
||||
// val i1 = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
|
||||
// i1.putExtra("notification_event", "=====================")
|
||||
// sendBroadcast(i1)
|
||||
var i = 1
|
||||
for (sbn in this@NLService.activeNotifications) {
|
||||
// BLog.LOGE("NLService sbn >>> ${sbn.packageName} , ${Gson().toJson(sbn.notification.extras.keySet())}")
|
||||
// val i2 = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
|
||||
// i2.putExtra("notification_event", i.toString() + " " + sbn.packageName + "\n")
|
||||
// sendBroadcast(i2)
|
||||
// i++
|
||||
}
|
||||
// val i3 = Intent("com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE")
|
||||
// i3.putExtra("notification_event", "===== Notification List ====")
|
||||
// sendBroadcast(i3)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
package bums.lunatic.launcher.view
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.GestureDetector
|
||||
import android.view.MotionEvent
|
||||
import android.view.ScaleGestureDetector
|
||||
import androidx.appcompat.widget.AppCompatImageView
|
||||
class ZoomImageView(context: Context, attrs: AttributeSet) : AppCompatImageView(context, attrs),
|
||||
ScaleGestureDetector.OnScaleGestureListener, GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener {
|
||||
|
||||
private var scaleFactor = 1.0f
|
||||
private val scaleGestureDetector = ScaleGestureDetector(context, this)
|
||||
private val gestureDetector = GestureDetector(context, this)
|
||||
|
||||
override fun onTouchEvent(event: MotionEvent): Boolean {
|
||||
scaleGestureDetector.onTouchEvent(event)
|
||||
gestureDetector.onTouchEvent(event)
|
||||
return true
|
||||
}
|
||||
|
||||
// ScaleGestureDetector callbacks
|
||||
override fun onScale(detector: ScaleGestureDetector): Boolean {
|
||||
scaleFactor *= detector.scaleFactor
|
||||
scaleFactor = scaleFactor.coerceIn(1.0f, 4.0f)
|
||||
scaleX = scaleFactor
|
||||
scaleY = scaleFactor
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onScaleBegin(detector: ScaleGestureDetector) = true
|
||||
override fun onScaleEnd(detector: ScaleGestureDetector) {}
|
||||
|
||||
// GestureDetector callbacks (클릭, 터치 등)
|
||||
override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
|
||||
performClick() // 클릭 이벤트 발생
|
||||
return true
|
||||
}
|
||||
|
||||
override fun performClick(): Boolean {
|
||||
super.performClick()
|
||||
// 추가로 클릭 시 동작할 코드 넣기
|
||||
if (hasOnClickListeners()) {
|
||||
callOnClick()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onDown(e: MotionEvent) = true
|
||||
override fun onShowPress(e: MotionEvent) {}
|
||||
override fun onSingleTapUp(e: MotionEvent) = true
|
||||
override fun onScroll(e1: MotionEvent?, e2: MotionEvent, distanceX: Float, distanceY: Float) = false
|
||||
override fun onLongPress(e: MotionEvent) {}
|
||||
override fun onFling(e1: MotionEvent?, e2: MotionEvent, velocityX: Float, velocityY: Float) = false
|
||||
override fun onDoubleTap(e: MotionEvent) = true
|
||||
override fun onDoubleTapEvent(e: MotionEvent) = true
|
||||
}
|
||||
BIN
app/src/main/res/drawable/dl_vid.png
Normal file
BIN
app/src/main/res/drawable/dl_vid.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 530 B |
@ -36,12 +36,27 @@
|
||||
android:layout_width="40dp"
|
||||
tools:ignore="ContentDescription"
|
||||
android:layout_height="40dp" />
|
||||
<ImageButton
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/fragment_container"
|
||||
app:layout_constraintLeft_toRightOf="@id/back"
|
||||
android:id="@+id/reload"
|
||||
android:scaleType="fitCenter"
|
||||
android:adjustViewBounds="true"
|
||||
android:visibility="visible"
|
||||
android:background="@null"
|
||||
android:src="@drawable/ic_refresh"
|
||||
android:tint="@color/white"
|
||||
android:foregroundTint="@color/white"
|
||||
android:layout_width="40dp"
|
||||
tools:ignore="ContentDescription"
|
||||
android:layout_height="40dp" />
|
||||
<TextView
|
||||
android:text="asdasdsadasd"
|
||||
android:id="@+id/current_address"
|
||||
app:layout_constraintTop_toTopOf="@id/back"
|
||||
app:layout_constraintRight_toLeftOf="@id/share"
|
||||
app:layout_constraintLeft_toRightOf="@id/back"
|
||||
app:layout_constraintRight_toLeftOf="@id/dl_video"
|
||||
app:layout_constraintLeft_toRightOf="@id/reload"
|
||||
android:textColor="@color/white"
|
||||
android:gravity="center"
|
||||
android:textSize="@dimen/_12sp"
|
||||
@ -49,6 +64,21 @@
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="40dp"/>
|
||||
<ImageButton
|
||||
app:layout_constraintTop_toTopOf="@id/back"
|
||||
app:layout_constraintRight_toLeftOf="@id/share"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:id="@+id/dl_video"
|
||||
android:scaleType="fitCenter"
|
||||
android:adjustViewBounds="true"
|
||||
android:visibility="gone"
|
||||
android:background="@null"
|
||||
android:tint="@color/white"
|
||||
android:foregroundTint="@color/white"
|
||||
android:src="@drawable/dl_vid"
|
||||
android:layout_width="40dp"
|
||||
tools:ignore="ContentDescription"
|
||||
android:layout_height="40dp" />
|
||||
<ImageButton
|
||||
app:layout_constraintTop_toTopOf="@id/back"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
@ -140,5 +170,13 @@
|
||||
android:onClick="floatClick"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="20dp"/>
|
||||
<bums.lunatic.launcher.view.FloatingActionButton
|
||||
app:fab_label="setting"
|
||||
android:id="@+id/setting"
|
||||
app:fab_showShadow="true"
|
||||
app:fab_size="mini"
|
||||
android:onClick="floatClick"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="20dp"/>
|
||||
</bums.lunatic.launcher.view.FloatingActionMenu>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@ -49,7 +49,7 @@
|
||||
android:textColor="@color/white"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
<ImageView
|
||||
<bums.lunatic.launcher.view.ZoomImageView
|
||||
app:layout_constraintTop_toBottomOf="@id/date"
|
||||
android:alpha="0.05"
|
||||
android:adjustViewBounds="true"
|
||||
@ -78,7 +78,7 @@
|
||||
android:textColor="@color/white"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
<ImageView
|
||||
<bums.lunatic.launcher.view.ZoomImageView
|
||||
app:layout_constraintTop_toBottomOf="@id/desc"
|
||||
android:id="@+id/screen"
|
||||
android:alpha="0.05"
|
||||
|
||||
29
app/src/main/res/layout/progress_dialog.xml
Normal file
29
app/src/main/res/layout/progress_dialog.xml
Normal file
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:padding="24dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
style="@android:style/Widget.ProgressBar.Horizontal"
|
||||
android:layout_width="250dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:max="100"
|
||||
android:progress="0" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textProgress"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:text="0%" />
|
||||
<Button
|
||||
android:text="다운로드 취소"
|
||||
android:gravity="center"
|
||||
android:id="@+id/dl_cancel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
Loading…
x
Reference in New Issue
Block a user