Hosting an executable within a Flutter application - flutter

I have a basic flutter project running on android where when the application starts, I write an executable bundled in my assets.
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');
}
Sometime later in my code I try to run it.
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);
});
});
}
But obtain a permission denied error.
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>
I've also tried:
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);
});
});
My executable:
// 'Hello World!' program
#include <iostream>
int main()
{
std::cout << "Hello World!" << std::endl;
return 0;
}
>> g++ main.cc -o main
Is there a way to run your own executables in flutter with the proper permissions? On native android, there is an option to file.setExecutable(true); using this strategy. (Hosting an executable within Android application)
Or will I have to experiment with method channels?
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
I also verified that the file was written to the internal memory of on the device that I expected it to be written to using android studio's device explore.

Besides the writable permission you need to have readable permission in your app.
<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"/>
...

You need to put the .db file extension at the end of the database name (Assuming DB_DIR is for a database). var path = join(DB_DIR, 'main.db');
Then I think you may want to use path_provider package and use
Directory documentsDirectory = await getApplicationDocumentsDirectory();
for the directory where you are accessing the database.

Related

How to unzip files to device memory in flutter

I was able to download file in zip format from remote server, but when unzip the file containing videos, I got error like this
E/flutter (11680): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: FileSystemException: Creation failed, path = 'out' (OS Error: Read-only file system, errno = 30)
E/flutter (11680): #0 _Directory.createSync (dart:io/directory_impl.dart:133:7)
E/flutter (11680): #1 extractArchiveToDisk
package:archive/…/io/extract_archive_to_disk.dart:21
E/flutter (11680): #2 ZipService.unzipSigns
package:gsl_distionary/services/zip_service.dart:13
E/flutter (11680): <asynchronous suspension>
Below is my code to unzip file using archive package:
static Future unzipSigns(String fileName) async {
final dir = await getApplicationSupportDirectory();
final bool isZippedFile = await File("${dir.path}/$fileName").exists();
if (isZippedFile) {
final inputStream = InputFileStream("${dir.path}/$fileName");
final archive = ZipDecoder().decodeBuffer(inputStream);
extractArchiveToDisk(archive, 'out');
}
}
What did I miss?

Flutter/Dart get_It singleton locator method failure

I have a simple dart class as follows:
import 'package:flutter/material.dart';
class UiUtils {
// TEMPORARY FOR UNIT TEST PURPOSES ONLY
int addition(int x, int y) {
return x + y;
}
}
(Note: The above is a sample, the actual class does have more than that temp function.)
My pubspec.yml file contains the following:
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
intl: ^0.17.0
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
get_it: ^7.1.3
provider: ^6.0.1
mockito: ^5.0.16
I have a dependency locator file as such:
import 'package:get_it/get_it.dart';
import 'package:quiz_test/utils/UiUtils.dart';
GetIt dependencyLocator = GetIt.instance;
void setupDependencyLocator() {
//dependencyLocator.registerSingleton(() => UiUtils());
dependencyLocator.registerFactory(() => UiUtils());
}
Finally, in main.dart I have the following:
void main() {
setupDependencyLocator();
runApp(MyApp());
}
(There is of course more code than this).
As it is displayed, the code works fine, however if I change the dependancy_locator file from the current factory method to the singleton instead (i.e. comment out one to enable the other) I get the following error:
[VERBOSE-2:ui_dart_state.cc(209)] Unhandled Exception: type '_ServiceFactory<() => UiUtils, void, void>' is not a subtype of type '_ServiceFactory<Object, dynamic, dynamic>' of 'value'
#0 _LinkedHashMapMixin.[]= (dart:collection-patch/compact_hash.dart)
#1 _GetItImplementation._register (package:get_it/get_it_impl.dart:844:35)
#2 _GetItImplementation.registerSingleton (package:get_it/get_it_impl.dart:587:5)
#3 setupDependencyLocator (package:quiz_test/utils/dependency_locator.dart:7:21)
#4 main (package:quiz_test/main.dart:13:3)
#5 _runMainZoned.<anonymous closure>.<anonymous closure> (dart:ui/hooks.dart:145:25)
#6 _rootRun (dart:async/zone.dart:1428:13)
#7 _CustomZone.run (dart:async/zone.dart:1328:19)
#8 _runZoned (dart:async/zone.dart:1863:10)
#9 runZonedGuarded (dart:async/zone.dart:1851:12)
#10 _runMainZoned.<anonymous closure> (dart:ui/hooks.dart:141:5)
#11 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.<…>
Can anyone please help me to understand why I cannot use the singleton call rather than the factory one? My thought process is that I do not need a unique instance of this class, which is what I believe factory will give me, I just need a single instance of it for any classes that require it.
Any help is greatly appreciated.
I was able to resolve this by doing the following:
dependencyLocator.registerSingleton<UiUtils>(UiUtils());
So, my dependencyLocator class now looks like this:
import 'package:get_it/get_it.dart';
import 'package:quiz_test/utils/UiUtils.dart';
GetIt dependencyLocator = GetIt.instance;
void setupDependencyLocator() {
dependencyLocator.registerSingleton<UiUtils>(UiUtils());
}
I hope this helps someone else from getting stuck!

