Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1aba004e43 | ||
|
|
cdf77b308d | ||
|
|
200067a3b2 |
@@ -7,6 +7,7 @@
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||
|
||||
<application
|
||||
android:name="${applicationName}"
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+25
@@ -8,6 +8,8 @@ import io.flutter.embedding.android.FlutterActivity
|
||||
import io.flutter.embedding.engine.FlutterEngine
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import java.io.File
|
||||
import android.content.Context
|
||||
import android.media.AudioManager
|
||||
|
||||
class MainActivity : FlutterActivity() {
|
||||
|
||||
@@ -32,9 +34,32 @@ class MainActivity : FlutterActivity() {
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
requestAudioFocus()
|
||||
|
||||
setHighRefreshRate()
|
||||
}
|
||||
|
||||
private fun requestAudioFocus() {
|
||||
val audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
audioManager.requestAudioFocus(
|
||||
AudioManager.OnAudioFocusChangeListener { focusChange ->
|
||||
Log.d("MainActivity", "音频焦点变化: $focusChange")
|
||||
},
|
||||
AudioManager.STREAM_MUSIC,
|
||||
AudioManager.AUDIOFOCUS_GAIN
|
||||
)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
audioManager.requestAudioFocus(
|
||||
null,
|
||||
AudioManager.STREAM_MUSIC,
|
||||
AudioManager.AUDIOFOCUS_GAIN
|
||||
)
|
||||
}
|
||||
Log.d("MainActivity", "✅ 已请求音频焦点")
|
||||
}
|
||||
|
||||
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
||||
super.configureFlutterEngine(flutterEngine)
|
||||
|
||||
@@ -20,7 +20,7 @@ pluginManagement {
|
||||
plugins {
|
||||
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
|
||||
id("com.android.application") version "9.0.1" apply false
|
||||
id("org.jetbrains.kotlin.android") version "2.2.20" apply false
|
||||
id("org.jetbrains.kotlin.android") version "2.3.20" apply false
|
||||
}
|
||||
|
||||
include(":app")
|
||||
|
||||
+67
-57
@@ -5,6 +5,7 @@ import 'package:media_kit/media_kit.dart';
|
||||
import 'package:audio_service/audio_service.dart' as audio_service;
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'services/audio_service.dart';
|
||||
import 'services/playback_service.dart';
|
||||
import 'services/app_lifecycle_service.dart';
|
||||
@@ -15,8 +16,8 @@ import 'pages/home_page.dart';
|
||||
import 'pages/player_page.dart';
|
||||
import 'pages/playlist_page.dart';
|
||||
import 'widgets/global_mini_player.dart';
|
||||
import 'utils/navigation.dart';
|
||||
|
||||
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||||
final stopwatch = Stopwatch();
|
||||
|
||||
bool _appInitialized = false;
|
||||
@@ -363,65 +364,74 @@ class _QTPlayerAppState extends State<QTPlayerApp> {
|
||||
debugPrint(
|
||||
'🎨 [QTPlayerApp] build #$_buildCount ${stopwatch.elapsedMilliseconds}ms');
|
||||
|
||||
return MaterialApp(
|
||||
title: '清听',
|
||||
theme: ThemeData(
|
||||
brightness: Brightness.dark,
|
||||
primaryColor: const Color(0xFF7C9A9E),
|
||||
colorScheme: const ColorScheme.dark(
|
||||
primary: Color(0xFF7C9A9E),
|
||||
secondary: Color(0xFFB8D4D0),
|
||||
surface: Color(0xFF1A1F1E),
|
||||
onSurface: Colors.white,
|
||||
),
|
||||
useMaterial3: true,
|
||||
// ⭐ 使用 AnnotatedRegion 包裹 MaterialApp,统一控制系统栏样式
|
||||
return AnnotatedRegion<SystemUiOverlayStyle>(
|
||||
value: SystemUiOverlayStyle(
|
||||
statusBarColor: Colors.transparent,
|
||||
statusBarIconBrightness: Brightness.light,
|
||||
systemNavigationBarColor: const Color(0xFF1A1F1E),
|
||||
systemNavigationBarIconBrightness: Brightness.light,
|
||||
),
|
||||
navigatorKey: navigatorKey,
|
||||
navigatorObservers: [MiniPlayerNavigatorObserver()],
|
||||
onGenerateRoute: _onGenerateRoute,
|
||||
builder: (context, child) {
|
||||
return Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
if (child != null) child,
|
||||
AnimatedBuilder(
|
||||
animation: RouteManager(),
|
||||
builder: (context, _) {
|
||||
final routeManager = RouteManager();
|
||||
final shouldShow = routeManager.currentRoute != '/player' &&
|
||||
routeManager.currentRoute != '/playlist';
|
||||
child: MaterialApp(
|
||||
title: '清听',
|
||||
theme: ThemeData(
|
||||
brightness: Brightness.dark,
|
||||
primaryColor: const Color(0xFF7C9A9E),
|
||||
colorScheme: const ColorScheme.dark(
|
||||
primary: Color(0xFF7C9A9E),
|
||||
secondary: Color(0xFFB8D4D0),
|
||||
surface: Color(0xFF1A1F1E),
|
||||
onSurface: Colors.white,
|
||||
),
|
||||
useMaterial3: true,
|
||||
),
|
||||
navigatorKey: navigatorKey,
|
||||
navigatorObservers: [MiniPlayerNavigatorObserver()],
|
||||
onGenerateRoute: _onGenerateRoute,
|
||||
builder: (context, child) {
|
||||
return Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
if (child != null) child,
|
||||
AnimatedBuilder(
|
||||
animation: RouteManager(),
|
||||
builder: (context, _) {
|
||||
final routeManager = RouteManager();
|
||||
final shouldShow = routeManager.currentRoute != '/player' &&
|
||||
routeManager.currentRoute != '/playlist';
|
||||
|
||||
return AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
switchInCurve: Curves.easeOut,
|
||||
switchOutCurve: Curves.easeIn,
|
||||
transitionBuilder: (child, animation) {
|
||||
return FadeTransition(
|
||||
opacity: animation,
|
||||
child: SlideTransition(
|
||||
position: Tween<Offset>(
|
||||
begin: const Offset(0, 0.1),
|
||||
end: Offset.zero,
|
||||
).animate(animation),
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
},
|
||||
child: shouldShow
|
||||
? const Align(
|
||||
key: ValueKey('mini_player_visible'),
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: GlobalMiniPlayer(),
|
||||
)
|
||||
: const SizedBox.shrink(
|
||||
key: ValueKey('mini_player_hidden'),
|
||||
return AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
switchInCurve: Curves.easeOut,
|
||||
switchOutCurve: Curves.easeIn,
|
||||
transitionBuilder: (child, animation) {
|
||||
return FadeTransition(
|
||||
opacity: animation,
|
||||
child: SlideTransition(
|
||||
position: Tween<Offset>(
|
||||
begin: const Offset(0, 0.1),
|
||||
end: Offset.zero,
|
||||
).animate(animation),
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
child: shouldShow
|
||||
? const Align(
|
||||
key: ValueKey('mini_player_visible'),
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: GlobalMiniPlayer(),
|
||||
)
|
||||
: const SizedBox.shrink(
|
||||
key: ValueKey('mini_player_hidden'),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||||
@@ -2,6 +2,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../services/audio_service.dart';
|
||||
import '../utils/navigation.dart'; // ⭐ 导入 navigatorKey
|
||||
|
||||
class GlobalMiniPlayer extends StatelessWidget {
|
||||
const GlobalMiniPlayer({super.key});
|
||||
@@ -45,11 +46,9 @@ class GlobalMiniPlayer extends StatelessWidget {
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
// ⭐ 使用 Navigator.of(context) 替代 navigatorKey
|
||||
Navigator.of(context, rootNavigator: true)
|
||||
.pushNamed('/player');
|
||||
// ⭐ 使用 navigatorKey 直接跳转
|
||||
navigatorKey.currentState?.pushNamed('/player');
|
||||
},
|
||||
// ⭐ 替换弃用的 withOpacity 为 withValues
|
||||
highlightColor: Colors.white.withValues(alpha: 0.05),
|
||||
splashColor: Colors.white.withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
@@ -124,8 +123,8 @@ class GlobalMiniPlayer extends StatelessWidget {
|
||||
size: 24,
|
||||
),
|
||||
onPressed: () {
|
||||
// ⭐ 使用 Navigator.of(context)
|
||||
Navigator.of(context).pushNamed('/playlist');
|
||||
// ⭐ 使用 navigatorKey 直接跳转
|
||||
navigatorKey.currentState?.pushNamed('/playlist');
|
||||
},
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
|
||||
@@ -32,7 +32,6 @@ dependencies:
|
||||
sdk: flutter
|
||||
media_kit: 1.2.6
|
||||
media_kit_libs_audio: ^1.0.7
|
||||
#media_kit_libs_android_audio: 1.3.8
|
||||
shared_preferences: 2.2.2
|
||||
provider: ^6.1.2
|
||||
dio: ^5.4.0 # HTTP 客户端
|
||||
|
||||
Reference in New Issue
Block a user