....
This commit is contained in:
parent
53ba35a3de
commit
4acc01b742
@ -901,5 +901,5 @@ function autoScrollAndHandleDotax() {
|
|||||||
//
|
//
|
||||||
// // 시작
|
// // 시작
|
||||||
// scrollAndSend();
|
// scrollAndSend();
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
@ -76,16 +76,21 @@ import bums.lunatic.launcher.tokiz.Novels
|
|||||||
import bums.lunatic.launcher.tokiz.Perplexity
|
import bums.lunatic.launcher.tokiz.Perplexity
|
||||||
import bums.lunatic.launcher.tokiz.Twitter
|
import bums.lunatic.launcher.tokiz.Twitter
|
||||||
import bums.lunatic.launcher.tokiz.Webtoons
|
import bums.lunatic.launcher.tokiz.Webtoons
|
||||||
|
import bums.lunatic.launcher.tokiz.YouTube
|
||||||
import bums.lunatic.launcher.tokiz.Zota
|
import bums.lunatic.launcher.tokiz.Zota
|
||||||
import bums.lunatic.launcher.utils.Blog
|
import bums.lunatic.launcher.utils.Blog
|
||||||
|
import bums.lunatic.launcher.utils.KakaoPublicTransfer
|
||||||
import bums.lunatic.launcher.workers.WorkersDb
|
import bums.lunatic.launcher.workers.WorkersDb
|
||||||
|
import com.google.android.gms.common.util.DataUtils
|
||||||
import com.google.android.material.color.DynamicColors
|
import com.google.android.material.color.DynamicColors
|
||||||
|
import com.google.gson.Gson
|
||||||
import com.yausername.ffmpeg.FFmpeg
|
import com.yausername.ffmpeg.FFmpeg
|
||||||
import com.yausername.youtubedl_android.YoutubeDL
|
import com.yausername.youtubedl_android.YoutubeDL
|
||||||
import com.yausername.youtubedl_android.YoutubeDLException
|
import com.yausername.youtubedl_android.YoutubeDLException
|
||||||
import io.realm.kotlin.ext.query
|
import io.realm.kotlin.ext.query
|
||||||
import kr.lunaticbum.utils.ui.DisplayUtil
|
import kr.lunaticbum.utils.ui.DisplayUtil
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
import org.jsoup.helper.DataUtil
|
||||||
import org.mozilla.geckoview.ExperimentDelegate
|
import org.mozilla.geckoview.ExperimentDelegate
|
||||||
import org.mozilla.geckoview.GeckoResult
|
import org.mozilla.geckoview.GeckoResult
|
||||||
import org.mozilla.geckoview.GeckoRuntime
|
import org.mozilla.geckoview.GeckoRuntime
|
||||||
@ -465,6 +470,7 @@ open class LauncherActivity : CommonActivity() {
|
|||||||
} catch (e: YoutubeDLException) {
|
} catch (e: YoutubeDLException) {
|
||||||
Blog.LOGE("failed to initialize youtubedl-android", e)
|
Blog.LOGE("failed to initialize youtubedl-android", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
val intent = Intent(this, ForeGroundService::class.java)
|
val intent = Intent(this, ForeGroundService::class.java)
|
||||||
this.startForegroundService(intent)
|
this.startForegroundService(intent)
|
||||||
|
|
||||||
@ -536,6 +542,11 @@ open class LauncherActivity : CommonActivity() {
|
|||||||
.replace(R.id.fragment_container, Comics())
|
.replace(R.id.fragment_container, Comics())
|
||||||
.commit()
|
.commit()
|
||||||
}
|
}
|
||||||
|
R.id.youtube ->{
|
||||||
|
supportFragmentManager.beginTransaction()
|
||||||
|
.replace(R.id.fragment_container, YouTube())
|
||||||
|
.commit()
|
||||||
|
}
|
||||||
R.id.perplexity ->{
|
R.id.perplexity ->{
|
||||||
supportFragmentManager.beginTransaction()
|
supportFragmentManager.beginTransaction()
|
||||||
.replace(R.id.fragment_container, Perplexity())
|
.replace(R.id.fragment_container, Perplexity())
|
||||||
@ -679,6 +690,9 @@ open class LauncherActivity : CommonActivity() {
|
|||||||
currentFragment.doNextPage()
|
currentFragment.doNextPage()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
is YouTube -> {
|
||||||
|
currentFragment.back()
|
||||||
|
}
|
||||||
is Novels -> {
|
is Novels -> {
|
||||||
currentFragment.actionNextEvent(false)
|
currentFragment.actionNextEvent(false)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,7 +13,9 @@ import android.content.Context
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import android.os.Environment
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
@ -41,6 +43,8 @@ import bums.lunatic.launcher.workers.RuliWebGetter
|
|||||||
import bums.lunatic.launcher.workers.TheQooGetter
|
import bums.lunatic.launcher.workers.TheQooGetter
|
||||||
import bums.lunatic.launcher.workers.YoutubeGetter
|
import bums.lunatic.launcher.workers.YoutubeGetter
|
||||||
import bums.lunatic.launcher.workers.YoutubeGetter.Companion.YT_WORK_TAG
|
import bums.lunatic.launcher.workers.YoutubeGetter.Companion.YT_WORK_TAG
|
||||||
|
import com.yausername.youtubedl_android.YoutubeDL
|
||||||
|
import com.yausername.youtubedl_android.YoutubeDLRequest
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -49,6 +53,8 @@ import okhttp3.OkHttpClient
|
|||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import okhttp3.ResponseBody
|
import okhttp3.ResponseBody
|
||||||
|
import java.io.File
|
||||||
|
import java.util.UUID
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
|
||||||
@ -56,7 +62,12 @@ class ForeGroundService : Service() {
|
|||||||
companion object {
|
companion object {
|
||||||
val ACTION_SENDMSG = "ACTION_SEND_TO_LOVE"
|
val ACTION_SENDMSG = "ACTION_SEND_TO_LOVE"
|
||||||
val EXTRA_MSGKEY = "SEND_MSG"
|
val EXTRA_MSGKEY = "SEND_MSG"
|
||||||
|
|
||||||
|
val ACTION_VIDEO_DOWNLOAD = "ACTION_YTURL_DOWNLOAD"
|
||||||
|
val EXTRA_TARGET_URL = "ACTION_SEND_TO_LOVE"
|
||||||
|
val targetUrls = arrayListOf<String>()
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class BLUETOOTH_STATE(val statestr: String) {
|
enum class BLUETOOTH_STATE(val statestr: String) {
|
||||||
ENABLED("enabledBlutooth"),
|
ENABLED("enabledBlutooth"),
|
||||||
DISABLED("disableBlutooth"),
|
DISABLED("disableBlutooth"),
|
||||||
@ -78,20 +89,80 @@ class ForeGroundService : Service() {
|
|||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
Blog.LOGE("onStartCommand >>> ${intent}")
|
Blog.LOGE("onStartCommand >>> ${intent}")
|
||||||
if (ACTION_SENDMSG.equals(intent?.action)) {
|
when(intent?.action) {
|
||||||
|
ACTION_SENDMSG -> {
|
||||||
intent?.getStringExtra(EXTRA_MSGKEY)?.let {
|
intent?.getStringExtra(EXTRA_MSGKEY)?.let {
|
||||||
sendToI(it)
|
sendToI(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ACTION_VIDEO_DOWNLOAD -> {
|
||||||
|
intent?.getStringExtra(EXTRA_TARGET_URL)?.let {
|
||||||
|
Uri.parse(it)?.let {
|
||||||
|
addToTargetYtubeUrl(it.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
startForeGround()
|
startForeGround()
|
||||||
return START_STICKY
|
return START_STICKY
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startForeGround() {
|
fun addToTargetYtubeUrl(url : String) {
|
||||||
|
targetUrls.add(url)
|
||||||
|
if((targetUrls?.size ?: 0) > 0) {
|
||||||
|
downloadVideo(targetUrls?.firstOrNull())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentProcessId : String? = null
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
if (value == null) {
|
||||||
|
startForeGround(0,0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun downloadVideo(url: String?) {
|
||||||
|
url?.let {
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
val youtubeDLDir = File(
|
||||||
|
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
|
||||||
|
"youtubedl-android"
|
||||||
|
)
|
||||||
|
val command = YoutubeDLRequest(url)
|
||||||
|
command.addOption("-o", youtubeDLDir.getAbsolutePath() + "/%(title)s.%(ext)s");
|
||||||
|
currentProcessId = UUID.randomUUID().toString()
|
||||||
|
YoutubeDL.getInstance()
|
||||||
|
.execute(command, currentProcessId) { progress, est, str ->
|
||||||
|
startForeGround(100, progress.toInt(),str)
|
||||||
|
if (progress >= 100) {
|
||||||
|
targetUrls.remove(url)
|
||||||
|
currentProcessId = null
|
||||||
|
if((targetUrls?.size ?: 0) > 0) {
|
||||||
|
downloadVideo(targetUrls?.firstOrNull())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
currentProcessId = null
|
||||||
|
if((targetUrls?.size ?: 0) > 0) {
|
||||||
|
downloadVideo(targetUrls?.firstOrNull())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun startForeGround(max : Int = 0 , progress : Int = 0, str : String = "실행중입니다.") {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
val channel = NotificationChannel(
|
val channel = NotificationChannel(
|
||||||
CHANNEL_ID,
|
CHANNEL_ID,
|
||||||
"BLE 서비스 채널",
|
"BUM'S 서비스",
|
||||||
NotificationManager.IMPORTANCE_HIGH
|
NotificationManager.IMPORTANCE_HIGH
|
||||||
)
|
)
|
||||||
val manager = getSystemService(NotificationManager::class.java)
|
val manager = getSystemService(NotificationManager::class.java)
|
||||||
@ -110,7 +181,7 @@ class ForeGroundService : Service() {
|
|||||||
|
|
||||||
startForeground(NOTIF_ID, NotificationCompat.Builder(this, CHANNEL_ID)
|
startForeground(NOTIF_ID, NotificationCompat.Builder(this, CHANNEL_ID)
|
||||||
.setContentTitle("BLE 서비스")
|
.setContentTitle("BLE 서비스")
|
||||||
.setContentText("실행중입니다.")
|
.setContentText(str)
|
||||||
.setPriority(NotificationCompat.PRIORITY_MAX)
|
.setPriority(NotificationCompat.PRIORITY_MAX)
|
||||||
.setSmallIcon(R.drawable.ic_b)
|
.setSmallIcon(R.drawable.ic_b)
|
||||||
.setContentIntent(pendingIntent)
|
.setContentIntent(pendingIntent)
|
||||||
@ -118,6 +189,7 @@ class ForeGroundService : Service() {
|
|||||||
.addAction(android.R.drawable.ic_btn_speak_now,"버스 탐", makeSendMsgAction(1,"돼지 버스 탔다요~!"))
|
.addAction(android.R.drawable.ic_btn_speak_now,"버스 탐", makeSendMsgAction(1,"돼지 버스 탔다요~!"))
|
||||||
.addAction(android.R.drawable.ic_btn_speak_now,"버스 내림", makeSendMsgAction(2,"돼지 버스 내린다요~!"))
|
.addAction(android.R.drawable.ic_btn_speak_now,"버스 내림", makeSendMsgAction(2,"돼지 버스 내린다요~!"))
|
||||||
.setOngoing(true) // 사용자가 알림을 스와이프로 지울 수 없게 만듦
|
.setOngoing(true) // 사용자가 알림을 스와이프로 지울 수 없게 만듦
|
||||||
|
.setProgress(max, progress, false)
|
||||||
.build())
|
.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,6 +313,8 @@ class ForeGroundService : Service() {
|
|||||||
return mWorkManager
|
return mWorkManager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun sendToI(msg: String) {
|
fun sendToI(msg: String) {
|
||||||
if (PrefString.telegramSendTarget.get().length > 5) {
|
if (PrefString.telegramSendTarget.get().length > 5) {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
@ -256,6 +330,8 @@ class ForeGroundService : Service() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun sendToI(boolean: Boolean) {
|
fun sendToI(boolean: Boolean) {
|
||||||
if (PrefString.telegramSendTarget.get().length > 5) {
|
if (PrefString.telegramSendTarget.get().length > 5) {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
@ -280,6 +356,8 @@ class ForeGroundService : Service() {
|
|||||||
} else Blog.LOGE("sendToI telegram Error Occurred")
|
} else Blog.LOGE("sendToI telegram Error Occurred")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@SuppressLint("MissingPermission")
|
@SuppressLint("MissingPermission")
|
||||||
fun isConnected(device: BluetoothDevice): Boolean {
|
fun isConnected(device: BluetoothDevice): Boolean {
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import android.content.Intent
|
|||||||
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP
|
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||||
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import android.os.Build
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
@ -41,6 +42,11 @@ import androidx.core.view.isVisible
|
|||||||
import androidx.work.Worker
|
import androidx.work.Worker
|
||||||
import bums.lunatic.launcher.LauncherActivity.Companion.getRuntime
|
import bums.lunatic.launcher.LauncherActivity.Companion.getRuntime
|
||||||
import bums.lunatic.launcher.R
|
import bums.lunatic.launcher.R
|
||||||
|
import bums.lunatic.launcher.helpers.ForeGroundService
|
||||||
|
import bums.lunatic.launcher.helpers.ForeGroundService.Companion.ACTION_SENDMSG
|
||||||
|
import bums.lunatic.launcher.helpers.ForeGroundService.Companion.ACTION_VIDEO_DOWNLOAD
|
||||||
|
import bums.lunatic.launcher.helpers.ForeGroundService.Companion.EXTRA_MSGKEY
|
||||||
|
import bums.lunatic.launcher.helpers.ForeGroundService.Companion.EXTRA_TARGET_URL
|
||||||
import bums.lunatic.launcher.model.Dotax
|
import bums.lunatic.launcher.model.Dotax
|
||||||
import bums.lunatic.launcher.model.DotaxArticles
|
import bums.lunatic.launcher.model.DotaxArticles
|
||||||
import bums.lunatic.launcher.model.getRssData
|
import bums.lunatic.launcher.model.getRssData
|
||||||
@ -93,7 +99,6 @@ class GeckoWeb : BWebview {
|
|||||||
constructor(context: Context?) : super(context) {
|
constructor(context: Context?) : super(context) {
|
||||||
buildWeb()
|
buildWeb()
|
||||||
}
|
}
|
||||||
var decoViews = arrayListOf<View>()
|
|
||||||
override fun setVisibility(visibility: Int) {
|
override fun setVisibility(visibility: Int) {
|
||||||
super.setVisibility(visibility)
|
super.setVisibility(visibility)
|
||||||
decoViews.filter { it != null && it.id > -1 && it.id != R.id.dl_video }.forEach { it.visibility = visibility }
|
decoViews.filter { it != null && it.id > -1 && it.id != R.id.dl_video }.forEach { it.visibility = visibility }
|
||||||
@ -124,38 +129,7 @@ class GeckoWeb : BWebview {
|
|||||||
session.mediaDelegate = mediaDelegate
|
session.mediaDelegate = mediaDelegate
|
||||||
session.promptDelegate = promptDelegate
|
session.promptDelegate = promptDelegate
|
||||||
session.mediaSessionDelegate = mediaSessionDelegate
|
session.mediaSessionDelegate = mediaSessionDelegate
|
||||||
// session.permissionDelegate = (object : PermissionDelegate {
|
|
||||||
// override fun onContentPermissionRequest(
|
|
||||||
// session: GeckoSession,
|
|
||||||
// perm: PermissionDelegate.ContentPermission
|
|
||||||
// ): GeckoResult<Int?>? {
|
|
||||||
//
|
|
||||||
// return super.onContentPermissionRequest(session, perm)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// override fun onAndroidPermissionsRequest(
|
|
||||||
// session: GeckoSession,
|
|
||||||
// permissions: Array<out String?>?,
|
|
||||||
// callback: PermissionDelegate.Callback
|
|
||||||
// ) {
|
|
||||||
// super.onAndroidPermissionsRequest(session, permissions, callback)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// override fun onMediaPermissionRequest(
|
|
||||||
// session: GeckoSession,
|
|
||||||
// uri: String,
|
|
||||||
// video: Array<out PermissionDelegate.MediaSource?>?,
|
|
||||||
// audio: Array<out PermissionDelegate.MediaSource?>?,
|
|
||||||
// callback: PermissionDelegate.MediaCallback
|
|
||||||
// ) {
|
|
||||||
//
|
|
||||||
// // 첫 번째 비디오·오디오 소스를 허용
|
|
||||||
//
|
|
||||||
// callback.grant(video?.firstOrNull(), audio?.firstOrNull())
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// });
|
|
||||||
it.webExtensionController
|
it.webExtensionController
|
||||||
.ensureBuiltIn(extPath, extId)
|
.ensureBuiltIn(extPath, extId)
|
||||||
.accept( // Register message delegate for background script
|
.accept( // Register message delegate for background script
|
||||||
@ -420,109 +394,6 @@ class GeckoWeb : BWebview {
|
|||||||
mOnSave?.saved()
|
mOnSave?.saved()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun downloadImage(context: Context, url: Uri, isGif : Boolean = false) {
|
|
||||||
Blog.LOGE("url.lastPathSegment ${url.lastPathSegment}")
|
|
||||||
val fileName = url.host + "_${SimpleDateFormat("yyyyMMddHHmmsss").format(Date())}.${if(isGif){"gif"}else{"jpg"}}"
|
|
||||||
val request = DownloadManager.Request(url)
|
|
||||||
request.setTitle(fileName)
|
|
||||||
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI or DownloadManager.Request.NETWORK_MOBILE)
|
|
||||||
request.setDescription("이미지 다운로드 중...")
|
|
||||||
request.setAllowedOverMetered(true) // 선택 사항 - 데이터 요금제 네트워크에서도 허용
|
|
||||||
request.setVisibleInDownloadsUi(true)
|
|
||||||
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName)
|
|
||||||
// 네트워크타입, 알림설정 등 옵션 추가 가능
|
|
||||||
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
|
|
||||||
|
|
||||||
val dm = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
|
|
||||||
|
|
||||||
Toast.makeText(context, "다운로드 시작: $fileName", Toast.LENGTH_SHORT).show()
|
|
||||||
val downloadId = dm.enqueue(request)
|
|
||||||
monitorDownloadStatus(dm, downloadId, context)
|
|
||||||
}
|
|
||||||
fun monitorDownloadStatus(dm: DownloadManager, downloadId: Long, context: Context) {
|
|
||||||
val handler = CoroutineExceptionHandler { _, exception ->
|
|
||||||
// 에러 처리 로직 (선택)
|
|
||||||
exception.printStackTrace()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 백그라운드에서 5초 간격으로 상태 체크
|
|
||||||
CoroutineScope(Dispatchers.IO + handler).launch {
|
|
||||||
while (true) {
|
|
||||||
val query = DownloadManager.Query().setFilterById(downloadId)
|
|
||||||
val cursor = dm.query(query)
|
|
||||||
var downloadFinished = false
|
|
||||||
|
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
|
||||||
val status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
|
|
||||||
when (status) {
|
|
||||||
DownloadManager.STATUS_SUCCESSFUL -> {
|
|
||||||
// 다운로드 성공 처리
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
// UI 갱신 등 메인 스레드 작업 (필요 시)
|
|
||||||
}
|
|
||||||
downloadFinished = true
|
|
||||||
}
|
|
||||||
DownloadManager.STATUS_FAILED -> {
|
|
||||||
val reason = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_REASON))
|
|
||||||
// 여기에 reason값에 따라 적절한 처리 또는 로깅 수행
|
|
||||||
Log.e("DownloadManager", "Download failed with reason code: $reason")
|
|
||||||
// 다운로드 실패 처리
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
// UI 갱신 등 메인 스레드 작업 (필요 시)
|
|
||||||
}
|
|
||||||
downloadFinished = true
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
Blog.LOGE("DownloadManager.STATUS >> ${status}")
|
|
||||||
}
|
|
||||||
// 진행 중, 대기 중 등 기타 상태는 계속 확인
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cursor?.close()
|
|
||||||
|
|
||||||
if (downloadFinished) break
|
|
||||||
|
|
||||||
delay(5000L) // 5초 대기 후 다시 반복
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
fun replaceDcUrl(origin: String): String {
|
||||||
var result = origin
|
var result = origin
|
||||||
for (i in 0..19) {
|
for (i in 0..19) {
|
||||||
@ -562,76 +433,6 @@ class GeckoWeb : BWebview {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
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
|
var dialog : Dialog? = null
|
||||||
fun getFilterF() = String(java.util.Base64.getMimeDecoder().decode("aHR0cHM6Ly9pamF2dG9ycmVudC5jb20=".toByteArray()))
|
fun getFilterF() = String(java.util.Base64.getMimeDecoder().decode("aHR0cHM6Ly9pamF2dG9ycmVudC5jb20=".toByteArray()))
|
||||||
@ -890,8 +691,6 @@ class GeckoWeb : BWebview {
|
|||||||
lastedUrl = url
|
lastedUrl = url
|
||||||
}
|
}
|
||||||
checkIfDownloadable(url)
|
checkIfDownloadable(url)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -281,6 +281,7 @@ internal class RssHome : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun searchKeyword() {
|
fun searchKeyword() {
|
||||||
|
binding.geckoWeb.visibility = View.GONE
|
||||||
// val builder: AlertDialog.Builder = AlertDialog.Builder(requireContext())
|
// val builder: AlertDialog.Builder = AlertDialog.Builder(requireContext())
|
||||||
// builder.setTitle("Keyword")
|
// builder.setTitle("Keyword")
|
||||||
// val viewInflated: View = LayoutInflater.from(requireContext())
|
// val viewInflated: View = LayoutInflater.from(requireContext())
|
||||||
@ -327,6 +328,7 @@ internal class RssHome : Fragment() {
|
|||||||
|
|
||||||
|
|
||||||
fun ask() {
|
fun ask() {
|
||||||
|
binding.geckoWeb.visibility = View.GONE
|
||||||
val bottomSheet = WebBottomSheet()
|
val bottomSheet = WebBottomSheet()
|
||||||
bottomSheet.listener = object : WebBottomSheet.OnGoToWebListener{
|
bottomSheet.listener = object : WebBottomSheet.OnGoToWebListener{
|
||||||
override fun enterSearch() {
|
override fun enterSearch() {
|
||||||
|
|||||||
@ -54,7 +54,7 @@ class SearchBottomSheet : BottomSheetDialogFragment() {
|
|||||||
val categoryContainer = view.findViewById<LinearLayout>(R.id.categoryContainer)
|
val categoryContainer = view.findViewById<LinearLayout>(R.id.categoryContainer)
|
||||||
addVote = view.findViewById<CheckBox>(R.id.add_vote) as CheckBox
|
addVote = view.findViewById<CheckBox>(R.id.add_vote) as CheckBox
|
||||||
addRead = view.findViewById<CheckBox>(R.id.add_read) as CheckBox
|
addRead = view.findViewById<CheckBox>(R.id.add_read) as CheckBox
|
||||||
addRead.setOnCheckedChangeListener {v,b->triggerSearchWithDebounce(inputKeyword.text.toString())}
|
addVote.setOnCheckedChangeListener {v,b->triggerSearchWithDebounce(inputKeyword.text.toString())}
|
||||||
addRead.setOnCheckedChangeListener {v,b->triggerSearchWithDebounce(inputKeyword.text.toString())}
|
addRead.setOnCheckedChangeListener {v,b->triggerSearchWithDebounce(inputKeyword.text.toString())}
|
||||||
// 카테고리 목록
|
// 카테고리 목록
|
||||||
val categories = RssDataType.getAll()
|
val categories = RssDataType.getAll()
|
||||||
@ -66,6 +66,7 @@ class SearchBottomSheet : BottomSheetDialogFragment() {
|
|||||||
text = category.name
|
text = category.name
|
||||||
tag = category
|
tag = category
|
||||||
isAllCaps = false
|
isAllCaps = false
|
||||||
|
this.isSelected = true
|
||||||
setBackgroundResource(android.R.drawable.btn_default)
|
setBackgroundResource(android.R.drawable.btn_default)
|
||||||
setTextColor(Color.WHITE)
|
setTextColor(Color.WHITE)
|
||||||
setBackgroundResource(R.color.tabs_black)
|
setBackgroundResource(R.color.tabs_black)
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package bums.lunatic.launcher.receiver
|
package bums.lunatic.launcher.receiver
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.app.Notification
|
import android.app.Notification
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
@ -30,6 +31,7 @@ import bums.lunatic.launcher.model.LocationLog
|
|||||||
import bums.lunatic.launcher.model.NotificationItem
|
import bums.lunatic.launcher.model.NotificationItem
|
||||||
import bums.lunatic.launcher.utils.BitmapConverter
|
import bums.lunatic.launcher.utils.BitmapConverter
|
||||||
import bums.lunatic.launcher.utils.Blog
|
import bums.lunatic.launcher.utils.Blog
|
||||||
|
import bums.lunatic.launcher.utils.KakaoPublicTransfer
|
||||||
import bums.lunatic.launcher.workers.LocationUpdateService.Companion.inRangeLocation
|
import bums.lunatic.launcher.workers.LocationUpdateService.Companion.inRangeLocation
|
||||||
import bums.lunatic.launcher.workers.WorkersDb
|
import bums.lunatic.launcher.workers.WorkersDb
|
||||||
import com.google.android.gms.location.LocationServices
|
import com.google.android.gms.location.LocationServices
|
||||||
@ -70,6 +72,7 @@ class NLService : NotificationListenerService() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressLint("MissingPermission")
|
||||||
@RequiresApi(Build.VERSION_CODES.S)
|
@RequiresApi(Build.VERSION_CODES.S)
|
||||||
override fun onNotificationPosted(sbn: StatusBarNotification) {
|
override fun onNotificationPosted(sbn: StatusBarNotification) {
|
||||||
Blog.LOGE("onNotificationPosted ${sbn}")
|
Blog.LOGE("onNotificationPosted ${sbn}")
|
||||||
@ -95,25 +98,51 @@ class NLService : NotificationListenerService() {
|
|||||||
Blog.LOGE("title >> ${title} text >> ${text} bigText >> ${bigText} extraInfo >> ${extraInfo} subText >> ${subText} conversationTitle >> ${conversationTitle} summaryText >> ${summaryText} verificationText >> ${verificationText}")
|
Blog.LOGE("title >> ${title} text >> ${text} bigText >> ${bigText} extraInfo >> ${extraInfo} subText >> ${subText} conversationTitle >> ${conversationTitle} summaryText >> ${summaryText} verificationText >> ${verificationText}")
|
||||||
mHourlyLogWriter?.writeLog("${sbn.packageName}\n${stringBuffer.toString()}")
|
mHourlyLogWriter?.writeLog("${sbn.packageName}\n${stringBuffer.toString()}")
|
||||||
when (sbn.packageName){
|
when (sbn.packageName){
|
||||||
"com.kakao.talk" -> {
|
"com.kakao.taxi" -> {
|
||||||
|
var defaultMsg : StringBuffer? = StringBuffer("돼지 택시 ")
|
||||||
|
if (stringBuffer.contains("택시") && stringBuffer.contains("탑승") && stringBuffer.contains("완료")) {
|
||||||
|
defaultMsg?.append("탔다요~!")
|
||||||
|
}else if(stringBuffer.contains("택시") && stringBuffer.contains("자동결제") && stringBuffer.contains("물건")) {
|
||||||
|
defaultMsg?.append("거의 다 왔다요~!")
|
||||||
|
}else if(stringBuffer.contains("택시") && stringBuffer.contains("도착") && stringBuffer.contains("선택")) {
|
||||||
|
defaultMsg?.append("내린다요~!")
|
||||||
|
} else {
|
||||||
|
defaultMsg = null
|
||||||
}
|
}
|
||||||
"kakaopay.app" -> {
|
defaultMsg?.let {
|
||||||
if (stringBuffer.contains("모바일") && stringBuffer.contains("교통카드")) {
|
makeMsgByTransferInfomation(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"com.kakao.talk" -> {
|
||||||
|
if (stringBuffer.contains("카카오페이") && stringBuffer.contains("모바일") && stringBuffer.contains("교통카드") && stringBuffer.contains("사용 내역")) {
|
||||||
var usePublicTransportation = PrefBoolean.usePublicTransportation.get(false)
|
var usePublicTransportation = PrefBoolean.usePublicTransportation.get(false)
|
||||||
PrefBoolean.usePublicTransportation.set(!usePublicTransportation)
|
PrefBoolean.usePublicTransportation.set(!usePublicTransportation)
|
||||||
|
var defaultMsg = StringBuffer("돼지가 대중교통에${if (!usePublicTransportation){" 탑승 "} else {"서 하차"}} 했다요~!")
|
||||||
|
KakaoPublicTransfer(stringBuffer.toString()).let {
|
||||||
|
defaultMsg.append("\n${it.transportType}(${it.transportName})")
|
||||||
|
defaultMsg.append("\n${it.dateTime}")
|
||||||
|
}
|
||||||
|
makeMsgByTransferInfomation(defaultMsg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"kakaopay.app" -> {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresPermission(allOf = [Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION])
|
||||||
|
fun makeMsgByTransferInfomation(stringBuffer : StringBuffer) {
|
||||||
val actionIntent = Intent(this, ForeGroundService::class.java).apply {
|
val actionIntent = Intent(this, ForeGroundService::class.java).apply {
|
||||||
action = ACTION_SENDMSG
|
action = ACTION_SENDMSG
|
||||||
putExtra(EXTRA_MSGKEY, "돼지가 대중교통에${if (!usePublicTransportation){" 탑승 "} else {"서 하차"}} 했다요~!") // 전달할 데이터
|
putExtra(EXTRA_MSGKEY, stringBuffer.toString()) // 전달할 데이터
|
||||||
}
|
}
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
startForegroundService(actionIntent)
|
startForegroundService(actionIntent)
|
||||||
} else {
|
} else {
|
||||||
startService(actionIntent)
|
startService(actionIntent)
|
||||||
}
|
}
|
||||||
}
|
pushLocation(this)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresPermission(allOf = [Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION])
|
@RequiresPermission(allOf = [Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION])
|
||||||
|
|||||||
@ -28,12 +28,14 @@ import android.webkit.WebView
|
|||||||
import android.webkit.WebViewClient
|
import android.webkit.WebViewClient
|
||||||
import android.widget.ArrayAdapter
|
import android.widget.ArrayAdapter
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
|
import android.widget.ImageButton
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
import bums.lunatic.launcher.LauncherActivity
|
||||||
import bums.lunatic.launcher.LauncherActivity.Companion.getRuntime
|
import bums.lunatic.launcher.LauncherActivity.Companion.getRuntime
|
||||||
import bums.lunatic.launcher.R
|
import bums.lunatic.launcher.R
|
||||||
import bums.lunatic.launcher.tokiz.common.PairArray
|
import bums.lunatic.launcher.tokiz.common.PairArray
|
||||||
@ -404,6 +406,21 @@ abstract class BaseToki : Fragment(), PagedTextViewInterface {
|
|||||||
} else {
|
} else {
|
||||||
lastedUrl = url
|
lastedUrl = url
|
||||||
}
|
}
|
||||||
|
binding.menuWeb.checkIfDownloadable(url)
|
||||||
|
binding.menuWeb.decoViews.filter { it != null && it.id > -1 }.forEach {
|
||||||
|
if (it != null && it.id > -1) {
|
||||||
|
if (it.id == R.id.back) {
|
||||||
|
it.setOnClickListener { session.goBack() }
|
||||||
|
} else if (it.id == R.id.current_address) {
|
||||||
|
(it as? TextView)?.let {
|
||||||
|
it.tag = currentTitle
|
||||||
|
it.text = url
|
||||||
|
}
|
||||||
|
}else if (it.id == R.id.reload) {
|
||||||
|
it.setOnClickListener { session.reload() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
completePageLoad(LastInfo().apply {
|
completePageLoad(LastInfo().apply {
|
||||||
this.pageUrl = url?.toUri()?.path ?: getLastedDoamin() ?: ""
|
this.pageUrl = url?.toUri()?.path ?: getLastedDoamin() ?: ""
|
||||||
@ -635,6 +652,15 @@ abstract class BaseToki : Fragment(), PagedTextViewInterface {
|
|||||||
}
|
}
|
||||||
val nullCursor = PointerIcon.getSystemIcon(context!!, PointerIcon.TYPE_NULL)
|
val nullCursor = PointerIcon.getSystemIcon(context!!, PointerIcon.TYPE_NULL)
|
||||||
binding.root.setPointerIcon(nullCursor)
|
binding.root.setPointerIcon(nullCursor)
|
||||||
|
|
||||||
|
|
||||||
|
binding.menuWeb
|
||||||
|
(activity as? LauncherActivity)?.let { activity ->
|
||||||
|
binding.menuWeb.decoViews.add(activity.findViewById<TextView>(R.id.current_address))
|
||||||
|
binding.menuWeb.decoViews.add(activity.findViewById<ImageButton>(R.id.back))
|
||||||
|
binding.menuWeb.decoViews.add(activity.findViewById<ImageButton>(R.id.reload))
|
||||||
|
binding.menuWeb.decoViews.add(activity.findViewById<ImageButton>(R.id.dl_video))
|
||||||
|
}
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1500,6 +1526,8 @@ abstract class BaseToki : Fragment(), PagedTextViewInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
open fun back() {
|
||||||
|
// binding.menuWeb.session?.goBack()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
60
app/src/main/kotlin/bums/lunatic/launcher/tokiz/YouTube.kt
Normal file
60
app/src/main/kotlin/bums/lunatic/launcher/tokiz/YouTube.kt
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import bums.lunatic.launcher.tokiz.common.TouchArea
|
||||||
|
import bums.lunatic.launcher.tokiz.view.PagedTextViewInterface
|
||||||
|
|
||||||
|
class YouTube : BaseToki(){
|
||||||
|
override val contentsType = "youtube"
|
||||||
|
override var lastNumber : Int = 143
|
||||||
|
override val webcontentsName : String = "youtube"
|
||||||
|
override val afterDot = "com"
|
||||||
|
override fun getLastedDoamin(): String {
|
||||||
|
return String.format("https://%s.%s", webcontentsName, afterDot)
|
||||||
|
}
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
super.onCreateView(inflater, container, savedInstanceState)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
loadLastInfo()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun back() {
|
||||||
|
binding.menuWeb.session?.goBack()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTouch(touchArea: TouchArea) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTimeoverTouch() {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSwipeLeft(touchCount: Int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSwipeRight(touchCount: Int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSwipeDown(touchCount: Int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSwipeUp(touchCount: Int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onLongClick() {
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,15 +2,25 @@ package bums.lunatic.launcher.tokiz.view
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import android.view.PointerIcon
|
import android.view.PointerIcon
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
|
import bums.lunatic.launcher.R
|
||||||
|
import bums.lunatic.launcher.helpers.ForeGroundService
|
||||||
|
import bums.lunatic.launcher.helpers.ForeGroundService.Companion.ACTION_VIDEO_DOWNLOAD
|
||||||
|
import bums.lunatic.launcher.helpers.ForeGroundService.Companion.EXTRA_TARGET_URL
|
||||||
import bums.lunatic.launcher.tokiz.common.TouchArea
|
import bums.lunatic.launcher.tokiz.common.TouchArea
|
||||||
import bums.lunatic.launcher.utils.Blog
|
import bums.lunatic.launcher.utils.Blog
|
||||||
import bums.lunatic.launcher.utils.SimpleFingerGestures
|
import bums.lunatic.launcher.utils.SimpleFingerGestures
|
||||||
|
import com.yausername.youtubedl_android.YoutubeDL
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import org.mozilla.gecko.util.ThreadUtils.runOnUiThread
|
||||||
import org.mozilla.geckoview.GeckoView
|
import org.mozilla.geckoview.GeckoView
|
||||||
import java.util.Base64
|
import java.util.Base64
|
||||||
|
|
||||||
@ -23,6 +33,7 @@ enum class JxEvent {
|
|||||||
}
|
}
|
||||||
typealias JxInteface = (JxEvent)->Unit
|
typealias JxInteface = (JxEvent)->Unit
|
||||||
open class BWebview : GeckoView {
|
open class BWebview : GeckoView {
|
||||||
|
var decoViews = arrayListOf<View>()
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
constructor(context: Context?) : super(context) {
|
constructor(context: Context?) : super(context) {
|
||||||
this.setOnTouchListener { v, event ->
|
this.setOnTouchListener { v, event ->
|
||||||
@ -57,8 +68,53 @@ open class BWebview : GeckoView {
|
|||||||
this.setPointerIcon(nullCursor)
|
this.setPointerIcon(nullCursor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fun videoDlownLoad(videoUrl : String) {
|
||||||
|
val actionIntent = Intent(context, ForeGroundService::class.java).apply {
|
||||||
|
action = ACTION_VIDEO_DOWNLOAD
|
||||||
|
putExtra(EXTRA_TARGET_URL, videoUrl) // 전달할 데이터
|
||||||
|
}
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
context.startForegroundService(actionIntent)
|
||||||
|
} else {
|
||||||
|
context.startService(actionIntent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
val mSimpleFingerGestures = SimpleFingerGestures(omfgl = object : SimpleFingerGestures.OnFingerGestureListener{
|
val mSimpleFingerGestures = SimpleFingerGestures(omfgl = object : SimpleFingerGestures.OnFingerGestureListener{
|
||||||
|
|
||||||
override fun onSwipeUp(
|
override fun onSwipeUp(
|
||||||
|
|||||||
@ -8,6 +8,27 @@ import android.provider.ContactsContract.PhoneLookup
|
|||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
|
data class KakaoPayTransitHistory(
|
||||||
|
val dateTime: String,
|
||||||
|
val transportType: String,
|
||||||
|
val transportName: String,
|
||||||
|
val balance: Int
|
||||||
|
)
|
||||||
|
|
||||||
|
fun KakaoPublicTransfer(raw : String) : KakaoPayTransitHistory {
|
||||||
|
val dateTimeRegex = Regex("""사용일시\s*:\s*([^\n]+)""")
|
||||||
|
val transportTypeRegex = Regex("""이용수단\s*:\s*([^\n]+)""")
|
||||||
|
val transportNameRegex = Regex("""이용수단명\s*:\s*([^\n]+)""")
|
||||||
|
val balanceRegex = Regex("""잔액\s*:\s*([\d,]+)""")
|
||||||
|
|
||||||
|
val dateTime = dateTimeRegex.find(raw)?.groups?.get(1)?.value?.trim() ?: ""
|
||||||
|
val transportType = transportTypeRegex.find(raw)?.groups?.get(1)?.value?.trim() ?: ""
|
||||||
|
val transportName = transportNameRegex.find(raw)?.groups?.get(1)?.value?.trim() ?: ""
|
||||||
|
val balance = balanceRegex.find(raw)?.groups?.get(1)?.value?.replace(",", "")?.toInt() ?: 0
|
||||||
|
|
||||||
|
return KakaoPayTransitHistory(dateTime, transportType, transportName, balance)
|
||||||
|
}
|
||||||
|
|
||||||
fun afterDay(date: Long): Long {
|
fun afterDay(date: Long): Long {
|
||||||
val cal: Calendar = Calendar.getInstance()
|
val cal: Calendar = Calendar.getInstance()
|
||||||
cal.setTime(Date(date))
|
cal.setTime(Date(date))
|
||||||
|
|||||||
@ -33,9 +33,9 @@
|
|||||||
android:src="@drawable/back_vector"
|
android:src="@drawable/back_vector"
|
||||||
android:tint="@color/white"
|
android:tint="@color/white"
|
||||||
android:foregroundTint="@color/white"
|
android:foregroundTint="@color/white"
|
||||||
android:layout_width="40dp"
|
android:layout_width="@dimen/main_top_height"
|
||||||
tools:ignore="ContentDescription"
|
tools:ignore="ContentDescription"
|
||||||
android:layout_height="40dp" />
|
android:layout_height="@dimen/main_top_height" />
|
||||||
<ImageButton
|
<ImageButton
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/fragment_container"
|
app:layout_constraintTop_toBottomOf="@id/fragment_container"
|
||||||
@ -48,9 +48,9 @@
|
|||||||
android:src="@drawable/ic_refresh"
|
android:src="@drawable/ic_refresh"
|
||||||
android:tint="@color/white"
|
android:tint="@color/white"
|
||||||
android:foregroundTint="@color/white"
|
android:foregroundTint="@color/white"
|
||||||
android:layout_width="40dp"
|
android:layout_width="@dimen/main_top_height"
|
||||||
tools:ignore="ContentDescription"
|
tools:ignore="ContentDescription"
|
||||||
android:layout_height="40dp" />
|
android:layout_height="@dimen/main_top_height" />
|
||||||
<TextView
|
<TextView
|
||||||
android:text="asdasdsadasd"
|
android:text="asdasdsadasd"
|
||||||
android:id="@+id/current_address"
|
android:id="@+id/current_address"
|
||||||
@ -63,7 +63,8 @@
|
|||||||
android:ellipsize="middle"
|
android:ellipsize="middle"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="40dp"/>
|
android:layout_height="@dimen/main_top_height"/>
|
||||||
|
"/>
|
||||||
<ImageButton
|
<ImageButton
|
||||||
app:layout_constraintTop_toTopOf="@id/back"
|
app:layout_constraintTop_toTopOf="@id/back"
|
||||||
app:layout_constraintRight_toLeftOf="@id/share"
|
app:layout_constraintRight_toLeftOf="@id/share"
|
||||||
@ -76,9 +77,9 @@
|
|||||||
android:tint="@color/white"
|
android:tint="@color/white"
|
||||||
android:foregroundTint="@color/white"
|
android:foregroundTint="@color/white"
|
||||||
android:src="@drawable/dl_vid"
|
android:src="@drawable/dl_vid"
|
||||||
android:layout_width="40dp"
|
android:layout_width="@dimen/main_top_height"
|
||||||
tools:ignore="ContentDescription"
|
tools:ignore="ContentDescription"
|
||||||
android:layout_height="40dp" />
|
android:layout_height="@dimen/main_top_height" />
|
||||||
<ImageButton
|
<ImageButton
|
||||||
app:layout_constraintTop_toTopOf="@id/back"
|
app:layout_constraintTop_toTopOf="@id/back"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
@ -92,9 +93,9 @@
|
|||||||
android:tint="@color/white"
|
android:tint="@color/white"
|
||||||
android:foregroundTint="@color/white"
|
android:foregroundTint="@color/white"
|
||||||
android:src="@drawable/ic_share"
|
android:src="@drawable/ic_share"
|
||||||
android:layout_width="40dp"
|
android:layout_width="@dimen/main_top_height"
|
||||||
tools:ignore="ContentDescription"
|
tools:ignore="ContentDescription"
|
||||||
android:layout_height="40dp" />
|
android:layout_height="@dimen/main_top_height" />
|
||||||
<bums.lunatic.launcher.view.FloatingActionMenu
|
<bums.lunatic.launcher.view.FloatingActionMenu
|
||||||
android:id="@+id/floating_action_menu"
|
android:id="@+id/floating_action_menu"
|
||||||
android:layout_margin="5dp"
|
android:layout_margin="5dp"
|
||||||
@ -138,6 +139,14 @@
|
|||||||
android:onClick="floatClick"
|
android:onClick="floatClick"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="20dp"/>
|
android:layout_height="20dp"/>
|
||||||
|
<bums.lunatic.launcher.view.FloatingActionButton
|
||||||
|
app:fab_label="youtube"
|
||||||
|
android:id="@+id/youtube"
|
||||||
|
app:fab_showShadow="true"
|
||||||
|
app:fab_size="mini"
|
||||||
|
android:onClick="floatClick"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="20dp"/>
|
||||||
<bums.lunatic.launcher.view.FloatingActionButton
|
<bums.lunatic.launcher.view.FloatingActionButton
|
||||||
app:fab_label="perplexity"
|
app:fab_label="perplexity"
|
||||||
android:id="@+id/perplexity"
|
android:id="@+id/perplexity"
|
||||||
|
|||||||
@ -33,9 +33,9 @@
|
|||||||
android:visibility="visible"
|
android:visibility="visible"
|
||||||
android:background="@null"
|
android:background="@null"
|
||||||
android:src="@drawable/saved"
|
android:src="@drawable/saved"
|
||||||
android:layout_width="40dp"
|
android:layout_width="@dimen/main_top_height"
|
||||||
tools:ignore="ContentDescription"
|
tools:ignore="ContentDescription"
|
||||||
android:layout_height="40dp" />
|
android:layout_height="@dimen/main_top_height" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/hide"
|
android:id="@+id/hide"
|
||||||
@ -46,11 +46,11 @@
|
|||||||
android:layout_marginLeft="12dp"
|
android:layout_marginLeft="12dp"
|
||||||
android:scaleType="fitCenter"
|
android:scaleType="fitCenter"
|
||||||
android:background="@null"
|
android:background="@null"
|
||||||
android:layout_width="40dp"
|
android:layout_width="@dimen/main_top_height"
|
||||||
android:visibility="visible"
|
android:visibility="visible"
|
||||||
android:adjustViewBounds="true"
|
android:adjustViewBounds="true"
|
||||||
tools:ignore="ContentDescription"
|
tools:ignore="ContentDescription"
|
||||||
android:layout_height="40dp"
|
android:layout_height="@dimen/main_top_height"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
@ -62,9 +62,9 @@
|
|||||||
android:tintMode="multiply"
|
android:tintMode="multiply"
|
||||||
android:scaleType="fitCenter"
|
android:scaleType="fitCenter"
|
||||||
android:background="@null"
|
android:background="@null"
|
||||||
android:layout_width="40dp"
|
android:layout_width="@dimen/main_top_height"
|
||||||
android:adjustViewBounds="true"
|
android:adjustViewBounds="true"
|
||||||
android:layout_height="40dp"
|
android:layout_height="@dimen/main_top_height"
|
||||||
app:tint="@color/white"
|
app:tint="@color/white"
|
||||||
tools:ignore="ContentDescription" />
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
@ -75,10 +75,10 @@
|
|||||||
android:src="@drawable/bookmark"
|
android:src="@drawable/bookmark"
|
||||||
android:scaleType="fitCenter"
|
android:scaleType="fitCenter"
|
||||||
android:background="@null"
|
android:background="@null"
|
||||||
android:layout_width="40dp"
|
android:layout_width="@dimen/main_top_height"
|
||||||
android:adjustViewBounds="true"
|
android:adjustViewBounds="true"
|
||||||
tools:ignore="ContentDescription"
|
tools:ignore="ContentDescription"
|
||||||
android:layout_height="40dp"/>
|
android:layout_height="@dimen/main_top_height"/>
|
||||||
|
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user