【问题标题】:Hosting an executable within a Flutter application在 Flutter 应用程序中托管可执行文件
【发布时间】:2020-09-15 07:11:44
【问题描述】:

我有一个在 android 上运行的基本颤振项目,当应用程序启动时,我编写了一个捆绑在我的资产中的可执行文件。

  static String appInternalPath = '/data/data/com.maksimdan.face_merger';

  void writeExecutable() async {
    var executablePath = join(appInternalPath, 'main');

    if (await File(executablePath).exists()) {
      File(executablePath).delete();
      print('deleted old executable');
    } else {
      print('not executable exists');
    }

    ByteData data = await rootBundle.load('lib/py/dist/main');
    List<int> bytes =
        data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
    await File(executablePath).writeAsBytes(bytes);
    print('wrote new executable');
  }

稍后在我的代码中我尝试运行它。

  void invokeExecutable() async {
    String executablePath = join(appInternalPath, 'main');
    Process.run('chmod', ['u+x', executablePath]).then((ProcessResult results) {
      Process.run(executablePath, []).then((ProcessResult results) {
        print(results.stdout);
      });
    });
  }

但获取权限被拒绝错误。

E/flutter (31825): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: ProcessException: Permission denied
E/flutter (31825):   Command: /data/data/com.maksimdan.flutter_general/main 
E/flutter (31825): #0      _ProcessImpl._start (dart:io-patch/process_patch.dart:390:33)
E/flutter (31825): #1      Process.start (dart:io-patch/process_patch.dart:36:20)
E/flutter (31825): #2      _runNonInteractiveProcess (dart:io-patch/process_patch.dart:565:18)
E/flutter (31825): #3      Process.run (dart:io-patch/process_patch.dart:47:12)
E/flutter (31825): #4      _MyHomePageState.invokeExecutable.<anonymous closure> (package:flutter_general/main.dart:51:15)
E/flutter (31825): #5      _rootRunUnary (dart:async/zone.dart:1362:47)
E/flutter (31825): #6      _CustomZone.runUnary (dart:async/zone.dart:1265:19)
E/flutter (31825): <asynchronous suspension>

我也试过了:

      Process.run('/system/bin/chmod', ['744', path]).then((ProcessResult results) {
        print('shell1 complete');
        Process.run(path, []).then((ProcessResult results) {
          print('shell2 complete');
          print(results.stdout);
        });
      });

我的可执行文件:

// 'Hello World!' program 
 
#include <iostream>
 
int main()
{
  std::cout << "Hello World!" << std::endl;
  return 0;
}
>> g++ main.cc -o main

有没有办法以适当的权限运行您自己的可执行文件?在原生 android 上,可以选择使用此策略 file.setExecutable(true);。 (Hosting an executable within Android application)

或者我必须尝试方法通道吗?


pubspec.yml

name: face_merger
description: A new Flutter project.

version: 1.0.0+1

environment:
  sdk: ">=2.1.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter

  sqflite: ^1.3.0+2
  process_run: ^0.10.10+1
  cupertino_icons: ^0.1.3

dev_dependencies:
  flutter_test:
    sdk: flutter


flutter:
  uses-material-design: true
  assets:
    - lib/py/dist/main

我还验证了该文件已写入设备的内部存储器,我希望使用 android studio 的设备探索将其写入。

【问题讨论】:

  • 你在什么平台上运行?
  • @Eiko 安卓平台
  • 有趣地在同一路径上运行chmod 可执行文件会得到Unhandled Exception: ProcessException: No such file or directory,这没有多大意义。
  • 你能分享你使用的 pubspec.yaml 包吗?
  • 会不会和你项目安装的地方有关?也许您要编写的路径需要您的操作系统的一些管理员权限?

标签: flutter dart


【解决方案1】:

除了可写权限外,您还需要在应用中具有可读权限。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xxx.yyy">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

...

【讨论】:

  • 为了完整性我也试过这个。可执行文件正在写入手机内部存储器,而不是外部存储器。
【解决方案2】:

您需要将 .db 文件扩展名放在数据库名称的末尾(假设 DB_DIR 用于数据库)。 var path = join(DB_DIR, 'main.db');

那么我想你可能想使用path_provider package 并使用

Directory documentsDirectory = await getApplicationDocumentsDirectory();

用于访问数据库的目录。

【讨论】:

  • 我最初使用 db_dir 作为占位符名称;对困惑感到抱歉;我已经编辑了这个问题。但我对复制数据库不感兴趣。它是一个可以在终端上运行的可执行文件。我已经证明复制可执行文件不是问题,而是它尝试在失败的应用程序中执行它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-15
  • 2018-05-21
  • 2012-12-11
  • 2011-04-25
  • 2023-02-21
  • 2020-06-19
  • 2016-08-17
相关资源
最近更新 更多