我正在制作一个带有抖动的警报应用程序,然后到达警报管理器调用我的背景飞镖代码的地方。有没有一种方法可以使用背景飞镖代码启动浮动页面?
我之前在android中构建了一个警报应用,而在android中,代码流是这样的: Alarm_Scheduler-> Alarm_Manager-> Intent-> Receiver-> Intent-> Activity
也在java android中,警报管理器在延迟后返回数据 但在颤抖的情况下,android_alarm_manager并未将ID赋予回调(或至少我没有尝试过)。
我的想法是扑朔迷离: Alarm_Scheduler-> Alarm_Manager-> Intent-> Receiver-> Intent-> Dart Isolate-> Intent-> Receiver-> Intent->新的Flutter Activity-> Flutter页面
但是我不认为有一种方法可以在不使用Persistence(设备存储)的情况下,向Flutter页面发送警报属性,例如音量或贪睡时间。
这是警报的当前回调代码:
import 'package:fanoos/application/interfaces/alarm/IAlarmStore.dart';
import 'package:fanoos/application/interfaces/dates/ICalendar.dart';
import 'package:fanoos/application/interfaces/dates/IDateFactory.dart';
import 'package:fanoos/common/DateType.dart';
import 'package:fanoos/infrastructure_flutter/App.dart';
class Tasks {
static IAlarmStore alarmStore;
static ICalendar calendar;
static IDateFactory dateFactory;
static Future prepare(){
App.backgroundTaskSetup();
}
static void initState(){
alarmStore = App.container.resolve<IAlarmStore>();
calendar = App.container.resolve<ICalendar>();
dateFactory = App.container.resolve<IDateFactory>();
}
static Future<void> alarm() async {
prepare();
initState();
/// find out what alarms could have called this
var now = DateTime.now();
var hour = now.hour;
var today = dateFactory.today(DateType.Miladi);
var thisWeekDay = calendar.weekDay(today);
var results = await alarmStore.searchAlarmByHour(hour);
var actives = results.where((alarm)=>alarm.active==true);
// alarms that happen today
var todays = actives.where((alarm){
if(!alarm.activeDays.contains(true)) return true;
if(alarm.activeDays[thisWeekDay-1]) return true;
return false;
});
// alarms before now
var beforeNow = todays.where((alarm){
var time = DateTime(now.year,now.month,now.day,alarm.hour,alarm.minute);
return time.isBefore(now);
}).toList();
// the nearest alarm to [now]
var selectedAlarm = beforeNow.first;
var alarmTime = DateTime(now.year,now.month,now.day,selectedAlarm.hour,selectedAlarm.minute);
var delta = now.difference(alarmTime);
for(var i=1;i<beforeNow.length;i++){
var alarm = beforeNow[i];
var time = DateTime(now.year,now.month,now.day,alarm.hour,alarm.minute);
var diff = now.difference(time);
if(diff<delta){
selectedAlarm = alarm;
delta = diff;
}
}
/// see if its valid
// see if its should go on
if(!selectedAlarm.active) return;
// check its function
if(selectedAlarm.function!='alarm') return;
/// run intended code
launchAlarmPage(); // not implemented
}
}
答案 0 :(得分:1)
在新版本的android_alarm_manager中,如果回调方法具有int参数,则会将ID传递给它。
要从后台启动Flutter页面,您应该从android端开始一个新的flutter活动,还可以为MaterialApp设置初始路线。
该过程将如下所示:
应用中的飞镖-> Android_Alarm_Manager->后台隔离中的飞镖->启动插件-> Flutter活动-> Flutter页面
启动器插件:
class LauncherPlugin: FlutterPlugin, MethodCallHandler {
companion object {
var context: Context? = null
var launched : Boolean = false
@JvmStatic
var tag : String = ""
@JvmStatic
val key: String = "fanoos/LauncherPlugin"
@JvmStatic
fun registerWith(registrar: PluginRegistry.Registrar) {
val channel = MethodChannel(registrar.messenger(), key)
context = registrar.activeContext()
channel.setMethodCallHandler(LauncherPlugin())
}
}
override fun onAttachedToEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
val channel = MethodChannel(binding.flutterEngine.dartExecutor, key)
context = binding.applicationContext
channel.setMethodCallHandler(LauncherPlugin())
}
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
when(call.method){
"getTag" -> {
result.success(tag)
}
"launch" -> {
try {
val route = call.argument<String>("route")!!
tag = call.argument("tag")!!
val intent = Intent(context, LaunchActivity::class.java).apply {
putExtra("route", route)
putExtra("destroy_engine_with_activity", true)
}
context!!.startActivity(intent)
launched = true
} catch (e: Exception){
Log.w("launcher",e.message)
result.error("12",e.message, e.localizedMessage)
} finally {
result.success(launched)
}
}
"launchedByPlugin" -> {
result.success(launched)
launched = false
}
else -> result.notImplemented()
}
}
}
颤振活动示例
class LaunchActivity : FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (Build.VERSION.SDK_INT > 26) {
setShowWhenLocked(true)
setTurnScreenOn(true)
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
keyguardManager.requestDismissKeyguard(this, null)
} else {
window.addFlags(
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
or WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
or WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON)
}
}
}
Dart插件:
class FanoosLauncher {
static const MethodChannel _channel = const MethodChannel('fanoos/LauncherPlugin');
static Future<String> get tag async => await _channel.invokeMethod('getTag');
static Future<bool> launch({String tag = '', String route = '/'}) async {
return await _channel.invokeMethod('launch',{
'tag' : tag,
'route' : route,
});
}
static bool _lbp;
static Future<bool> get launchedByPlugin async {
if (_lbp==null) {
_lbp = await _channel.invokeMethod('launchedByPlugin');
}
return _lbp;
}
}