일단 저장

This commit is contained in:
lunaticbum 2026-01-13 18:04:06 +09:00
parent df69d779d9
commit 175165184d
4 changed files with 451 additions and 118 deletions

View File

@ -99,6 +99,8 @@
android:screenOrientation="userPortrait"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|screenLayout|layoutDirection|navigation"
android:windowSoftInputMode="adjustResize"
android:noHistory="true"
android:excludeFromRecents="true"
android:exported="false">
<intent-filter>
@ -118,7 +120,9 @@
<activity
android:name=".LauncherActivity"
android:theme="@style/Theme.LunarLauncher.Starting"
android:launchMode="singleTop"
android:launchMode="singleInstance"
android:clearTaskOnLaunch="true"
android:stateNotNeeded="true"
android:screenOrientation="userPortrait"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|screenLayout|layoutDirection|navigation"
android:windowSoftInputMode="adjustResize"

View File

@ -7,6 +7,7 @@ import android.app.SearchManager
import android.appwidget.AppWidgetHost
import android.appwidget.AppWidgetHostView
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProviderInfo
import android.content.Context
import android.content.Intent
import android.content.res.Configuration
@ -184,7 +185,10 @@ open class LauncherActivity : CommonActivity() {
}
fun onSwipeRight() {
startActivity(Intent(this, NeoRssActivity::class.java))
startActivity(Intent(this, NeoRssActivity::class.java).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP)
})
}
private lateinit var binding: LauncherActivityBinding
@ -231,45 +235,51 @@ open class LauncherActivity : CommonActivity() {
override fun onNewIntent(intent: Intent) {
Blog.LOGE("onNewIntent intent >> ${intent}")
if(intent?.action?.equals(Intent.ACTION_SEND) == true &&
intent?.hasExtra(Intent.EXTRA_TEXT) == true) {
intent?.getStringExtra(Intent.EXTRA_TEXT)?.let {
if(it.startsWith("http") == false) {
it.split("http").forEach { string ->
if(string.startsWith("http")) {
try {
string.toUri()?.let { uri ->
Blog.LOGE("onNewIntent string uri.lastPathSegment >>>>> ${uri.host}")
Blog.LOGE("onNewIntent string uri.lastPathSegment >>>>> ${uri.lastPathSegment}")
}
} catch (e: Exception) {
// if(intent?.action?.equals(Intent.ACTION_SEND) == true &&
// intent?.hasExtra(Intent.EXTRA_TEXT) == true) {
// intent?.getStringExtra(Intent.EXTRA_TEXT)?.let {
// if(it.startsWith("http") == false) {
// it.split("http").forEach { string ->
// if(string.startsWith("http")) {
// try {
// string.toUri()?.let { uri ->
// Blog.LOGE("onNewIntent string uri.lastPathSegment >>>>> ${uri.host}")
// Blog.LOGE("onNewIntent string uri.lastPathSegment >>>>> ${uri.lastPathSegment}")
// }
// } catch (e: Exception) {
//
// }
// }
// }
// } else {
// try {
// it.toUri()?.let { uri ->
// Blog.LOGE("onNewIntent it uri.lastPathSegment >>>>> ${uri.host}")
// Blog.LOGE("onNewIntent it uri.lastPathSegment >>>>> ${uri.lastPathSegment}")
// }
// } catch (e: Exception) {
//
// }
// }
// }
// } else if (intent?.action == Intent.ACTION_WEB_SEARCH) {
// openWithIntent(intent)
// } else {
}
}
}
} else {
try {
it.toUri()?.let { uri ->
Blog.LOGE("onNewIntent it uri.lastPathSegment >>>>> ${uri.host}")
Blog.LOGE("onNewIntent it uri.lastPathSegment >>>>> ${uri.lastPathSegment}")
}
} catch (e: Exception) {
// Blog.LOGE("onNewIntent intent?.hasExtra >> ${intent?.hasExtra(Intent.EXTRA_STREAM)}")
//&& intent.hasExtra("android.intent.extra.EXTRA_START_REASON") && intent.getStringExtra(
// "android.intent.extra.EXTRA_START_REASON"
// ).equals("startDockOrHome")
// )
}
}
try {
val fragment = supportFragmentManager.findFragmentByTag(AppDrawerBottomSheet.TAG)
Blog.LOGE("fragment >>> $fragment")
if (fragment is AppDrawerBottomSheet) {
fragment.dismiss()
}
} else if (intent?.action == Intent.ACTION_WEB_SEARCH) {
openWithIntent(intent)
} else {
Blog.LOGE("onNewIntent intent?.hasExtra >> ${intent?.hasExtra(Intent.EXTRA_STREAM)}")
if (intent?.action?.equals(Intent.ACTION_MAIN) == true && intent.categories.contains(
Intent.CATEGORY_HOME
) && intent.hasExtra("android.intent.extra.EXTRA_START_REASON") && intent.getStringExtra(
"android.intent.extra.EXTRA_START_REASON"
).equals("startDockOrHome")
) {
Intent.CATEGORY_HOME)) {
} else {
intent?.extras?.keySet()?.forEach {
@ -287,7 +297,11 @@ open class LauncherActivity : CommonActivity() {
}
}
} catch (e : Exception) {
e.printStackTrace()
}
// }
super.onNewIntent(intent)
}
@ -341,12 +355,13 @@ open class LauncherActivity : CommonActivity() {
}
// 위젯 관련 변수
private var appWidgetManager: AppWidgetManager? = null
private var appWidgetHost: AppWidgetHost? = null
private var appWidgetHost: WidgetHost? = null
private val APPWIDGET_HOST_ID = 1024
private val REQUEST_PICK_APPWIDGET = 100
private val REQUEST_CREATE_APPWIDGET = 101
fun showAppDrawer() {
val bottomSheet = AppDrawerBottomSheet.newInstance()
bottomSheet.show(supportFragmentManager, AppDrawerBottomSheet.TAG)
@ -357,15 +372,20 @@ open class LauncherActivity : CommonActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
installSplashScreen()
super.onCreate(savedInstanceState)
try {
YoutubeDL.getInstance().init(this)
FFmpeg.getInstance().init(this);
CoroutineScope(Dispatchers.IO).launch {
YoutubeDL.getInstance().updateYoutubeDL(this@LauncherActivity)
}
} catch (e: YoutubeDLException) {
Blog.LOGE("failed to initialize youtubedl-android", e)
}
// try {
// YoutubeDL.getInstance().init(this)
// FFmpeg.getInstance().init(this);
// CoroutineScope(Dispatchers.IO).launch {
// try {
// YoutubeDL.getInstance().updateYoutubeDL(this@LauncherActivity)
// }catch (e : Exception) {
//
// }
//
// }
// } catch (e: YoutubeDLException) {
// Blog.LOGE("failed to initialize youtubedl-android", e)
// }
val intent = Intent(this, ForeGroundService::class.java)
this.startForegroundService(intent)
@ -376,7 +396,7 @@ open class LauncherActivity : CommonActivity() {
window.statusBarColor = Color.TRANSPARENT
// (선택 사항) 내비게이션 바도 투명하게 하고 싶다면
window.navigationBarColor = Color.TRANSPARENT
window.navigationBarColor = Color.TRANSPARENT
val nlService = Intent(this, NLService::class.java)
this.startService(nlService)
@ -444,7 +464,7 @@ open class LauncherActivity : CommonActivity() {
view.layoutParams = params
// AppWidgetHostView에 크기 변경 알림 (위젯 내용물 재배치 유도)
(view as? AppWidgetHostView)?.updateAppWidgetSize(null, params.width, params.height, params.width, params.height)
return true // 이벤트를 처리했음을 알림
}
@ -453,6 +473,29 @@ open class LauncherActivity : CommonActivity() {
})
}
private fun updateWidgetOptions(appWidgetId: Int, hostView: AppWidgetHostView) {
val width = hostView.layoutParams.width
val height = hostView.layoutParams.height
// DP 단위로 변환 (시스템은 픽셀이 아니라 DP를 기준으로 레이아웃을 결정함)
val density = resources.displayMetrics.density
val widthDp = (width / density).toInt()
val heightDp = (height / density).toInt()
val options = Bundle().apply {
putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, widthDp)
putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, heightDp)
putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, widthDp)
putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, heightDp)
}
// 시스템 매니저에 현재 위젯의 새로운 크기 정보를 동기화
appWidgetManager?.updateAppWidgetOptions(appWidgetId, options)
// 호스트 뷰에게도 크기가 변했으니 다시 그리라고 명령 (콘텐츠 유실 방지)
hostView.updateAppWidgetSize(options, widthDp, heightDp, widthDp, heightDp)
}
override fun onPause() {
super.onPause()
@ -508,6 +551,30 @@ open class LauncherActivity : CommonActivity() {
private var lastTouchX = 0f
private var lastTouchY = 0f
private fun reconfigureWidget(widgetId: Int) {
val appWidgetInfo = appWidgetManager?.getAppWidgetInfo(widgetId)
// 1. 해당 위젯이 설정 액티비티를 가지고 있는지 확인
if (appWidgetInfo?.configure != null) {
try {
// 2. AppWidgetHost를 통해 설정 액티비티 실행
// REQUEST_CREATE_APPWIDGET을 재사용하거나 별도의 코드를 지정하세요.
appWidgetHost?.startAppWidgetConfigureActivityForResult(
this,
widgetId,
0,
REQUEST_CREATE_APPWIDGET,
null
)
} catch (e: Exception) {
e.printStackTrace()
showToast("설정 화면을 열 수 없습니다.")
}
} else {
showToast("이 위젯은 설정을 지원하지 않습니다.")
}
}
// 위젯 뷰 생성 및 화면 배치
private fun createWidget(data: Intent?, savedWidgetData: WidgetData? = null) {
val appWidgetId = savedWidgetData?.appWidgetId ?: data?.extras?.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) ?: return
@ -551,9 +618,12 @@ open class LauncherActivity : CommonActivity() {
// 새로 추가된 위젯이라면 DB에 저장
if (savedWidgetData == null) {
saveWidgetState(appWidgetId, hostView!!.x, hostView.y, width, height, appWidgetInfo.provider.className)
} else {
}
}
// 위젯 정보 DB 저장
private fun saveWidgetState(id: Int, x: Float, y: Float, w: Int, h: Int, name: String) {
WorkersDb.getRealm().writeBlocking {
@ -575,7 +645,7 @@ open class LauncherActivity : CommonActivity() {
createWidget(null, widgetData)
}
}
lateinit var scaleDetector: android.view.ScaleGestureDetector
lateinit var scaleDetector: android.view.ScaleGestureDetector
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
if (ev == null) return super.dispatchTouchEvent(ev)
@ -846,3 +916,4 @@ open class LauncherActivity : CommonActivity() {
// lActivity?.startActivity(mapIntent)
//}
//

View File

@ -0,0 +1,250 @@
package bums.lunatic.launcher
import android.annotation.SuppressLint
import android.app.Activity
import android.appwidget.AppWidgetHost
import android.appwidget.AppWidgetHostView
import android.appwidget.AppWidgetManager
import android.content.Context
import android.content.Intent
import android.graphics.Rect
import android.os.Bundle
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.ScaleGestureDetector
import android.view.View
import android.widget.FrameLayout
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import bums.lunatic.launcher.model.WidgetData
interface OnWidgetUpdateListener {
fun onStateChanged(widgetId: Int, x: Float, y: Float, width: Int, height: Int)
fun onDeleted(widgetId: Int)
fun onLongPress(view: View) // 추가 메뉴(설정 등) 띄우기용
}
class WidgetWorkspaceLayout @JvmOverloads constructor(
context: android.content.Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {
private val APPWIDGET_HOST_ID = 1024
private var appWidgetManager = AppWidgetManager.getInstance(context)
private var appWidgetHost = AppWidgetHost(context, APPWIDGET_HOST_ID)
private var isDragging = false
private var currentView: View? = null
private var lastX = 0f
private var lastY = 0f
private var deleteZone: View? = null
// Activity로부터 전달받을 결과 처리기 (캡슐화의 핵심)
private lateinit var pickLauncher: ActivityResultLauncher<Intent>
private lateinit var configLauncher: ActivityResultLauncher<Intent>
private var updateListener: OnWidgetUpdateListener? = null
// 1. 뷰가 화면에 붙을 때 호스트 리스닝 시작
override fun onAttachedToWindow() {
super.onAttachedToWindow()
appWidgetHost.startListening()
setupResultLaunchers() // 결과 처리기 초기화
}
// 2. 뷰가 떨어질 때 리스닝 중지 (메모리 누수 방지)
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
appWidgetHost.stopListening()
}
// 3. Activity Result 처리를 뷰 내부로 가져오기
private fun setupResultLaunchers() {
val activity = context as? ComponentActivity ?: return
val registry = activity.activityResultRegistry
// 위젯 선택 결과 처리
pickLauncher = registry.register("pick_widget", ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
handleWidgetPickResult(result.data)
}
}
// 위젯 설정 결과 처리
configLauncher = registry.register("config_widget", ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
createWidgetView(result.data?.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) ?: -1)
}
}
}
// 4. 새 위젯 추가 프로세스 시작 (Activity 호출 필요 없음)
fun addNewWidget() {
val appWidgetId = appWidgetHost.allocateAppWidgetId()
val pickIntent = Intent(AppWidgetManager.ACTION_APPWIDGET_PICK).apply {
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
}
pickLauncher.launch(pickIntent)
}
private fun handleWidgetPickResult(data: Intent?) {
val appWidgetId = data?.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) ?: return
val appWidgetInfo = appWidgetManager.getAppWidgetInfo(appWidgetId)
if (appWidgetInfo?.configure != null) {
// 설정창이 있는 위젯이면 설정창 실행
val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE).apply {
component = appWidgetInfo.configure
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
}
configLauncher.launch(intent)
} else {
// 설정창 없으면 바로 생성
createWidgetView(appWidgetId)
}
}
// 5. 위젯 뷰 생성 및 레이아웃 배치 로직
fun createWidgetView(appWidgetId: Int, savedData: WidgetData? = null) {
val info = appWidgetManager.getAppWidgetInfo(appWidgetId) ?: return
val hostView = appWidgetHost.createView(context, appWidgetId, info)
hostView.setAppWidget(appWidgetId, info)
hostView.tag = appWidgetId
// 위치 및 크기 설정 (savedData가 있으면 복구, 없으면 초기화)
val params = LayoutParams(
savedData?.width ?: info.minWidth,
savedData?.height ?: info.minHeight
)
hostView.layoutParams = params
hostView.x = savedData?.x ?: 100f
hostView.y = savedData?.y ?: 100f
addView(hostView)
// 새 위젯이라면 DB 저장 알림
if (savedData == null) {
updateListener?.onStateChanged(appWidgetId, hostView.x, hostView.y, params.width, params.height)
}
}
private val scaleDetector = ScaleGestureDetector(context, object : ScaleGestureDetector.SimpleOnScaleGestureListener() {
override fun onScale(detector: ScaleGestureDetector): Boolean {
currentView?.let { view ->
val params = view.layoutParams
params.width = (params.width * detector.scaleFactor).toInt().coerceAtLeast(150)
params.height = (params.height * detector.scaleFactor).toInt().coerceAtLeast(150)
view.layoutParams = params
return true
}
return false
}
})
fun setup(listener: OnWidgetUpdateListener, deleteZoneView: View) {
this.updateListener = listener
this.deleteZone = deleteZoneView
}
// 자식 위젯의 클릭을 방해하지 않으면서 드래그 시점에 이벤트를 뺏어옴
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
if (ev.action == MotionEvent.ACTION_DOWN) {
// 자식 뷰(위젯) 중 터치 지점에 있는 것을 찾음
currentView = findChildByPos(ev.x, ev.y)
}
return isDragging || super.onInterceptTouchEvent(ev)
}
@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(event: MotionEvent): Boolean {
scaleDetector.onTouchEvent(event)
if (scaleDetector.isInProgress) return true
when (event.actionMasked) {
MotionEvent.ACTION_MOVE -> {
if (isDragging && currentView != null) {
if (lastX != 0f && lastY != 0f) {
currentView!!.x += event.rawX - lastX
currentView!!.y += event.rawY - lastY
}
lastX = event.rawX
lastY = event.rawY
// 삭제 영역 피드백 (UI 로직도 여기서 처리)
checkDeleteZoneFeedback()
}
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
finalizeWidgetAction()
}
}
return true
}
private fun finalizeWidgetAction() {
currentView?.let { view ->
val widgetId = view.tag as? Int ?: return@let
if (isInsideDeleteZone(view)) {
updateListener?.onDeleted(widgetId)
removeView(view)
} else {
// 시스템 옵션 동기화 (콘텐츠 유실 방지 핵심)
syncSystemOptions(widgetId, view as AppWidgetHostView)
// 액티비티에는 "저장해라"라고 결과만 통보
updateListener?.onStateChanged(widgetId, view.x, view.y, view.width, view.height)
}
view.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start()
}
deleteZone?.visibility = View.GONE
isDragging = false
currentView = null
lastX = 0f
lastY = 0f
}
// 위젯 롱클릭 시 드래그 모드 진입 (Activity에서 호출할 함수)
fun startDrag(view: View) {
this.currentView = view
this.isDragging = true
this.deleteZone?.visibility = View.VISIBLE
view.animate().scaleX(1.05f).scaleY(1.05f).setDuration(100).start()
}
private fun syncSystemOptions(widgetId: Int, hostView: AppWidgetHostView) {
val density = resources.displayMetrics.density
val wDp = (hostView.width / density).toInt()
val hDp = (hostView.height / density).toInt()
val options = Bundle().apply {
putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, wDp)
putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, hDp)
}
appWidgetManager?.updateAppWidgetOptions(widgetId, options)
hostView.updateAppWidgetSize(options, wDp, hDp, wDp, hDp)
}
private fun isInsideDeleteZone(view: View): Boolean {
if (deleteZone == null) return false
val rect = Rect()
deleteZone!!.getGlobalVisibleRect(rect)
return rect.contains(view.x.toInt() + view.width / 2, view.y.toInt() + view.height / 2)
}
private fun checkDeleteZoneFeedback() {
// 삭제 영역 위일 때 배경색 변경 등 피드백 로직
}
private fun findChildByPos(x: Float, y: Float): View? {
for (i in childCount - 1 downTo 0) {
val child = getChildAt(i)
if (x >= child.x && x <= child.x + child.width && y >= child.y && y <= child.y + child.height) {
return child
}
}
return null
}
}

