From 08a196e60ed714263d5283f3c0579bb2dcf56e02 Mon Sep 17 00:00:00 2001
From: lmw <125975490@qq.com>
Date: 星期一, 03 三月 2025 17:44:26 +0800
Subject: [PATCH] save

---
 app/src/main/res/layout/item_banner.xml                                  |    2 
 app/src/main/java/com/sinata/xqmuse/ThinkAudioService.kt                 |   89 ++++++++++++++++++++++
 app/src/main/java/com/sinata/xqmuse/ui/home/VoiceDetailActivity.kt       |    1 
 app/src/main/java/com/sinata/xqmuse/ui/home/adapter/CardBannerAdapter.kt |    2 
 app/src/main/res/layout/item_banner_card.xml                             |    6 
 app/src/main/res/layout/activity_guide.xml                               |    2 
 app/src/main/res/layout/fragment_home.xml                                |    4 
 app/src/main/java/com/sinata/xqmuse/MainActivity.kt                      |   78 ++++++++++---------
 app/src/main/java/com/sinata/xqmuse/network/Apis.kt                      |    2 
 9 files changed, 140 insertions(+), 46 deletions(-)

diff --git a/app/src/main/java/com/sinata/xqmuse/MainActivity.kt b/app/src/main/java/com/sinata/xqmuse/MainActivity.kt
index 2890343..c2fb678 100644
--- a/app/src/main/java/com/sinata/xqmuse/MainActivity.kt
+++ b/app/src/main/java/com/sinata/xqmuse/MainActivity.kt
@@ -8,6 +8,7 @@
 import android.provider.Settings
 import android.util.Log
 import android.view.View
+import android.view.WindowManager
 import androidx.fragment.app.Fragment
 import androidx.fragment.app.FragmentPagerAdapter
 import cn.sinata.xldutils.gone
@@ -57,7 +58,7 @@
     private var thinkHandler:Handler? = null //冥想时间相关
     private var inGuide = false //true 引导中...
 
-    private val isFirst by lazy { intent.getBooleanExtra("isFirst",false) } //首次安装,需要到导师引导页
+    private val isFirst by lazy { intent.getBooleanExtra("isFirst", false) } //首次安装,需要到导师引导页
 
     private val MSG_PROGRESS = 0//疗愈进度+1
     private val MSG_TODAY = 1//今日疗愈更新计时
