diff --git a/android/app/src/main/java/cn/toside/music/mobile/lyric/Lyric.java b/android/app/src/main/java/cn/toside/music/mobile/lyric/Lyric.java index 99eb38c..f93fd84 100644 --- a/android/app/src/main/java/cn/toside/music/mobile/lyric/Lyric.java +++ b/android/app/src/main/java/cn/toside/music/mobile/lyric/Lyric.java @@ -13,6 +13,7 @@ import com.facebook.react.bridge.ReactApplicationContext; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Objects; public class Lyric extends LyricPlayer { LyricView lyricView = null; @@ -48,7 +49,7 @@ public class Lyric extends LyricPlayer { public void onReceive(Context context, Intent intent) { String strAction = intent.getAction(); - switch (strAction) { + switch (Objects.requireNonNull(strAction)) { case Intent.ACTION_SCREEN_OFF: Log.d("Lyric", "ACTION_SCREEN_OFF"); handleScreenOff(); diff --git a/android/app/src/main/java/cn/toside/music/mobile/utils/UtilsEvent.java b/android/app/src/main/java/cn/toside/music/mobile/utils/UtilsEvent.java new file mode 100644 index 0000000..b69d346 --- /dev/null +++ b/android/app/src/main/java/cn/toside/music/mobile/utils/UtilsEvent.java @@ -0,0 +1,22 @@ +package cn.toside.music.mobile.utils; + +import android.util.Log; + +import androidx.annotation.Nullable; + +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.modules.core.DeviceEventManagerModule; + +public class UtilsEvent { + final String SCREEN_STATE = "screen-state"; + + private final ReactApplicationContext reactContext; + UtilsEvent(ReactApplicationContext reactContext) { this.reactContext = reactContext; } + + public void sendEvent(String eventName, @Nullable WritableMap params) { + reactContext + .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) + .emit(eventName, params); + } +} diff --git a/android/app/src/main/java/cn/toside/music/mobile/utils/UtilsModule.java b/android/app/src/main/java/cn/toside/music/mobile/utils/UtilsModule.java index b803cd2..fdb4f48 100644 --- a/android/app/src/main/java/cn/toside/music/mobile/utils/UtilsModule.java +++ b/android/app/src/main/java/cn/toside/music/mobile/utils/UtilsModule.java @@ -4,8 +4,10 @@ import android.annotation.SuppressLint; import android.app.Activity; import android.app.NotificationChannel; import android.app.NotificationManager; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.net.Uri; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; @@ -19,12 +21,14 @@ import androidx.core.app.NotificationManagerCompat; import androidx.core.content.FileProvider; import androidx.core.os.LocaleListCompat; +import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.UiThreadUtil; import com.facebook.react.bridge.WritableArray; +import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableNativeArray; import java.io.File; @@ -35,9 +39,13 @@ import java.util.Objects; public class UtilsModule extends ReactContextBaseJavaModule { private final ReactApplicationContext reactContext; + UtilsEvent utilsEvent; + UtilsModule(ReactApplicationContext reactContext) { super(reactContext); this.reactContext = reactContext; + utilsEvent = new UtilsEvent(reactContext); + registerScreenBroadcastReceiver(); } @Override @@ -45,6 +53,36 @@ public class UtilsModule extends ReactContextBaseJavaModule { return "UtilsModule"; } + private void registerScreenBroadcastReceiver() { + final IntentFilter theFilter = new IntentFilter(); + /** System Defined Broadcast */ + theFilter.addAction(Intent.ACTION_SCREEN_ON); + theFilter.addAction(Intent.ACTION_SCREEN_OFF); + + BroadcastReceiver screenOnOffReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String strAction = intent.getAction(); + + WritableMap params = Arguments.createMap(); + + switch (Objects.requireNonNull(strAction)) { + case Intent.ACTION_SCREEN_OFF: + + params.putString("state", "OFF"); + utilsEvent.sendEvent(utilsEvent.SCREEN_STATE, params); + break; + case Intent.ACTION_SCREEN_ON: + params.putString("state", "ON"); + utilsEvent.sendEvent(utilsEvent.SCREEN_STATE, params); + break; + } + } + }; + + reactContext.registerReceiver(screenOnOffReceiver, theFilter); + } + @ReactMethod public void exitApp() { // https://github.com/wumke/react-native-exit-app/blob/master/android/src/main/java/com/github/wumke/RNExitApp/RNExitAppModule.java diff --git a/package-lock.json b/package-lock.json index 6846a70..3a11fdd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "react-native-pager-view": "^6.2.1", "react-native-quick-base64": "^2.0.7", "react-native-quick-md5": "^3.0.5", - "react-native-track-player": "github:lyswhut/react-native-track-player#45aa27463844ee836b31322f987ff3981acf8c59", + "react-native-track-player": "github:lyswhut/react-native-track-player#4c61871ef85440b8ce52143fb8d1abfe7c5f1ab7", "react-native-vector-icons": "^10.0.0" }, "devDependencies": { @@ -9542,8 +9542,8 @@ }, "node_modules/react-native-track-player": { "version": "2.1.2", - "resolved": "git+ssh://git@github.com/lyswhut/react-native-track-player.git#45aa27463844ee836b31322f987ff3981acf8c59", - "integrity": "sha512-a0WPgO+tpR6WBFNDUw8GapR1eUkqe7N7jtEKpVq1WdeDDXRz5Sx36CZK2Q9Ux4raWoey46ATPvo41zwjaL02Wg==", + "resolved": "git+ssh://git@github.com/lyswhut/react-native-track-player.git#4c61871ef85440b8ce52143fb8d1abfe7c5f1ab7", + "integrity": "sha512-2nAbgRWVH5SOcaf5TJZK0AXYtlLURWRX51rxRP8slolXujZNiHqDpXYr6s2tFGQziUcLLYZoRTtmH51ehqSI9A==", "license": "Apache-2.0", "peerDependencies": { "react": ">=16.8.6", @@ -17993,9 +17993,9 @@ } }, "react-native-track-player": { - "version": "git+ssh://git@github.com/lyswhut/react-native-track-player.git#45aa27463844ee836b31322f987ff3981acf8c59", - "integrity": "sha512-a0WPgO+tpR6WBFNDUw8GapR1eUkqe7N7jtEKpVq1WdeDDXRz5Sx36CZK2Q9Ux4raWoey46ATPvo41zwjaL02Wg==", - "from": "react-native-track-player@github:lyswhut/react-native-track-player#45aa27463844ee836b31322f987ff3981acf8c59", + "version": "git+ssh://git@github.com/lyswhut/react-native-track-player.git#4c61871ef85440b8ce52143fb8d1abfe7c5f1ab7", + "integrity": "sha512-2nAbgRWVH5SOcaf5TJZK0AXYtlLURWRX51rxRP8slolXujZNiHqDpXYr6s2tFGQziUcLLYZoRTtmH51ehqSI9A==", + "from": "react-native-track-player@github:lyswhut/react-native-track-player#4c61871ef85440b8ce52143fb8d1abfe7c5f1ab7", "requires": {} }, "react-native-vector-icons": { diff --git a/package.json b/package.json index d865c3d..81021d3 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "react-native-pager-view": "^6.2.1", "react-native-quick-base64": "^2.0.7", "react-native-quick-md5": "^3.0.5", - "react-native-track-player": "github:lyswhut/react-native-track-player#45aa27463844ee836b31322f987ff3981acf8c59", + "react-native-track-player": "github:lyswhut/react-native-track-player#4c61871ef85440b8ce52143fb8d1abfe7c5f1ab7", "react-native-vector-icons": "^10.0.0" }, "devDependencies": { diff --git a/publish/changeLog.md b/publish/changeLog.md index f247511..ff172a1 100644 --- a/publish/changeLog.md +++ b/publish/changeLog.md @@ -24,6 +24,7 @@ - 优化数据传输逻辑,列表同步指令使用队列机制,保证列表同步操作的顺序 - 暂停播放时播放详情歌词页不要自动滚动歌词回播放位置 - 播放详情页歌词添加延迟滚动及着色动画 +- 优化息屏下的逻辑处理,尽量减少电量消耗 ### 修复 diff --git a/src/core/init/player/playProgress.ts b/src/core/init/player/playProgress.ts index 8c2ca67..a74e90a 100644 --- a/src/core/init/player/playProgress.ts +++ b/src/core/init/player/playProgress.ts @@ -7,6 +7,7 @@ import { throttleBackgroundTimer } from '@/utils/tools' import BackgroundTimer from 'react-native-background-timer' import playerState from '@/store/player/state' import settingState from '@/store/setting/state' +import { onScreenStateChange } from '@/utils/nativeModules/utils' const delaySavePlayInfo = throttleBackgroundTimer(() => { void savePlayInfo({ @@ -22,13 +23,15 @@ export default () => { let updateTimeout: number | null = null + let isScreenOn = true + const getCurrentTime = () => { void getPosition().then(position => { if (!position) return setNowPlayTime(position) if (!playerState.isPlay) return - if (settingState.setting['player.isSavePlayTime'] && !playerState.playMusicInfo.isTempPlay) { + if (settingState.setting['player.isSavePlayTime'] && !playerState.playMusicInfo.isTempPlay && isScreenOn) { delaySavePlayInfo() } }) @@ -57,6 +60,7 @@ export default () => { updateTimeout = null } const startUpdateTimeout = () => { + if (!isScreenOn) return clearUpdateTimeout() updateTimeout = BackgroundTimer.setInterval(() => { getCurrentTime() @@ -146,6 +150,13 @@ export default () => { if (keys.includes('player.playbackRate')) startUpdateTimeout() } + const handleScreenStateChanged: Parameters[0] = (state) => { + isScreenOn = state == 'ON' + if (isScreenOn) { + if (playerState.isPlay) startUpdateTimeout() + } else clearUpdateTimeout() + } + global.app_event.on('play', handlePlay) global.app_event.on('pause', handlePause) @@ -159,4 +170,6 @@ export default () => { // global.app_event.on('playerEmptied', handleEmpied) global.app_event.on('musicToggled', handleSetPlayInfo) global.state_event.on('configUpdated', handleConfigUpdated) + + onScreenStateChange(handleScreenStateChanged) } diff --git a/src/utils/nativeModules/utils.ts b/src/utils/nativeModules/utils.ts index 675657a..0bf30fa 100644 --- a/src/utils/nativeModules/utils.ts +++ b/src/utils/nativeModules/utils.ts @@ -1,4 +1,4 @@ -import { NativeModules } from 'react-native' +import { NativeEventEmitter, NativeModules } from 'react-native' const { UtilsModule } = NativeModules @@ -44,3 +44,14 @@ export const readFile = async(filePath: string): Promise => { export const getSystemLocales = async(): Promise => { return UtilsModule.getSystemLocales() } + +export const onScreenStateChange = (callback: (state: 'ON' | 'OFF') => void): () => void => { + const eventEmitter = new NativeEventEmitter(UtilsModule) + const eventListener = eventEmitter.addListener('screen-state', event => { + callback(event.state) + }) + + return () => { + eventListener.remove() + } +}