Flutter应用安装插件flutter_install_app的使用

发布于 1周前 作者 nodeper 来自 Flutter

Flutter应用安装插件flutter_install_app的使用

flutter_app_installer 是一个用于安装和/或更新应用的Flutter插件。它支持Android和iOS平台,但并非所有方法都适用于所有平台。

该插件是基于app_installer的分支。

iOS

  • 打开App Store应用页面
  • 打开App Store应用评论

Android

  • 打开Google Play应用页面
  • 安装APK文件(检测未知来源)

开始使用

打开App Store

/// 应用信息
String androidAppId = 'com.felipheallef.tasks';
String iOSAppId = '324684580';

AppInstaller.goStore(androidAppId, iOSAppId);

打开评论

AppInstaller.goStore(androidAppId, iOSAppId, review: true);

安装APK(仅限Android)

从设备存储

AppInstaller.installApk('/sdcard/apk/app-debug.apk');

注意: 需要先允许读取存储权限,否则会解析错误。

从资源包

final file = DefaultAssetBundle.of(context).load('assets/apk/app-debug.apk');
final bytes = file.buffer.asUint8List();
AppInstaller.installApkBytes(bytes);

无需用户操作(Android 12及以上版本)

AppInstaller.installApk('/sdcard/apk/app-debug.apk', actionRequired: false);

注意:

  • 如果设置了actionRequiredfalse,当满足以下条件时,用户操作将不再需要:
    • 被安装的应用针对API 30及以上版本,并且运行在Android 12及以上版本;
    • 应用是现有版本应用的安装记录者(即此安装会话是一个应用更新)或者安装程序正在更新自身;
    • 安装程序声明了UPDATE_PACKAGES_WITHOUT_USER_ACTION权限。

AndroidManifest.xml

<!-- Provider -->
<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="${applicationId}.fileProvider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

android/app/src/main/res/xml/file_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path path="Android/data/packagename/" name="files_root" />
    <external-path path="." name="external_storage_root" />
</paths>

// 替换packagename为你的应用包名

问题和反馈

如需提交反馈或报告错误,请在这里提交问题。感谢您的支持!


示例代码

example/lib/main.dart

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_install_app/flutter_install_app.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String androidAppId = 'com.felipheallef.tasks';
  String iOSAppId = '324684580';

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('插件示例应用'),
        ),
        body: Center(
          child: Column(
            children: <Widget>[
              SizedBox(height: 80),
              TextButton.icon(
                onPressed: () {
                  AppInstaller.goStore(androidAppId, iOSAppId);
                },
                icon: Icon(Icons.store),
                label: Text('前往商店'),
              ),
              SizedBox(height: 40),
              TextButton.icon(
                onPressed: () {
                  AppInstaller.goStore(androidAppId, iOSAppId, review: true);
                },
                icon: Icon(Icons.rate_review),
                label: Text('前往商店评论'),
              ),
              SizedBox(height: 40),
              TextButton.icon(
                onPressed: () async {
                  final apk = await rootBundle.load('assets/app-release.apk');
                  final bytes = apk.buffer.asUint8List();
                  AppInstaller.installApkBytes(bytes, actionRequired: false);
                },
                icon: Icon(Icons.arrow_downward),
                label: Text('从资源包安装APK'),
              ),
              SizedBox(height: 40),
              TextButton.icon(
                onPressed: () async {
                  final apk = await rootBundle.load('assets/app-release.apk');
                  final appDocDir = await getApplicationDocumentsDirectory();
                  final bytes = apk.buffer.asUint8List();

                  final path = join(appDocDir.path, 'app-release.apk');

                  File(path)
                    ..createSync()
                    ..writeAsBytesSync(bytes);

                  AppInstaller.installApk(path, actionRequired: false);
                },
                icon: Icon(Icons.arrow_downward),
                label: Text('从存储安装APK'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

更多关于Flutter应用安装插件flutter_install_app的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter应用安装插件flutter_install_app的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter应用中使用flutter_install_app插件的示例代码。这个插件允许你从Flutter应用中安装APK文件。

首先,确保你已经在pubspec.yaml文件中添加了flutter_install_app依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_install_app: ^x.y.z  # 请替换为最新版本号

然后运行flutter pub get来安装依赖。

接下来,在你的Flutter项目中,你可以按照以下方式使用flutter_install_app插件:

import 'package:flutter/material.dart';
import 'package:flutter_install_app/flutter_install_app.dart';
import 'dart:io';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Install App Example'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                onPressed: _installApp,
                child: Text('Install APK'),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Future<void> _installApp() async {
    // 这里假设APK文件已经存在于设备的某个路径,或者你可以从网络下载APK文件到本地路径
    String apkFilePath = '/storage/emulated/0/Download/example.apk';  // 请替换为实际的APK文件路径

    File apkFile = File(apkFilePath);
    if (await apkFile.exists()) {
      bool result = await FlutterInstallApp.installApk(apkPath: apkFilePath);
      if (result) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('APK安装成功!')),
        );
      } else {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('APK安装失败!')),
        );
      }
    } else {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('APK文件不存在!')),
      );
    }
  }
}

注意事项:

  1. APK文件路径:在上面的代码中,APK文件的路径是硬编码的。在实际应用中,你可能需要从服务器下载APK文件到本地存储,或者使用设备存储中已有的APK文件。

  2. 权限问题:确保你的应用有读取存储权限,尤其是在Android 6.0及以上版本中,需要在运行时请求权限。

  3. 设备兼容性:这个插件在Android设备上有效,但在iOS上无效,因为iOS不允许从第三方应用中直接安装应用。

  4. 错误处理:在实际应用中,应该添加更多的错误处理逻辑,比如处理文件读取失败、安装失败等情况。

  5. 调试:在调试时,确保你的APK文件是有效的,并且路径是正确的。你可以先在文件管理器中手动确认APK文件的存在和路径。

这个示例代码展示了如何使用flutter_install_app插件从Flutter应用中安装APK文件。根据你的具体需求,你可能需要调整APK文件的获取方式和错误处理逻辑。

回到顶部