@@ -72,14 +73,14 @@
 
     override fun initClick() {
         player_close.setOnClickListener {
-            TipDialog.show(supportFragmentManager,"是否关闭当前音频?",object :TipDialog.OnClickCallback{
+            TipDialog.show(supportFragmentManager, "是否关闭当前音频?", object : TipDialog.OnClickCallback {
                 override fun onOk() {
                     EventBus.getDefault().post(EmptyEvent(Const.EventCode.FINISH_THINK))
                 }
 
                 override fun onCancel() {
                 }
-            },"确认","取消")
+            }, "确认", "取消")
         }
 
         cl_player.setOnClickListener {
@@ -121,24 +122,24 @@
             override fun handleMessage(msg: Message) {
                 super.handleMessage(msg)
                 when(msg.what){
-                    MSG_PROGRESS->{
-                        currentPosition = thinkBgPlayer?.currentPosition ?:0
+                    MSG_PROGRESS -> {
+                        currentPosition = thinkBgPlayer?.currentPosition ?: 0
                         EventBus.getDefault().post(EmptyEvent(Const.EventCode.GOT_THINK_POSITION))
-                        sendEmptyMessageDelayed(MSG_PROGRESS,1000)
+                        sendEmptyMessageDelayed(MSG_PROGRESS, 1000)
                     }
-                    MSG_COUNTDOWN->{
-                        if (System.currentTimeMillis()>= finishTime)
+                    MSG_COUNTDOWN -> {
+                        if (System.currentTimeMillis() >= finishTime)
                             EventBus.getDefault().post(EmptyEvent(Const.EventCode.FINISH_THINK))
                         else
-                            sendEmptyMessageDelayed(MSG_COUNTDOWN,1000)
+                            sendEmptyMessageDelayed(MSG_COUNTDOWN, 1000)
                     }
-                    MSG_TODAY->{
+                    MSG_TODAY -> {
                         if (System.currentTimeMillis() - lastTodayTime > 60000) { //距离上次刷新过去了1分钟
-                            Log.e(Const.Tag,"已经过1分钟,需要重新获取今日疗愈数据")
+                            Log.e(Const.Tag, "已经过1分钟,需要重新获取今日疗愈数据")
                             lastTodayTime = System.currentTimeMillis()
                             (fragments[0] as HomeFragment).getToday()
                         }
-                        sendEmptyMessageDelayed(MSG_TODAY,5000)
+                        sendEmptyMessageDelayed(MSG_TODAY, 5000)
                     }
                 }
             }
@@ -151,29 +152,29 @@
         if (guidePlayer == null)
             guidePlayer = AudioUtils()
         if (guideAudio.isNullOrEmpty())
-            HttpManager.getPlan().request(this){_,data->
+            HttpManager.getPlan().request(this){ _, data->
                 guideAudio = data
                 if (inGuide){
                     guidePlayer?.setVolume(0.6f)
-                    guidePlayer?.loopPlayMusic(this,data)
+                    guidePlayer?.loopPlayMusic(this, data)
                 }
             }
         else{
             guidePlayer?.setVolume(0.6f)
-            guidePlayer?.loopPlayMusic(this,guideAudio)
+            guidePlayer?.loopPlayMusic(this, guideAudio)
         }
     }
 
     private fun startBgm() {
-        HttpManager.getHomeBackgroundMusicByUserId().request(this){_,data->
+        HttpManager.getHomeBackgroundMusicByUserId().request(this){ _, data->
             if (!data?.audioFile.isNullOrEmpty()){
                 if (bgPlayer == null)
                     bgPlayer = AudioUtils()
-                val volume = SPUtils.instance().getInt(Const.User.VOLUME,50)
-                bgPlayer?.setVolume(volume.toFloat()/100)
-                bgPlayer?.loopPlayMusic(this,data?.audioFile)
+                val volume = SPUtils.instance().getInt(Const.User.VOLUME, 50)
+                bgPlayer?.setVolume(volume.toFloat() / 100)
+                bgPlayer?.loopPlayMusic(this, data?.audioFile)
             }
-            (fragments[0] as HomeFragment).changeBg(data?.imageUrl?:"",data?.backUrl?:"")
+            (fragments[0] as HomeFragment).changeBg(data?.imageUrl ?: "", data?.backUrl ?: "")
         }
     }
 
@@ -188,8 +189,8 @@
                 thinkBgPlayer = AudioUtils()
                 thinkBgPlayer!!.setOnAudioStatusUpdateListener(this)
             }
-            val volume = SPUtils.instance().getInt(Const.User.VOLUME_THINK,50)
-            thinkBgPlayer?.setVolume(volume.toFloat()/100)
+            val volume = SPUtils.instance().getInt(Const.User.VOLUME_THINK, 50)
+            thinkBgPlayer?.setVolume(volume.toFloat() / 100)
             thinkBgPlayer?.startPlayMusic(this, voice?.meditationMusicList?.get(index))
             currentDuration = voice?.meditationSecondList?.get(index)?:0
             EventBus.getDefault().post(EmptyEvent(Const.EventCode.GOT_THINK_DURATION))
@@ -233,10 +234,10 @@
             return
         val time = ((System.currentTimeMillis() - startTime) / 1000).toInt()
         startTime = 0L
-        HttpManager.saveViewingHistory(voice?.id?:"", time).request(this,false,{ _, _->
-            Log.e(Const.Tag,"冥想记录成功:$time 秒")
-        }){_,_->
-            Log.e(Const.Tag,"冥想记录失败:$time 秒")
+        HttpManager.saveViewingHistory(voice?.id ?: "", time).request(this, false, { _, _ ->
+            Log.e(Const.Tag, "冥想记录成功:$time 秒")
+        }){ _, _->
+            Log.e(Const.Tag, "冥想记录失败:$time 秒")
         }
     }
 
@@ -248,7 +249,7 @@
     }
 
     private fun initTab() {
-        val titles = arrayListOf("疗愈","课程","","疗愈馆","我的")
+        val titles = arrayListOf("疗愈", "课程", "", "疗愈馆", "我的")
         val iconChecked = arrayListOf(
             R.mipmap.home_selected,
             R.mipmap.play_selected,
@@ -269,7 +270,7 @@
         fragments.add(DiscoveryFragment())
         fragments.add(MineFragment())
         view_pager.offscreenPageLimit = fragments.size
-        view_pager.adapter = object : FragmentPagerAdapter(supportFragmentManager,0) {
+        view_pager.adapter = object : FragmentPagerAdapter(supportFragmentManager, 0) {
             override fun getItem(p0: Int): Fragment {
                 return fragments[p0]
             }
@@ -327,7 +328,7 @@
     }
 
     @Subscribe
-    fun onEvent(e:EmptyEvent){
+    fun onEvent(e: EmptyEvent){
         if (e.code == Const.EventCode.CHANGE_USER){
             tab_bar.currentTab = 0
             onTabSelect(0)
@@ -359,8 +360,8 @@
         }else if(e.code == Const.EventCode.PAUSE_OR_RESUME_THINK){
             player_play.callOnClick()
         }else if(e.code == Const.EventCode.CHANGE_THINK_VOLUME){
-            val v = SPUtils.instance().getInt(Const.User.VOLUME_THINK,50)
-            thinkBgPlayer?.setVolume(v.toFloat()/100)
+            val v = SPUtils.instance().getInt(Const.User.VOLUME_THINK, 50)
+            thinkBgPlayer?.setVolume(v.toFloat() / 100)
         }else if(e.code == Const.EventCode.START_GUIDE_AUDIO){
             inGuide = true
             startGuide()
@@ -382,7 +383,7 @@
     }
 
     @Subscribe
-    fun onIntEvent(e:IntEvent){
+    fun onIntEvent(e: IntEvent){
         if (e.code == Const.EventCode.THINK_SEEK_PROGRESS){
             thinkBgPlayer?.seekTo(e.i)
             player_play.callOnClick()
@@ -394,12 +395,15 @@
         val answer = SPUtils.instance().getString(Const.User.ANSWER)
         if (!answer.isNullOrEmpty()){ //已登录并且有答案
             val reqAnswer = Gson().fromJson(answer, ReqAnswer::class.java)
-            reqAnswer?.device = Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID)
-            HttpManager.saveUserAnswers(reqAnswer).request(this,false,success = { _, _->
-                SPUtils.instance().put(Const.User.ANSWER,"").apply()
-                Log.e(Const.Tag,"私人定制已保存")
+            reqAnswer?.device = Settings.Secure.getString(
+                contentResolver,
+                Settings.Secure.ANDROID_ID
+            )
+            HttpManager.saveUserAnswers(reqAnswer).request(this, false, success = { _, _ ->
+                SPUtils.instance().put(Const.User.ANSWER, "").apply()
+                Log.e(Const.Tag, "私人定制已保存")
                 (fragments[0] as HomeFragment).getPrivacy()
-            }){_,_->
+            }){ _, _->
             }
         }
     }
diff --git a/app/src/main/java/com/sinata/xqmuse/ThinkAudioService.kt b/app/src/main/java/com/sinata/xqmuse/ThinkAudioService.kt
new file mode 100644
index 0000000..a6d8f87
--- /dev/null
+++ b/app/src/main/java/com/sinata/xqmuse/ThinkAudioService.kt
@@ -0,0 +1,89 @@
+package com.sinata.xqmuse
+
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.app.Service
+import android.content.Intent
+import android.media.AudioManager
+import android.media.MediaPlayer
+import android.os.Build
+import android.os.IBinder
+import android.os.PowerManager
+import androidx.core.app.NotificationCompat
+
+class ThinkAudioService:Service() {
+    private var mediaPlayer: MediaPlayer? = null
+    private var wakeLock: PowerManager.WakeLock? = null
+
+    override fun onCreate() {
+        super.onCreate()
+        // 初始化 MediaPlayer
+//        mediaPlayer = MediaPlayer.create(this, R.raw.audio_sample)
+        mediaPlayer!!.isLooping = true
+
+        // 初始化 WakeLock
+        val powerManager = getSystemService(POWER_SERVICE) as PowerManager
+        wakeLock = powerManager.newWakeLock(
+            PowerManager.PARTIAL_WAKE_LOCK,
+            "AudioService::WakeLock"
+        )
+    }
+
+    private val focusChangeListener =
+        AudioManager.OnAudioFocusChangeListener { focusChange ->
+            if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
+                mediaPlayer!!.pause() // 焦点丢失时暂停播放
+            }
+        }
+
+    private fun createNotificationChannel() {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            val channel = NotificationChannel(
+                "audio_channel",
+                "音频播放",
+                NotificationManager.IMPORTANCE_LOW
+            )
+            getSystemService(NotificationManager::class.java).createNotificationChannel(channel)
+        }
+    }
+
+    override fun onBind(intent: Intent?): IBinder? {
+        return null
+    }
+
+    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
+        // 创建通知渠道(Android 8.0+ 必须)
+        createNotificationChannel()
+
+        // 启动前台服务
+        val notification = NotificationCompat.Builder(this, "audio_channel")
+            .setContentTitle("音频播放中")
+            .setSmallIcon(R.mipmap.ic_launcher)
+            .build()
+        startForeground(1, notification)
+
+        // 请求音频焦点
+        val audioManager = getSystemService(AUDIO_SERVICE) as AudioManager
+        val result = audioManager.requestAudioFocus(
+            focusChangeListener,
+            AudioManager.STREAM_MUSIC,
+            AudioManager.AUDIOFOCUS_GAIN
+        )
+        if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
+            mediaPlayer?.start()
+            wakeLock?.acquire(30 * 60 * 1000L) // 申请 WakeLock
+        }
+        return START_STICKY
+    }
+
+    override fun onDestroy() {
+        if (mediaPlayer != null) {
+            mediaPlayer!!.release()
+            mediaPlayer = null
+        }
+        if (wakeLock != null && wakeLock!!.isHeld) {
+            wakeLock!!.release()
+        }
+        super.onDestroy()
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/sinata/xqmuse/network/Apis.kt b/app/src/main/java/com/sinata/xqmuse/network/Apis.kt
index 0f34416..961345f 100644
--- a/app/src/main/java/com/sinata/xqmuse/network/Apis.kt
+++ b/app/src/main/java/com/sinata/xqmuse/network/Apis.kt
@@ -5,7 +5,7 @@
 
 //    private const val TEST_URL = "http://192.168.110.64:9000/" //内网
     private const val TEST_URL = "https://xq.xqzhihui.com/api/" //外网
-    private const val LINE_URL = "https://jkcyl.cn/app/" //正式服
+    private const val LINE_URL = "" //正式服
     val BASE_URL = if (isTest) TEST_URL else LINE_URL
 
     /**公共接口*/
diff --git a/app/src/main/java/com/sinata/xqmuse/ui/home/VoiceDetailActivity.kt b/app/src/main/java/com/sinata/xqmuse/ui/home/VoiceDetailActivity.kt
index 1b55c56..a08bc83 100644
--- a/app/src/main/java/com/sinata/xqmuse/ui/home/VoiceDetailActivity.kt
+++ b/app/src/main/java/com/sinata/xqmuse/ui/home/VoiceDetailActivity.kt
@@ -150,6 +150,7 @@
             }
         }
         EventBus.getDefault().register(this)
+        iv_play.keepScreenOn = true
     }
 
     private fun startTimer(){
diff --git a/app/src/main/java/com/sinata/xqmuse/ui/home/adapter/CardBannerAdapter.kt b/app/src/main/java/com/sinata/xqmuse/ui/home/adapter/CardBannerAdapter.kt
index ae4cb28..0a951fb 100644
--- a/app/src/main/java/com/sinata/xqmuse/ui/home/adapter/CardBannerAdapter.kt
+++ b/app/src/main/java/com/sinata/xqmuse/ui/home/adapter/CardBannerAdapter.kt
@@ -34,7 +34,7 @@
         val bannerViewHolder = holder as BannerViewHolder
         bannerViewHolder.iv_bg.setImageURI(data?.coverUrl?.split(",")?.get(1))
         bannerViewHolder.tv_title.text = data?.meditationTitle
-        bannerViewHolder.tv_subtitle.text = data?.coverDescription?.ellipsize(6)
+        bannerViewHolder.tv_subtitle.text = data?.coverDescription?.ellipsize(4)
         bannerViewHolder.tv_count.text = ((data?.realLearnedNum?:0)+(data?.virtualLearnedNum?:0)).toString()
         when(data?.chargeType){ //1=免费 2=会员免费 3=单独收费
             2->{
diff --git a/app/src/main/res/layout/activity_guide.xml b/app/src/main/res/layout/activity_guide.xml
index 8bcf343..324aef3 100644
--- a/app/src/main/res/layout/activity_guide.xml
+++ b/app/src/main/res/layout/activity_guide.xml
@@ -8,7 +8,7 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         app:screenScaleType="type_center_crop"
-        app:playerBackgroundColor="@color/colorPrimary"
+        app:playerBackgroundColor="@color/white"
         android:id="@+id/player"/>
 
     <TextView
diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml
index c00013c..a26cf61 100644
--- a/app/src/main/res/layout/fragment_home.xml
+++ b/app/src/main/res/layout/fragment_home.xml
@@ -126,7 +126,7 @@
                 android:layout_height="wrap_content"
                 app:layout_constraintBottom_toBottomOf="@id/iv_today"
                 android:paddingVertical="8dp"
-                android:textSize="11sp"
+                android:textSize="14sp"
                 android:textColor="@color/white"
                 android:gravity="end"
                 android:id="@+id/tv_today_count"
@@ -141,7 +141,7 @@
                 app:layout_constraintBaseline_toBaselineOf="@id/tv_today_count"
                 app:layout_constraintStart_toStartOf="parent"
                 android:layout_marginStart="18dp"
-                android:textSize="11sp"
+                android:textSize="14sp"
                 android:textColor="@color/white" />
 
 
diff --git a/app/src/main/res/layout/item_banner.xml b/app/src/main/res/layout/item_banner.xml
index fbfd655..ee31397 100644
--- a/app/src/main/res/layout/item_banner.xml
+++ b/app/src/main/res/layout/item_banner.xml
@@ -45,6 +45,6 @@
         android:layout_marginBottom="16dp"
         app:layout_constraintStart_toStartOf="@id/tv_name"
         android:textColor="@color/white"
-        android:textSize="10sp"
+        android:textSize="14sp"
         android:textStyle="bold"/>
 </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_banner_card.xml b/app/src/main/res/layout/item_banner_card.xml
index 043899c..33de3e3 100644
--- a/app/src/main/res/layout/item_banner_card.xml
+++ b/app/src/main/res/layout/item_banner_card.xml
@@ -34,7 +34,7 @@
             android:text="缓解压力"
             android:singleLine="true"
             android:ellipsize="end"
-            android:textSize="14sp"
+            android:textSize="16sp"
             android:textColor="@color/white"
             android:id="@+id/tv_title"/>
         <TextView
@@ -46,7 +46,7 @@
             app:layout_constraintBottom_toBottomOf="parent"
             android:layout_marginBottom="11dp"
             android:text="缓解压力"
-            android:textSize="9sp"
+            android:textSize="11sp"
             android:textColor="@color/white"
             android:id="@+id/tv_subtitle"/>
         <ImageView
@@ -63,7 +63,7 @@
             android:layout_height="wrap_content"
             android:id="@+id/tv_count"
             android:textColor="@color/white"
-            android:textSize="9sp"
+            android:textSize="11sp"
             app:layout_constraintStart_toEndOf="@id/iv"
             app:layout_constraintBaseline_toBaselineOf="@id/tv_subtitle"
             android:layout_marginStart="2dp"

--
Gitblit v1.7.1