Я работаю над довольно простым приложением для будильников, которое использует android_alarm_manager для планирования сигналов и flutter_audio_query, чтобы собрать информацию о музыке, которая нужна мне для работы. Когда срабатывает будильник, мне нужно загрузить flutter_audio_query, чтобы иметь доступ к путям звуковых файлов, которые я хочу использовать.
Проблема, с которой я столкнулся в настоящее время, заключается в том, что плагин не загружается внутри обратного вызова, что вызывает исключение MissingPluginException. Это не похоже на проблему, например, с плагином PathProvider (который я изначально намеревался использовать для демонстрации ниже).
Попытка MCVE (создан новый проект Flutter с поддержкой Kotlin, AndroidX под Flutter Version 1.12.13 + hotfix.8; полный репозиторий здесь):
main.dart:
import 'package:android_alarm_manager/android_alarm_manager.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_audio_query/flutter_audio_query.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await AndroidAlarmManager.initialize();
runApp(MyApp());
Scheduler().setupAlarm();
// Runs because the FAQ plugin is loaded correctly.
final demoSongList = await FlutterAudioQuery().getSongs();
print('Main function: ${demoSongList.length}');
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(child: Text('Sample Text', textDirection: TextDirection.ltr,));
}
}
class Scheduler {
setupAlarm() async {
print('Setting up alarm!');
final success = await AndroidAlarmManager.oneShot(Duration(seconds: 3), 42, callback);
print(success);
}
static callback() async {
// Requires FAQ plugin to be loaded which it isn't.
final songs = await FlutterAudioQuery().getSongs();
print('Callback ${songs.length}!');
}
}
pubspec.yaml
name: stack_overflow_demo
description: A Demo Application demonstrating the issue with android_alarm_manager and plugins
version: 1.0.0+1
environment:
sdk: ">=2.1.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
android_alarm_manager: ^0.4.5+3
flutter_audio_query: ^0.3.3
dev_dependencies:
flutter_test:
sdk: flutter
flutter:
uses-material-design: true
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.github.geisterfurz007.stack_overflow_demo">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<application
android:name="io.flutter.app.FlutterApplication"
android:label="stack_overflow_demo"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
<service
android:name="io.flutter.plugins.androidalarmmanager.AlarmService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false"/>
<receiver
android:name="io.flutter.plugins.androidalarmmanager.AlarmBroadcastReceiver"
android:exported="false"/>
<receiver
android:name="io.flutter.plugins.androidalarmmanager.RebootBroadcastReceiver"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
</receiver>
</application>
</manifest>
Если требуются другие файлы, дайте мне знать; Я добавлю их, как только смогу!
Насколько я понимаю, с Android Embedding V2 (как заявлено в AndroidManifest.xml) все плагины должны загружаться через отражение, и создание моего собственного приложения для загрузки плагинов не требуется .
Теперь о самом вопросе этого вопроса: что заставляет плагин FlutterAudioQuery не загружаться в обратном вызове и как мне это изменить, чтобы я мог использовать его при срабатывании будильника?
Для прозрачности: после довольно низкого количества просмотров этого вопроса через день я решил открыть проблему Github в репозитории flutter здесь.