Flutter Unhandled Exception: Null check operator used on a null value

I am getting the following error Unhandled Exception: Null check operator and I am not sure if it is something wrong in my code or the library I am using. I am trying to test the livequery of the parse_server_sdk used by back4app because I require sending and receiving images in Realtime. Here is the relevant code:
import 'dart:io';
import 'package:filepicker_windows/filepicker_windows.dart';
import 'package:flutter/material.dart';
import 'package:parse_server_sdk_flutter/parse_server_sdk.dart';
void main() async {
final keyApplicationId = 'EPARW6nRAAyp5uehoDE7rBEby4wtehcZf9EayykS';
final keyClientKey = 'fDaL2DjyC9YdwCwZ4RB5c5vhACROaMOO1EjjL4Zn';
final keyParseServerUrl = 'https://parseapi.back4app.com';
final LIVE_QUERY_URL = 'wss://samuraichat.b4a.io';
await Parse().initialize(keyApplicationId, keyParseServerUrl,
clientKey: keyClientKey,
autoSendSessionId: true,
liveQueryUrl: LIVE_QUERY_URL,
coreStore: CoreStoreMemoryImp());
final LiveQuery liveQuery = LiveQuery();
QueryBuilder<ParseObject> query =
QueryBuilder<ParseObject>(ParseObject('FirstClass'))
..whereEqualTo('chatId', 1);
Subscription subscription = await liveQuery.client.subscribe(query);
subscription.on(LiveQueryEvent.create, (value) {
print('*** CREATE ***: ${DateTime.now().toString()}\n $value ');
print((value as ParseObject).objectId);
print((value as ParseObject).get('message'));
});
runApp(MyApp());
}
Here is the error stack:
[ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: Null check operator used on a null value
#0 MethodChannel.binaryMessenger (package:flutter/src/services/platform_channel.dart:142:86)
#1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:148:36)
#2 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:331:12)
#3 MethodChannelConnectivity.checkConnectivity (package:connectivity_platform_interface/src/method_channel_connectivity.dart:41:29)
#4 Connectivity.checkConnectivity (package:connectivity/connectivity.dart:46:22)
#5 Parse.checkConnectivity (package:parse_server_sdk_flutter/parse_server_sdk.dart:106:34)
#6 new LiveQueryReconnectingController (package:parse_server_sdk/src/network/parse_live_query.dart:45:28)
#7 new LiveQueryClient._internal (package:parse_server_sdk/src/network/parse_live_query.dart:146:30)
#8 LiveQueryClient._getInstance (package:parse_server_sdk/src/network/parse_live_query.dart:153:35)
#9 new LiveQuery (package:parse_server_sdk/src/network/parse_live_query.dart:416:30)
#10 main (package:chat_app/main.dart:18:37)
<asynchronous suspension>
Thanks.
Try to clean your app cache:
flutter clean
This bug should be fixed with this PR.
You use the current nullsafety branch by overriding the dependency in your pubspec.yaml:
dependency_overrides:
parse_server_sdk_flutter:
git:
url: https://github.com/parse-community/Parse-SDK-Flutter.git
ref: nullsafety
path: packages/flutter
parse_server_sdk:
git:
url: https://github.com/parse-community/Parse-SDK-Flutter.git
ref: nullsafety
path: packages/dart

Flutter 1.0 - Unable to load text asset

I'm having some trouble loading text assets in flutter (1.0).
This is the current code attempting to read the asset.
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
Future<String> getFileData(String path) async {
return await rootBundle.loadString(path);
}
Future<File> get _localFile async {
final path = await _localPath;
final file = File('$path/toon_test_3.json');
bool exists = file.existsSync();
if(exists){
return file;
} else {
// Load the default file
final newfile = await getFileData('toonRepo/data.json');
return file.writeAsString(newfile);
}
}
loadString will failing popping up the following:
Could not load source 'dart:core/runtime/libobject_patch.dart': <source not available>.
If execution continues the following exception is raised:
Exception has occurred.
FlutterError (Unable to load asset: toonRepo/data.json)
I've tried a lot of solutions here that revolve around the asset section in pubspec.yaml
name: hello_world
description: A new Flutter project.
version: 1.0.0+1
environment:
sdk: ">=2.0.0-dev.68.0 <3.0.0"
dependencies:
path_provider: ^0.4.1
flutter:
sdk: flutter
cupertino_icons: ^0.1.2
english_words: ^3.1.0
dev_dependencies:
flutter_test:
sdk: flutter
flutter:
assets:
- toonRepo/
uses-material-design: true
Am I going wrong somewhere very silly?
Cheers for any pointers you have.
Project Structure
Here is a temporary copy of the code if you want to take a peek.
Github
And here's a stack trace
[VERBOSE-2:shell.cc(184)] Dart Error: Unhandled exception:
Unable to load asset: toonRepo/data.json
#0 PlatformAssetBundle.load (package:flutter/src/services/asset_bundle.dart:221:7)
<asynchronous suspension>
#1 AssetBundle.loadString (package:flutter/src/services/asset_bundle.dart:67:33)
<asynchronous suspension>
#2 CachingAssetBundle.loadString.<anonymous closure> (package:flutter/src/services/asset_bundle.dart:162:56)
#3 __InternalLinkedHashMap&_HashVMBase&MapMixin&_LinkedHashMapMixin.putIfAbsent (dart:collection/runtime/libcompact_hash.dart:284:23)
The asset access works fine with the pubspec.yaml in your question.
new Text("Name: " + toon.info.name)),
fails because toon is null because it never got a value assigned.
You could use new Text("Name: " + (toon?.info?.name ?? 'foo')), to work around the exception.
If you add
widget.storage.getFileData('toonRepo/data.json').then((f) => print(f));
to _FlutterDemoState.initState(), you'll see that reading the asset works just fine.

Flutter play custom sound using audioplayers 0.7.7?

pubspec.yaml
flutter:
uses-material-design: true
assets:
- assets/Images/1.png
- assets/Images/MP3.mp3
Test.dart
Widget localAsset() {
return _tab([
Text("Click to play"),
_btn('Play', () => audioCache.play('assets\Images\MP3.mp3')),
]);
}
I am new to flutter, for my applications i want play two sounds mode(background sound ,button action sound), after referred from flutter package i have changed code like as above , when i used this widget in my material,i am getting below error,
E/flutter ( 2750): [ERROR:flutter/shell/common/shell.cc(181)] Dart Error: Unhandled exception:
E/flutter ( 2750): Unable to load asset: assets/assetsImagesMP3.mp3
E/flutter ( 2750): #0 PlatformAssetBundle.load (package:flutter/src/services/asset_bundle.dart:221:7)
Backslash are Windows-specific. Use slashes instead. Android is Unix-based and so is iOS
audioCache.play('assets/Images/MP3.mp3')