View File

@ -298,67 +298,67 @@ open class NeoRssActivity : CommonActivity() {
showContents(v.id)
}
override fun onNewIntent(intent: Intent) {
Blog.LOGE("onNewIntent intent >> ${intent}")
if(intent?.action?.equals(Intent.ACTION_SEND) == true &&
intent?.hasExtra(Intent.EXTRA_TEXT) == true) {
intent?.getStringExtra(Intent.EXTRA_TEXT)?.let {
if(it.startsWith("http") == false) {
it.split("http").forEach { string ->
if(string.startsWith("http")) {
try {
string.toUri()?.let { uri ->
Blog.LOGE("onNewIntent string uri.lastPathSegment >>>>> ${uri.host}")
Blog.LOGE("onNewIntent string uri.lastPathSegment >>>>> ${uri.lastPathSegment}")
}
} catch (e: Exception) {
}
}
}
} else {
try {
it.toUri()?.let { uri ->
Blog.LOGE("onNewIntent it uri.lastPathSegment >>>>> ${uri.host}")
Blog.LOGE("onNewIntent it uri.lastPathSegment >>>>> ${uri.lastPathSegment}")
}
} catch (e: Exception) {
}
}
}
} else if (intent?.action == Intent.ACTION_WEB_SEARCH) {
openWithIntent(intent)
} else {
Blog.LOGE("onNewIntent intent?.hasExtra >> ${intent?.hasExtra(Intent.EXTRA_STREAM)}")
if (intent?.action?.equals(Intent.ACTION_MAIN) == true && intent.categories.contains(
Intent.CATEGORY_HOME
) && intent.hasExtra("android.intent.extra.EXTRA_START_REASON") && intent.getStringExtra(
"android.intent.extra.EXTRA_START_REASON"
).equals("startDockOrHome")
) {
} else {
intent?.extras?.keySet()?.forEach {
try {
Blog.LOGE(
"onNewIntent :: key >> ${it} :: value >> ${
intent?.extras?.getString(
it
)
}"
)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}
super.onNewIntent(intent)
}
// override fun onNewIntent(intent: Intent) {
// Blog.LOGE("onNewIntent intent >> ${intent}")
// if(intent?.action?.equals(Intent.ACTION_SEND) == true &&
// intent?.hasExtra(Intent.EXTRA_TEXT) == true) {
// intent?.getStringExtra(Intent.EXTRA_TEXT)?.let {
// if(it.startsWith("http") == false) {
// it.split("http").forEach { string ->
// if(string.startsWith("http")) {
// try {
// string.toUri()?.let { uri ->
// Blog.LOGE("onNewIntent string uri.lastPathSegment >>>>> ${uri.host}")
// Blog.LOGE("onNewIntent string uri.lastPathSegment >>>>> ${uri.lastPathSegment}")
// }
// } catch (e: Exception) {
//
// }
// }
// }
// } else {
// try {
// it.toUri()?.let { uri ->
// Blog.LOGE("onNewIntent it uri.lastPathSegment >>>>> ${uri.host}")
// Blog.LOGE("onNewIntent it uri.lastPathSegment >>>>> ${uri.lastPathSegment}")
// }
// } catch (e: Exception) {
//
// }
// }
// }
// } else if (intent?.action == Intent.ACTION_WEB_SEARCH) {
// openWithIntent(intent)
// } else {
// Blog.LOGE("onNewIntent intent?.hasExtra >> ${intent?.hasExtra(Intent.EXTRA_STREAM)}")
//
//
// if (intent?.action?.equals(Intent.ACTION_MAIN) == true && intent.categories.contains(
// Intent.CATEGORY_HOME
// ) && intent.hasExtra("android.intent.extra.EXTRA_START_REASON") && intent.getStringExtra(
// "android.intent.extra.EXTRA_START_REASON"
// ).equals("startDockOrHome")
// ) {
//
// } else {
// intent?.extras?.keySet()?.forEach {
// try {
// Blog.LOGE(
// "onNewIntent :: key >> ${it} :: value >> ${
// intent?.extras?.getString(
// it
// )
// }"
// )
// } catch (e: Exception) {
// e.printStackTrace()
// }
//
// }
// }
// }
// super.onNewIntent(intent)
// }
private fun openWithIntent(intent: Intent){
Blog.LOGE("intent >> ${intent}")
@ -382,24 +382,25 @@ open class NeoRssActivity : CommonActivity() {
super.onCreate(savedInstanceState)
try {
YoutubeDL.getInstance().init(this)
FFmpeg.getInstance().init(this);
FFmpeg.getInstance().init(this)
CoroutineScope(Dispatchers.IO).launch {
YoutubeDL.getInstance().updateYoutubeDL(this@NeoRssActivity)
try {
YoutubeDL.getInstance().updateYoutubeDL(this@NeoRssActivity)
} catch (e: YoutubeDLException) {
Blog.LOGE("failed to initialize youtubedl-android", e)
}
}
} catch (e: YoutubeDLException) {
Blog.LOGE("failed to initialize youtubedl-android", e)
}
val intent = Intent(this, ForeGroundService::class.java)
this.startForegroundService(intent)
// 1. 시스템 바 공간을 앱이 차지하도록 설정 (상태바 뒤로 레이아웃 확장)
WindowCompat.setDecorFitsSystemWindows(window, false)
// 2. 상태바 색상을 투명하게 변경 (필요한 경우)
window.statusBarColor = Color.TRANSPARENT
// (선택 사항) 내비게이션 바도 투명하게 하고 싶다면
window.navigationBarColor = Color.TRANSPARENT
window.navigationBarColor = Color.TRANSPARENT
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
@ -522,7 +523,9 @@ open class NeoRssActivity : CommonActivity() {
binding.controllPanel.visibility = View.GONE
binding.floatingActionMenu.visibility = View.GONE
}
sRuntime?.shutdown()
sRuntime = null
finish()
}
else -> {}
}
@ -568,7 +571,12 @@ open class NeoRssActivity : CommonActivity() {
super.onDestroy()
}
override fun onUserLeaveHint() {
showContents(R.id.close)
super.onUserLeaveHint()
}
@RequiresApi(Build.VERSION_CODES.O_MR1)
override fun onResume() {