Класс Activity, объявленный в вашем AndroidManifest.xml, неверен или не предоставил правильный FlutterEngine.Android

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Класс Activity, объявленный в вашем AndroidManifest.xml, неверен или не предоставил правильный FlutterEngine.

Сообщение Anonymous »

мне нужно работать со звуком в фоновом режиме
это код
файл audio_handler

Код: Выделить всё

import 'package:audio_service/audio_service.dart';
import 'package:just_audio/just_audio.dart';

Future initAudioService() async {
return await AudioService.init(
builder: () => MyAudioHandler(),
config: const AudioServiceConfig(
androidNotificationChannelId: 'com.mycompany.myapp.audio',
androidNotificationChannelName: 'Audio Service Demo',
androidNotificationOngoing: true,
androidStopForegroundOnPause: true,
),
);
}

class MyAudioHandler extends BaseAudioHandler {
final _player = AudioPlayer();
final _playlist = ConcatenatingAudioSource(children: []);

MyAudioHandler() {
_loadEmptyPlaylist();
_notifyAudioHandlerAboutPlaybackEvents();
_listenForDurationChanges();
_listenForCurrentSongIndexChanges();
_listenForSequenceStateChanges();
}

Future _loadEmptyPlaylist() async {
try {
await _player.setAudioSource(_playlist);
} catch (e) {
print("Error: $e");
}
}

void _notifyAudioHandlerAboutPlaybackEvents() {
_player.playbackEventStream.listen((PlaybackEvent event) {
final playing = _player.playing;
playbackState.add(playbackState.value.copyWith(
controls: [
MediaControl.skipToPrevious,
if (playing) MediaControl.pause else MediaControl.play,
MediaControl.stop,
MediaControl.skipToNext,
],
systemActions: const {
MediaAction.seek,
},
androidCompactActionIndices: const [0, 1, 3],
processingState: const {
ProcessingState.idle: AudioProcessingState.idle,
ProcessingState.loading: AudioProcessingState.loading,
ProcessingState.buffering: AudioProcessingState.buffering,
ProcessingState.ready: AudioProcessingState.ready,
ProcessingState.completed: AudioProcessingState.completed,
}[_player.processingState]!,
repeatMode: const {
LoopMode.off: AudioServiceRepeatMode.none,
LoopMode.one: AudioServiceRepeatMode.one,
LoopMode.all: AudioServiceRepeatMode.all,
}[_player.loopMode]!,
shuffleMode: (_player.shuffleModeEnabled)
? AudioServiceShuffleMode.all
: AudioServiceShuffleMode.none,
playing: playing,
updatePosition: _player.position,
bufferedPosition: _player.bufferedPosition,
speed: _player.speed,
queueIndex: event.currentIndex,
));
});
}

void _listenForDurationChanges() {
_player.durationStream.listen((duration) {
var index = _player.currentIndex;
final newQueue = queue.value;
if (index == null || newQueue.isEmpty) return;
if (_player.shuffleModeEnabled) {
index = _player.shuffleIndices!.indexOf(index);
}
final oldMediaItem = newQueue[index];
final newMediaItem = oldMediaItem.copyWith(duration: duration);
newQueue[index] = newMediaItem;
queue.add(newQueue);
mediaItem.add(newMediaItem);
});
}

void _listenForCurrentSongIndexChanges() {
_player.currentIndexStream.listen((index) {
final playlist = queue.value;
if (index == null || playlist.isEmpty) return;
if (_player.shuffleModeEnabled) {
index = _player.shuffleIndices!.indexOf(index);
}
mediaItem.add(playlist[index]);
});
}

void _listenForSequenceStateChanges() {
_player.sequenceStateStream.listen((SequenceState? sequenceState) {
final sequence = sequenceState?.effectiveSequence;
if (sequence == null || sequence.isEmpty) return;
final items = sequence.map((source) => source.tag as MediaItem);
queue.add(items.toList());
});
}

@override
Future addQueueItems(List mediaItems) async {
// manage Just Audio
final audioSource = mediaItems.map(_createAudioSource);
_playlist.addAll(audioSource.toList());

// notify system
final newQueue = queue.value..addAll(mediaItems);
queue.add(newQueue);
}

@override
Future  addQueueItem(MediaItem mediaItem) async {
// manage Just Audio
final audioSource = _createAudioSource(mediaItem);
_playlist.add(audioSource);

// notify system
final newQueue = queue.value..add(mediaItem);
queue.add(newQueue);
}

UriAudioSource _createAudioSource(MediaItem mediaItem) {
return AudioSource.uri(
Uri.parse(mediaItem.extras!['url'] as String),
tag: mediaItem,
);
}

@override
Future removeQueueItemAt(int index) async {
// manage Just Audio
_playlist.removeAt(index);

// notify system
final newQueue = queue.value..removeAt(index);
queue.add(newQueue);
}

@override
Future play() => _player.play();

@override
Future pause() => _player.pause();

@override
Future seek(Duration position) => _player.seek(position);

@override
Future skipToQueueItem(int index) async {
if (index < 0 || index >= queue.value.length) return;
if (_player.shuffleModeEnabled) {
index = _player.shuffleIndices![index];
}
_player.seek(Duration.zero, index: index);
}

@override
Future skipToNext() => _player.seekToNext();

@override
Future skipToPrevious() => _player.seekToPrevious();

@override
Future setRepeatMode(AudioServiceRepeatMode repeatMode) async {
switch (repeatMode) {
case AudioServiceRepeatMode.none:
_player.setLoopMode(LoopMode.off);
break;
case AudioServiceRepeatMode.one:
_player.setLoopMode(LoopMode.one);
break;
case AudioServiceRepeatMode.group:
case AudioServiceRepeatMode.all:
_player.setLoopMode(LoopMode.all);
break;
}
}

@override
Future setShuffleMode(AudioServiceShuffleMode shuffleMode) async {
if (shuffleMode == AudioServiceShuffleMode.none) {
_player.setShuffleModeEnabled(false);
} else {
await _player.shuffle();
_player.setShuffleModeEnabled(true);
}
}

@override
Future customAction(String name, [Map? extras]) async {
if (name == 'dispose') {
await _player.dispose();
super.stop();
}
}

@override
Future stop() async {
await _player.stop();
return super.stop();
}
}
Файл Service_Locator

