有没有一种方法可以使用alarm_manager启动活动页面?

时间:2019-07-28 16:48:31

标签: android flutter

我正在制作一个带有抖动的警报应用程序,然后到达警报管理器调用我的背景飞镖代码的地方。有没有一种方法可以使用背景飞镖代码启动浮动页面?

我之前在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
  }

}

1 个答案:

答案 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;
  }
}