我正在使用firebase_dynamic_links:^ 0.5.0在我的flutter应用程序中实现设置密码功能。由管理员创建用户时,用户会收到一封电子邮件。这封电子邮件中有一个动态链接。单击后,用户将被重定向到 1.应用商店/游戏商店(如果他/她没有应用)。 2.如果已安装应用程序,则在应用程序中打开设置密码屏幕。 firebase_dynamic_links提供了两种方法: 1.getInitialLink将来以检索打开应用程序的链接。 2.onLink回调可监听在应用程序处于活动状态或后台时打开的链接。
当应用程序处于终止状态并按下链接时,一切都会顺利进行,但是当应用程序处于后台时,导航将无法正常工作。
void main() => runApp(MaterialApp(
theme: new ThemeData(
primaryColor: Colours.appThemeColour,
),
onGenerateRoute: (RouteSettings settings) {
switch (settings.name) {
case '/': return new MyCustomRoute(
builder: (_) => new SplashScreen(),
settings: settings,
);
case '/setpassword': return new MyCustomRoute(
builder: (_) => new SetPassword(settings.arguments),
settings: settings,
);
...
}
}
)
);
class SplashScreen extends StatefulWidget {
@override
_SplashScreenState createState() => new _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
Uri deepLink;
_handleDeepLink(Uri deepLink) async{
if (deepLink != null) {
print("querParam=${deepLink.queryParameters["token"]}");
if(deepLink.queryParameters["otp"].toString()=="1"){
if(deepLink.queryParameters["token"]!=null){
String _status =await _networkUtil.verifyUser(deepLink.queryParameters["token"].toString());
Navigator.of(context).pushReplacementNamed('/setpassword',arguments: _status );
}else{
Navigator.of(context).pushReplacementNamed('/setpassword',arguments: "unknownError" );
}
}
else{
if(deepLink.queryParameters["token"]!=null){
String _status =await _networkUtil.verifyUser(deepLink.queryParameters["token"].toString());
SchedulerBinding.instance.addPostFrameCallback((_) {
Navigator.of(context).pushReplacementNamed('/resetpassword');
});
}else{
Navigator.of(context).pushReplacementNamed('/resetpassword');
}
}
}
}
}
initDynamicLinks() async {
final PendingDynamicLinkData data = await FirebaseDynamicLinks.instance.getInitialLink();
final Uri deepLink = data?.link;
if (deepLink != null) {
_handleDeepLink(deepLink);
}
FirebaseDynamicLinks.instance.onLink(
onSuccess: (PendingDynamicLinkData dynamicLink) async {
final Uri deepLink = dynamicLink?.link;
_handleDeepLink(deepLink);
},
onError: (OnLinkErrorException e) async {
print('onLinkError');
print(e.message);
}
);
}
@override
initState(){
initDynamicLinks().then((){
...
});
}
当应用程序处于后台并且单击链接时,它应该导航到设置密码屏幕,但是(通过我在下面提到的一个例外)进入到将应用程序移至后台时打开的屏幕。
D / ViewRootImpl @ 5c26021MainActivity:MSG_WINDOW_FOCUS_CHANGED 0 D / SurfaceView(25703):返回中继:oldFrame = [0,0] [1440,2560] newFrame = [0,0] [1440,2560] result = 0x5 surface = {Surface(name = null)/ @ 0x54b5e07 isValid = false 0} D / ViewRootImpl @ 5c26021MainActivity:mHardwareRenderer.destroy()#1 D / ViewRootImpl @ 5c26021MainActivity:中继返回:oldFrame = [0,0] [1440,2560] newFrame = [0,0] [1440,2560] result = 0x5 surface = {isValid = false 0} surfaceGenerationChanged = true D / InputTransport(25703):输入通道损坏:fd = 92 D / ViewRootImpl @ 5c26021MainActivity:mHardwareRenderer.destroy()#1 D / ViewRootImpl @ 5c26021MainActivity:中继返回:oldFrame = [0,0] [1440,2560] newFrame = [0,0] [1440,2560] result = 0x1 surface = {isValid = false 0} surfaceGenerationChanged = false D / ViewRootImpl @ 5c26021MainActivity:mHardwareRenderer.destroy()#1 D / ViewRootImpl @ 5c26021MainActivity:中继返回:oldFrame = [0,0] [1440,2560] newFrame = [0,0] [1440,2560] result = 0x1 surface = {isValid = false 0} surfaceGenerationChanged = false D / SurfaceView(25703):返回中继:oldFrame = [0,0] [1440,2560] newFrame = [0,0] [1440,2560] result = 0x7 surface = {Surface(name = null)/ @ 0x54b5e07 isValid = true 543154356736} D / mali_winsys(25703):EGLint new_window_surface(egl_winsys_display *,void *,EGLSurface,EGLConfig,egl_winsys_surface **,egl_color_buffer_format *,EGLBoolean)返回0x3000,[1440x2560] -format:1 I / Flutter(25703):querParam = e144efdbd666e615a47ebe18e25a556d D / ViewRootImpl @ 5c26021MainActivity:中继返回:oldFrame = [0,0] [1440,2560] newFrame = [0,0] [1440,2560] result = 0x7 surface = {isValid = true 542519654912} surfaceGenerationChanged = true D / ViewRootImpl @ 5c26021MainActivity:mHardwareRenderer.initialize()mSurface = {isValid = true 542519654912} hwInitialized = true D / mali_winsys(25703):EGLint new_window_surface(egl_winsys_display *,void *,EGLSurface,EGLConfig,egl_winsys_surface **,egl_color_buffer_format *,EGLBoolean)返回0x3000,[1440x2560] -format:1 D / ViewRootImpl @ 5c26021MainActivity:MSG_WINDOW_FOCUS_CHANGED 1 D / ViewRootImpl @ 5c26021MainActivity:mHardwareRenderer.initializeIfNeeded()#2 mSurface = {isValid = true 542519654912} V / InputMethodManager(25703):开始输入:tba=android.view.inputmethod.EditorInfo@6fb193a nm:com.root.amployee ic = null I / InputMethodManager(25703):[IMM] startInputInner-mService.startInputOrWindowGainedFocus D / InputTransport(25703):构造的输入通道:fd = 93
E / flutter(25703):[错误:flutter / lib / ui / ui_dart_state.cc(148)]未处理的异常:NoSuchMethodError:方法'ancestorStateOfType'被调用为null。 E / flutter(25703):接收者:null E / flutter(25703):尝试调用:ancestorStateOfType(“ TypeMatcher”的实例) E / flutter(25703):#0 Object.noSuchMethod(dart:core-patch / object_patch.dart:50:5)
答案 0 :(得分:0)
这是库本身的问题。由于您当前无法访问context
,因此无法访问。因此,我建议您在MaterialApp
或CupertinoApp
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final _navigatorKey = GlobalKey<NavigatorState>();
@override
Widget build(BuildContext context) {
return MaterialApp(
key: _navigatorKey,
home: Container(),
);
}
}