优化息屏下的逻辑处理,尽量减少电量消耗

This commit is contained in:
lyswhut 2023-09-03 15:25:52 +08:00
parent b4ace82958
commit c921f08560
8 changed files with 96 additions and 10 deletions

View File

@ -13,6 +13,7 @@ import com.facebook.react.bridge.ReactApplicationContext;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Objects;
public class Lyric extends LyricPlayer { public class Lyric extends LyricPlayer {
LyricView lyricView = null; LyricView lyricView = null;
@ -48,7 +49,7 @@ public class Lyric extends LyricPlayer {
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
String strAction = intent.getAction(); String strAction = intent.getAction();
switch (strAction) { switch (Objects.requireNonNull(strAction)) {
case Intent.ACTION_SCREEN_OFF: case Intent.ACTION_SCREEN_OFF:
Log.d("Lyric", "ACTION_SCREEN_OFF"); Log.d("Lyric", "ACTION_SCREEN_OFF");
handleScreenOff(); handleScreenOff();

View File

@ -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);
}
}

View File

@ -4,8 +4,10 @@ import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.app.NotificationChannel; import android.app.NotificationChannel;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri; import android.net.Uri;
import android.net.wifi.WifiInfo; import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager; import android.net.wifi.WifiManager;
@ -19,12 +21,14 @@ import androidx.core.app.NotificationManagerCompat;
import androidx.core.content.FileProvider; import androidx.core.content.FileProvider;
import androidx.core.os.LocaleListCompat; import androidx.core.os.LocaleListCompat;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.UiThreadUtil; import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.bridge.WritableArray; import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeArray; import com.facebook.react.bridge.WritableNativeArray;
import java.io.File; import java.io.File;
@ -35,9 +39,13 @@ import java.util.Objects;
public class UtilsModule extends ReactContextBaseJavaModule { public class UtilsModule extends ReactContextBaseJavaModule {
private final ReactApplicationContext reactContext; private final ReactApplicationContext reactContext;
UtilsEvent utilsEvent;
UtilsModule(ReactApplicationContext reactContext) { UtilsModule(ReactApplicationContext reactContext) {
super(reactContext); super(reactContext);
this.reactContext = reactContext; this.reactContext = reactContext;
utilsEvent = new UtilsEvent(reactContext);
registerScreenBroadcastReceiver();
} }
@Override @Override
@ -45,6 +53,36 @@ public class UtilsModule extends ReactContextBaseJavaModule {
return "UtilsModule"; 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 @ReactMethod
public void exitApp() { public void exitApp() {
// https://github.com/wumke/react-native-exit-app/blob/master/android/src/main/java/com/github/wumke/RNExitApp/RNExitAppModule.java // https://github.com/wumke/react-native-exit-app/blob/master/android/src/main/java/com/github/wumke/RNExitApp/RNExitAppModule.java

12
package-lock.json generated
View File

@ -26,7 +26,7 @@
"react-native-pager-view": "^6.2.1", "react-native-pager-view": "^6.2.1",
"react-native-quick-base64": "^2.0.7", "react-native-quick-base64": "^2.0.7",
"react-native-quick-md5": "^3.0.5", "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" "react-native-vector-icons": "^10.0.0"
}, },
"devDependencies": { "devDependencies": {
@ -9542,8 +9542,8 @@
}, },
"node_modules/react-native-track-player": { "node_modules/react-native-track-player": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "git+ssh://git@github.com/lyswhut/react-native-track-player.git#45aa27463844ee836b31322f987ff3981acf8c59", "resolved": "git+ssh://git@github.com/lyswhut/react-native-track-player.git#4c61871ef85440b8ce52143fb8d1abfe7c5f1ab7",
"integrity": "sha512-a0WPgO+tpR6WBFNDUw8GapR1eUkqe7N7jtEKpVq1WdeDDXRz5Sx36CZK2Q9Ux4raWoey46ATPvo41zwjaL02Wg==", "integrity": "sha512-2nAbgRWVH5SOcaf5TJZK0AXYtlLURWRX51rxRP8slolXujZNiHqDpXYr6s2tFGQziUcLLYZoRTtmH51ehqSI9A==",
"license": "Apache-2.0", "license": "Apache-2.0",
"peerDependencies": { "peerDependencies": {
"react": ">=16.8.6", "react": ">=16.8.6",
@ -17993,9 +17993,9 @@
} }
}, },
"react-native-track-player": { "react-native-track-player": {
"version": "git+ssh://git@github.com/lyswhut/react-native-track-player.git#45aa27463844ee836b31322f987ff3981acf8c59", "version": "git+ssh://git@github.com/lyswhut/react-native-track-player.git#4c61871ef85440b8ce52143fb8d1abfe7c5f1ab7",
"integrity": "sha512-a0WPgO+tpR6WBFNDUw8GapR1eUkqe7N7jtEKpVq1WdeDDXRz5Sx36CZK2Q9Ux4raWoey46ATPvo41zwjaL02Wg==", "integrity": "sha512-2nAbgRWVH5SOcaf5TJZK0AXYtlLURWRX51rxRP8slolXujZNiHqDpXYr6s2tFGQziUcLLYZoRTtmH51ehqSI9A==",
"from": "react-native-track-player@github:lyswhut/react-native-track-player#45aa27463844ee836b31322f987ff3981acf8c59", "from": "react-native-track-player@github:lyswhut/react-native-track-player#4c61871ef85440b8ce52143fb8d1abfe7c5f1ab7",
"requires": {} "requires": {}
}, },
"react-native-vector-icons": { "react-native-vector-icons": {

View File

@ -60,7 +60,7 @@
"react-native-pager-view": "^6.2.1", "react-native-pager-view": "^6.2.1",
"react-native-quick-base64": "^2.0.7", "react-native-quick-base64": "^2.0.7",
"react-native-quick-md5": "^3.0.5", "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" "react-native-vector-icons": "^10.0.0"
}, },
"devDependencies": { "devDependencies": {

View File

@ -24,6 +24,7 @@
- 优化数据传输逻辑,列表同步指令使用队列机制,保证列表同步操作的顺序 - 优化数据传输逻辑,列表同步指令使用队列机制,保证列表同步操作的顺序
- 暂停播放时播放详情歌词页不要自动滚动歌词回播放位置 - 暂停播放时播放详情歌词页不要自动滚动歌词回播放位置
- 播放详情页歌词添加延迟滚动及着色动画 - 播放详情页歌词添加延迟滚动及着色动画
- 优化息屏下的逻辑处理,尽量减少电量消耗
### 修复 ### 修复

View File

@ -7,6 +7,7 @@ import { throttleBackgroundTimer } from '@/utils/tools'
import BackgroundTimer from 'react-native-background-timer' import BackgroundTimer from 'react-native-background-timer'
import playerState from '@/store/player/state' import playerState from '@/store/player/state'
import settingState from '@/store/setting/state' import settingState from '@/store/setting/state'
import { onScreenStateChange } from '@/utils/nativeModules/utils'
const delaySavePlayInfo = throttleBackgroundTimer(() => { const delaySavePlayInfo = throttleBackgroundTimer(() => {
void savePlayInfo({ void savePlayInfo({
@ -22,13 +23,15 @@ export default () => {
let updateTimeout: number | null = null let updateTimeout: number | null = null
let isScreenOn = true
const getCurrentTime = () => { const getCurrentTime = () => {
void getPosition().then(position => { void getPosition().then(position => {
if (!position) return if (!position) return
setNowPlayTime(position) setNowPlayTime(position)
if (!playerState.isPlay) return if (!playerState.isPlay) return
if (settingState.setting['player.isSavePlayTime'] && !playerState.playMusicInfo.isTempPlay) { if (settingState.setting['player.isSavePlayTime'] && !playerState.playMusicInfo.isTempPlay && isScreenOn) {
delaySavePlayInfo() delaySavePlayInfo()
} }
}) })
@ -57,6 +60,7 @@ export default () => {
updateTimeout = null updateTimeout = null
} }
const startUpdateTimeout = () => { const startUpdateTimeout = () => {
if (!isScreenOn) return
clearUpdateTimeout() clearUpdateTimeout()
updateTimeout = BackgroundTimer.setInterval(() => { updateTimeout = BackgroundTimer.setInterval(() => {
getCurrentTime() getCurrentTime()
@ -146,6 +150,13 @@ export default () => {
if (keys.includes('player.playbackRate')) startUpdateTimeout() if (keys.includes('player.playbackRate')) startUpdateTimeout()
} }
const handleScreenStateChanged: Parameters<typeof onScreenStateChange>[0] = (state) => {
isScreenOn = state == 'ON'
if (isScreenOn) {
if (playerState.isPlay) startUpdateTimeout()
} else clearUpdateTimeout()
}
global.app_event.on('play', handlePlay) global.app_event.on('play', handlePlay)
global.app_event.on('pause', handlePause) global.app_event.on('pause', handlePause)
@ -159,4 +170,6 @@ export default () => {
// global.app_event.on('playerEmptied', handleEmpied) // global.app_event.on('playerEmptied', handleEmpied)
global.app_event.on('musicToggled', handleSetPlayInfo) global.app_event.on('musicToggled', handleSetPlayInfo)
global.state_event.on('configUpdated', handleConfigUpdated) global.state_event.on('configUpdated', handleConfigUpdated)
onScreenStateChange(handleScreenStateChanged)
} }

View File

@ -1,4 +1,4 @@
import { NativeModules } from 'react-native' import { NativeEventEmitter, NativeModules } from 'react-native'
const { UtilsModule } = NativeModules const { UtilsModule } = NativeModules
@ -44,3 +44,14 @@ export const readFile = async(filePath: string): Promise<string> => {
export const getSystemLocales = async(): Promise<string> => { export const getSystemLocales = async(): Promise<string> => {
return UtilsModule.getSystemLocales() 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()
}
}