首页 > 解决方案 > Flutter:为 iOS 和 Android 添加应用更新对话框

问题描述

我目前正在开发通知功能,因此当有新的更新可用时,用户会看到一个对话框,他可以在其中选择是否更新。我正在使用 Firebase 远程配置来执行此操作,其中我有一个名为“force_update_current_version”的参数,然后我在其中添加版本的值以进行检查。但我确实收到以下错误。

感谢您的帮助,我祝您在新的一年里身体健康。

Main.dart 代码

import 'checkUpdate.dart';

@override
void initState() {
  try {
    versionCheck(**context**);
  } catch (e) {
    print(e);
  }
  **super**.initState();
}

上下文错误:未定义的名称“上下文”。尝试将名称更正为已定义的名称,或定义名称。

超级错误:“超级”调用的上下文无效。

checkUpdate.dart 代码

import 'package:flutter/material.dart';
import 'dart:io';
import 'package:firebase_remote_config/firebase_remote_config.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:package_info/package_info.dart';
import 'package:flutter/cupertino.dart';

const APP_STORE_URL = 'https://apps.apple.com/us/app/appname/idAPP-ID';
const PLAY_STORE_URL =
    'https://play.google.com/store/apps/details?id=APP-ID';

versionCheck(context) async {
  //Get Current installed version of app
  final PackageInfo info = await PackageInfo.fromPlatform();
  double currentVersion = double.parse(info.version.trim().replaceAll(".", ""));

  //Get Latest version info from firebase config
  final RemoteConfig remoteConfig = await RemoteConfig.instance;

  try {
    // Using default duration to force fetching from remote server.
    await remoteConfig.fetch(expiration: const Duration(seconds: 0));
    await remoteConfig.activateFetched();
    remoteConfig.getString('force_update_current_version');
    double newVersion = double.parse(remoteConfig
        .getString('force_update_current_version')
        .trim()
        .replaceAll(".", ""));
    if (newVersion > currentVersion) {
      _showVersionDialog(context);
    }
  } on FetchThrottledException catch (exception) {
    // Fetch throttled.
    print(exception);
  } catch (exception) {
    print('Unable to fetch remote config. Cached or default values will be '
        'used');
  }
}

//Show Dialog to force user to update
_showVersionDialog(context) async {
  await showDialog<String>(
    context: context,
    barrierDismissible: false,
    builder: (BuildContext context) {
      String title = "New Update Available";
      String message =
          "There is a newer version of app available please update it now.";
      String btnLabel = "Update Now";
      String btnLabelCancel = "Later";
      return Platform.isIOS
          ? new CupertinoAlertDialog(
              title: Text(title),
              content: Text(message),
              actions: <Widget>[
                FlatButton(
                  child: Text(btnLabel),
                  onPressed: () => _launchURL(**Config**.APP_STORE_URL),
                ),
                FlatButton(
                  child: Text(btnLabelCancel),
                  onPressed: () => Navigator.pop(context),
                ),
              ],
            )
          : new AlertDialog(
              title: Text(title),
              content: Text(message),
              actions: <Widget>[
                FlatButton(
                  child: Text(btnLabel),
                  onPressed: () => _launchURL(**Config**.PLAY_STORE_URL),
                ),
                FlatButton(
                  child: Text(btnLabelCancel),
                  onPressed: () => Navigator.pop(context),
                ),
              ],
            );
    },
  );
}

_launchURL(String url) async {
  if (await canLaunch(url)) {
    await launch(url);
  } else {
    throw 'Could not launch $url';
  }
}

App 和 Play 商店的配置错误:未定义的名称“配置”。尝试将名称更正为已定义的名称,或定义名称。

标签: androidiosflutterdart

解决方案


  1. checkUpdate.dart我们需要导入firebase_remote_config暴露RemoteConfig类的包:
import 'package:firebase_remote_config/firebase_remote_config.dart';

确保之前安装它

  1. versionCheck()函数应从 a 调用StatefulWidget,因此,调用它的好地方是在第一个 screen 内Widget,例如:

class FirstScreen extends StatefulWidget {
  const FirstScreen({ Key key }) : super(key: key);

  @override
  _FirstScreenState createState() => _FirstScreenState();
}

class _FirstScreenState extends State<FirstScreen> {
  @override
  void initState() {
     super.initState();
     WidgetsBinding.instance
      .addPostFrameCallback((_) => versionCheck(context));
  }
  @override
  Widget build(BuildContext context) {
    return Container(color: const Color(0xFFFFE306));
  }
}

推荐阅读