Код: Выделить всё

import 'package:audio_service/audio_service.dart';
import '../page_manager.dart';
import 'audio_handler.dart';
import 'playlist_repository.dart';
import 'package:get_it/get_it.dart';

GetIt getIt = GetIt.instance;

Future setupServiceLocator() async {
// services
getIt.registerSingleton(await initAudioService());
getIt.registerLazySingleton
(() => DemoPlaylist());

// page state
getIt.registerLazySingleton(() => PageManager());
}
аудиофайл вызова

Код: Выделить всё

class Audio_Calling extends StatefulWidget {
const Audio_Calling({super.key});

@override
State createState() => _Audio_CallingState();
}

class _Audio_CallingState extends State  {
@override
void initState() {
super.initState();

getIt().init();
}

@override
void dispose() {
getIt().dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: const [
CurrentSongTitle(),
Playlist(),
AddRemoveSongButtons(),
AudioProgressBar(),
AudioControlButtons(),
],
),
),
),
);
}
}
файл менеджера страниц

Код: Выделить всё

class PageManager {
// Listeners: Updates going to the UI
final currentSongTitleNotifier = ValueNotifier('');
final playlistNotifier = ValueNotifier([]);
final progressNotifier = ProgressNotifier();
final repeatButtonNotifier = RepeatButtonNotifier();
final isFirstSongNotifier = ValueNotifier(true);
final playButtonNotifier = PlayButtonNotifier();
final isLastSongNotifier = ValueNotifier(true);
final isShuffleModeEnabledNotifier = ValueNotifier(false);

final _audioHandler = getIt();

// Events: Calls coming from the UI
void init() async {
await _loadPlaylist();
_listenToChangesInPlaylist();
_listenToPlaybackState();
_listenToCurrentPosition();
_listenToBufferedPosition();
_listenToTotalDuration();
_listenToChangesInSong();
}

Future _loadPlaylist() async {
final songRepository = getIt();
final playlist = await songRepository.fetchInitialPlaylist();
final mediaItems = playlist
.map((song) => MediaItem(
id: song['id'] ?? '',
album: song['album'] ?? '',
title: song['title'] ?? '',
extras: {'url': song['url']},
))
.toList();
_audioHandler.addQueueItems(mediaItems);
}

void _listenToChangesInPlaylist() {
_audioHandler.queue.listen((playlist) {
if (playlist.isEmpty) {
playlistNotifier.value = [];
currentSongTitleNotifier.value = '';
} else {
final newList = playlist.map((item) =>  item.title).toList();
playlistNotifier.value = newList;
}
_updateSkipButtons();
});
}

void _listenToPlaybackState() {
_audioHandler.playbackState.listen((playbackState) {
final isPlaying = playbackState.playing;
final processingState = playbackState.processingState;
if (processingState == AudioProcessingState.loading ||
processingState == AudioProcessingState.buffering) {
playButtonNotifier.value = ButtonState.loading;
} else if (!isPlaying) {
playButtonNotifier.value = ButtonState.paused;
} else if (processingState != AudioProcessingState.completed) {
playButtonNotifier.value = ButtonState.playing;
} else {
_audioHandler.seek(Duration.zero);
_audioHandler.pause();
}
});
}

void _listenToCurrentPosition() {
AudioService.position.listen((position) {
final oldState = progressNotifier.value;
progressNotifier.value = ProgressBarState(
current: position,
buffered: oldState.buffered,
total: oldState.total,
);
});
}

void _listenToBufferedPosition() {
_audioHandler.playbackState.listen((playbackState) {
final oldState = progressNotifier.value;
progressNotifier.value = ProgressBarState(
current: oldState.current,
buffered: playbackState.bufferedPosition,
total: oldState.total,
);
});
}

void _listenToTotalDuration() {
_audioHandler.mediaItem.listen((mediaItem) {
final oldState = progressNotifier.value;
progressNotifier.value = ProgressBarState(
current: oldState.current,
buffered: oldState.buffered,
total: mediaItem?.duration ?? Duration.zero,
);
});
}

void _listenToChangesInSong() {
_audioHandler.mediaItem.listen((mediaItem) {
currentSongTitleNotifier.value = mediaItem?.title ?? '';
_updateSkipButtons();
});
}

void _updateSkipButtons() {
final mediaItem = _audioHandler.mediaItem.value;
final playlist = _audioHandler.queue.value;
if (playlist.length < 2 || mediaItem == null) {
isFirstSongNotifier.value = true;
isLastSongNotifier.value = true;
} else {
isFirstSongNotifier.value = playlist.first == mediaItem;
isLastSongNotifier.value = playlist.last == mediaItem;
}
}

void play() => _audioHandler.play();
void pause() => _audioHandler.pause();

void seek(Duration position) => _audioHandler.seek(position);

void previous() => _audioHandler.skipToPrevious();
void next() => _audioHandler.skipToNext();

void repeat() {
repeatButtonNotifier.nextState();
final repeatMode = repeatButtonNotifier.value;
switch (repeatMode) {
case RepeatState.off:
_audioHandler.setRepeatMode(AudioServiceRepeatMode.none);
break;
case RepeatState.repeatSong:
_audioHandler.setRepeatMode(AudioServiceRepeatMode.one);
break;
case RepeatState.repeatPlaylist:
_audioHandler.setRepeatMode(AudioServiceRepeatMode.all);
break;
}
}

void shuffle() {
final enable = !isShuffleModeEnabledNotifier.value;
isShuffleModeEnabledNotifier.value = enable;
if (enable) {
_audioHandler.setShuffleMode(AudioServiceShuffleMode.all);
} else {
_audioHandler.setShuffleMode(AudioServiceShuffleMode.none);
}
}

Future add() async {
final songRepository = getIt();
final song = await songRepository.fetchAnotherSong();
final mediaItem = MediaItem(
id: song['id'] ?? '',
album: song['album'] ?? '',
title: song['title'] ?? '',
extras: {'url': song['url']},
);
_audioHandler.addQueueItem(mediaItem);
}

void remove() {
final lastIndex = _audioHandler.queue.value.length - 1;
if (lastIndex <  0) return;
_audioHandler.removeQueueItemAt(lastIndex);
}

void dispose() {
_audioHandler.customAction('dispose');
}

void stop() {
_audioHandler.stop();
}
}
основной

Код: Выделить всё

void main() async {
BlocOverrides.runZoned(
() async {
WidgetsFlutterBinding.ensureInitialized();
await setupServiceLocator();

runApp(Audio_Calling());
})}
когда я запускаю свой код, я получаю эту ошибку:
PlatformException (PlatformException(Класс Activity, объявленный в вашем AndroidManifest.xml, неверен или не предоставил правильный FlutterEngine. См. README для инструкций., null, null, null))
Изображение
как это решить


Подробнее здесь: https://stackoverflow.com/questions/758 ... s-not-prov
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»