type 'List<dynamic>' 不是 'Uint8List 类型的子类型
type 'List<dynamic>' is not a subtype of type 'Uint8List
我正在使用名为 device_apps
的 flutter 插件来获取安装在我的 android 设备中的应用程序信息。
它 returns 一个 List<Application>
如果我将对象从应用程序投射到 ApplicationWithIcon
,它会提供图标。
但是它返回的图标是一个Uint8列表类型,我想把它保存在本地,稍后在Image.memory()中使用。
如果我直接使用它而不在本地保存那么它可以正常工作 Image.memory(app.icon)。但是当我将图标保存在 json 文件中然后使用它时它显示错误:
type 'List' is not a subtype of type 'Uint8List'
如何保存到本地然后使用?
import 'dart:async';
import 'dart:convert';
import 'dart:ffi';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:device_apps/device_apps.dart';
import 'package:app_settings/app_settings.dart';
import 'package:flutter/services.dart' show rootBundle;
void main() {
runApp(
MaterialApp(
title: 'Reading and Writing Files',
home: MyApp(),
),
);
}
const String dataFile = 'data1.json';
class MyApp extends StatefulWidget {
@override
_AppState createState() => _AppState();
}
class _AppState extends State<MyApp> {
String data;
File _filePath;
bool _fileExists = false;
String jsonString;
List<dynamic> _json = [];
List<dynamic> _jsonshow = [];
List<Application> appsDetail;
void checkFile() async {
// chek if file exists
String dir = (await getApplicationDocumentsDirectory()).path;
String savePath = '$dir/$dataFile';
//for a directory: await Directory(savePath).exists();
if (await File(savePath).exists()) {
print("File exists");
} else {
print("File don't exists");
}
}
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
print(directory.path);
return directory.path;
}
Future<File> get _localFile async {
final path = await _localPath;
return File('$path/$dataFile');
}
void appDetail() async {
print("Getting app informations using 'device_apps' : ");
List<Application> apps = await DeviceApps.getInstalledApplications(
includeSystemApps: true,
includeAppIcons: true,
onlyAppsWithLaunchIntent: true,
);
print("Printing apps detail from appDetail() Funtion apps : ");
// for (int i = 0; i < apps.length; i++) print(apps[i]);
print(apps);
appsDetail = apps;
for (int i = 0; i < apps.length; i++) {
ApplicationWithIcon icon = apps[i] as ApplicationWithIcon;
print(icon.icon.runtimeType);
// print(apps[i]);
_json.add({
"totalApps": apps.length,
"appName": apps[i].appName,
"apkFilePath": apps[i].apkFilePath,
"packageName": apps[i].packageName,
"versionName": apps[i].versionName,
"versionCode": apps[i].versionCode,
"dataDir": apps[i].dataDir,
"systemApp": apps[i].systemApp,
"installTimeMillis": apps[i].installTimeMillis,
"updateTimeMillis": apps[i].updateTimeMillis,
"icon": icon.icon,
// "category": apps[i].category
});
}
print(_json);
}
void writeJsonfile() async {
print("Writing json file : ");
_filePath = await _localFile;
print("json before encoding : ");
print("$_json");
jsonString = jsonEncode(_json);
print("jsonString after encoding : ");
print(jsonString);
_filePath.writeAsString(
jsonEncode(jsonString),
);
}
Future<List<Object>> Apps() async {
print("Reading Json file");
_filePath = await _localFile;
_fileExists = await _filePath.exists();
print('0. File exists? $_fileExists');
if (_fileExists) {
try {
String jsonString = await _filePath.readAsString();
_json = jsonDecode(jsonString);
print('printing json file after reading : ');
print(_json);
return _json;
} catch (e) {
// Print exception errors
print('Tried reading _file error: $e');
// If encountering an error, return null
}
} else {}
}
@override
void initState() {
super.initState();
appDetail();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Reading and Writing data')),
body: Column(
children: <Widget>[
IconButton(icon: Icon(Icons.ac_unit), onPressed: Apps),
_json.length >= 1
? GridView.builder(
shrinkWrap: true,
physics: ScrollPhysics(),
scrollDirection: Axis.vertical,
itemCount: _json.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 5, childAspectRatio: 2.0),
itemBuilder: (BuildContext context, int index) {
return Column(
children: <Widget>[
Expanded(child: Text(_json[index]["appName"])),
Expanded(child: Image.memory(_json[index]["icon"])),
],
);
})
: Text("No Data Found"),
],
));
}
}
我找到了一个愚蠢的解决方案,但我不知道它为什么有效!
只需将 _json[index]['icon']
插入到变量中,然后在 Image.memory() 中使用它即可。
var icon = `_json[index]['icon']` ;
Image.memory(icon)
完整代码如下:
import 'dart:async';
import 'dart:convert';
import 'dart:ffi';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:device_apps/device_apps.dart';
import 'package:app_settings/app_settings.dart';
import 'package:flutter/services.dart' show rootBundle;
void main() {
runApp(
MaterialApp(
title: 'Reading and Writing Files',
home: MyApp(),
),
);
}
const String dataFile = 'data1.json';
class MyApp extends StatefulWidget {
@override
_AppState createState() => _AppState();
}
class _AppState extends State<MyApp> {
String data;
File _filePath;
bool _fileExists = false;
String jsonString;
List<dynamic> _json = [];
List<dynamic> _jsonshow = [];
List<Application> appsDetail;
void checkFile() async {
// chek if file exists
String dir = (await getApplicationDocumentsDirectory()).path;
String savePath = '$dir/$dataFile';
//for a directory: await Directory(savePath).exists();
if (await File(savePath).exists()) {
print("File exists");
} else {
print("File don't exists");
}
}
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
print(directory.path);
return directory.path;
}
Future<File> get _localFile async {
final path = await _localPath;
return File('$path/$dataFile');
}
void appDetail() async {
print("Getting app informations using 'device_apps' : ");
List<Application> apps = await DeviceApps.getInstalledApplications(
includeSystemApps: true,
includeAppIcons: true,
onlyAppsWithLaunchIntent: true,
);
print("Printing apps detail from appDetail() Funtion apps : ");
// for (int i = 0; i < apps.length; i++) print(apps[i]);
print(apps);
appsDetail = apps;
for (int i = 0; i < apps.length; i++) {
ApplicationWithIcon icon = apps[i] as ApplicationWithIcon;
print(icon.icon.runtimeType);
// print(apps[i]);
_json.add({
"totalApps": apps.length,
"appName": apps[i].appName,
"apkFilePath": apps[i].apkFilePath,
"packageName": apps[i].packageName,
"versionName": apps[i].versionName,
"versionCode": apps[i].versionCode,
"dataDir": apps[i].dataDir,
"systemApp": apps[i].systemApp,
"installTimeMillis": apps[i].installTimeMillis,
"updateTimeMillis": apps[i].updateTimeMillis,
"icon": icon.icon,
// "category": apps[i].category
});
}
print(_json);
}
void writeJsonfile() async {
print("Writing json file : ");
_filePath = await _localFile;
print("json before encoding : ");
print("$_json");
jsonString = jsonEncode(_json);
print("jsonString after encoding : ");
print(jsonString);
_filePath.writeAsString(
jsonEncode(jsonString),
);
}
Future<List<Object>> Apps() async {
print("Reading Json file");
_filePath = await _localFile;
_fileExists = await _filePath.exists();
print('0. File exists? $_fileExists');
if (_fileExists) {
try {
String jsonString = await _filePath.readAsString();
_json = jsonDecode(jsonString);
print('printing json file after reading : ');
print(_json);
return _json;
} catch (e) {
// Print exception errors
print('Tried reading _file error: $e');
// If encountering an error, return null
}
} else {}
}
@override
void initState() {
super.initState();
appDetail();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Reading and Writing data')),
body: Column(
children: <Widget>[
IconButton(icon: Icon(Icons.ac_unit), onPressed: Apps),
_json.length >= 1
? GridView.builder(
shrinkWrap: true,
physics: ScrollPhysics(),
scrollDirection: Axis.vertical,
itemCount: _json.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 5, childAspectRatio: 2.0),
itemBuilder: (BuildContext context, int index) {
print("Checking");
print(_json[index]["icon"].runtimeType);
var icon = _json[index]["icon"];
return Column(
children: <Widget>[
Expanded(child: Text(_json[index]["appName"])),
Expanded(child: Image.memory(icon)),
],
);
})
: Text("No Data Found"),
],
));
}
}
我在将图像从本机模块 (Android) 传递到 Flutter 时遇到了同样的问题。 (我正在制作一个插件)
默认情况下,Flutter 将处理来自底层平台的数据类型并将其映射到 Dart 中的适当数据类型,检查此 table here 以查看数据类型。
但我的情况听起来像是 Flutter 拦截了类型 byte[]
的值作为 List<dynamic>
所以只需将它从 List<dynamic>
转换为 List<Int>
Flutter 可以处理它的地方。
- 只要复制这个方法并给它你的列表,它就会转换 &return Unit8List 可以在 Flutter 中的任何地方使用,例如
image.memory()
.
Uint8List _getImageBinary(dynamicList) {
List<int> intList = dynamicList.cast<int>().toList(); //This is the magical line.
Uint8List data = Uint8List.fromList(intList);
return data;
}
我正在使用名为 device_apps
的 flutter 插件来获取安装在我的 android 设备中的应用程序信息。
它 returns 一个 List<Application>
如果我将对象从应用程序投射到 ApplicationWithIcon
,它会提供图标。
但是它返回的图标是一个Uint8列表类型,我想把它保存在本地,稍后在Image.memory()中使用。
如果我直接使用它而不在本地保存那么它可以正常工作 Image.memory(app.icon)。但是当我将图标保存在 json 文件中然后使用它时它显示错误:
type 'List' is not a subtype of type 'Uint8List'
如何保存到本地然后使用?
import 'dart:async';
import 'dart:convert';
import 'dart:ffi';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:device_apps/device_apps.dart';
import 'package:app_settings/app_settings.dart';
import 'package:flutter/services.dart' show rootBundle;
void main() {
runApp(
MaterialApp(
title: 'Reading and Writing Files',
home: MyApp(),
),
);
}
const String dataFile = 'data1.json';
class MyApp extends StatefulWidget {
@override
_AppState createState() => _AppState();
}
class _AppState extends State<MyApp> {
String data;
File _filePath;
bool _fileExists = false;
String jsonString;
List<dynamic> _json = [];
List<dynamic> _jsonshow = [];
List<Application> appsDetail;
void checkFile() async {
// chek if file exists
String dir = (await getApplicationDocumentsDirectory()).path;
String savePath = '$dir/$dataFile';
//for a directory: await Directory(savePath).exists();
if (await File(savePath).exists()) {
print("File exists");
} else {
print("File don't exists");
}
}
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
print(directory.path);
return directory.path;
}
Future<File> get _localFile async {
final path = await _localPath;
return File('$path/$dataFile');
}
void appDetail() async {
print("Getting app informations using 'device_apps' : ");
List<Application> apps = await DeviceApps.getInstalledApplications(
includeSystemApps: true,
includeAppIcons: true,
onlyAppsWithLaunchIntent: true,
);
print("Printing apps detail from appDetail() Funtion apps : ");
// for (int i = 0; i < apps.length; i++) print(apps[i]);
print(apps);
appsDetail = apps;
for (int i = 0; i < apps.length; i++) {
ApplicationWithIcon icon = apps[i] as ApplicationWithIcon;
print(icon.icon.runtimeType);
// print(apps[i]);
_json.add({
"totalApps": apps.length,
"appName": apps[i].appName,
"apkFilePath": apps[i].apkFilePath,
"packageName": apps[i].packageName,
"versionName": apps[i].versionName,
"versionCode": apps[i].versionCode,
"dataDir": apps[i].dataDir,
"systemApp": apps[i].systemApp,
"installTimeMillis": apps[i].installTimeMillis,
"updateTimeMillis": apps[i].updateTimeMillis,
"icon": icon.icon,
// "category": apps[i].category
});
}
print(_json);
}
void writeJsonfile() async {
print("Writing json file : ");
_filePath = await _localFile;
print("json before encoding : ");
print("$_json");
jsonString = jsonEncode(_json);
print("jsonString after encoding : ");
print(jsonString);
_filePath.writeAsString(
jsonEncode(jsonString),
);
}
Future<List<Object>> Apps() async {
print("Reading Json file");
_filePath = await _localFile;
_fileExists = await _filePath.exists();
print('0. File exists? $_fileExists');
if (_fileExists) {
try {
String jsonString = await _filePath.readAsString();
_json = jsonDecode(jsonString);
print('printing json file after reading : ');
print(_json);
return _json;
} catch (e) {
// Print exception errors
print('Tried reading _file error: $e');
// If encountering an error, return null
}
} else {}
}
@override
void initState() {
super.initState();
appDetail();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Reading and Writing data')),
body: Column(
children: <Widget>[
IconButton(icon: Icon(Icons.ac_unit), onPressed: Apps),
_json.length >= 1
? GridView.builder(
shrinkWrap: true,
physics: ScrollPhysics(),
scrollDirection: Axis.vertical,
itemCount: _json.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 5, childAspectRatio: 2.0),
itemBuilder: (BuildContext context, int index) {
return Column(
children: <Widget>[
Expanded(child: Text(_json[index]["appName"])),
Expanded(child: Image.memory(_json[index]["icon"])),
],
);
})
: Text("No Data Found"),
],
));
}
}
我找到了一个愚蠢的解决方案,但我不知道它为什么有效!
只需将 _json[index]['icon']
插入到变量中,然后在 Image.memory() 中使用它即可。
var icon = `_json[index]['icon']` ;
Image.memory(icon)
完整代码如下:
import 'dart:async';
import 'dart:convert';
import 'dart:ffi';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:device_apps/device_apps.dart';
import 'package:app_settings/app_settings.dart';
import 'package:flutter/services.dart' show rootBundle;
void main() {
runApp(
MaterialApp(
title: 'Reading and Writing Files',
home: MyApp(),
),
);
}
const String dataFile = 'data1.json';
class MyApp extends StatefulWidget {
@override
_AppState createState() => _AppState();
}
class _AppState extends State<MyApp> {
String data;
File _filePath;
bool _fileExists = false;
String jsonString;
List<dynamic> _json = [];
List<dynamic> _jsonshow = [];
List<Application> appsDetail;
void checkFile() async {
// chek if file exists
String dir = (await getApplicationDocumentsDirectory()).path;
String savePath = '$dir/$dataFile';
//for a directory: await Directory(savePath).exists();
if (await File(savePath).exists()) {
print("File exists");
} else {
print("File don't exists");
}
}
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
print(directory.path);
return directory.path;
}
Future<File> get _localFile async {
final path = await _localPath;
return File('$path/$dataFile');
}
void appDetail() async {
print("Getting app informations using 'device_apps' : ");
List<Application> apps = await DeviceApps.getInstalledApplications(
includeSystemApps: true,
includeAppIcons: true,
onlyAppsWithLaunchIntent: true,
);
print("Printing apps detail from appDetail() Funtion apps : ");
// for (int i = 0; i < apps.length; i++) print(apps[i]);
print(apps);
appsDetail = apps;
for (int i = 0; i < apps.length; i++) {
ApplicationWithIcon icon = apps[i] as ApplicationWithIcon;
print(icon.icon.runtimeType);
// print(apps[i]);
_json.add({
"totalApps": apps.length,
"appName": apps[i].appName,
"apkFilePath": apps[i].apkFilePath,
"packageName": apps[i].packageName,
"versionName": apps[i].versionName,
"versionCode": apps[i].versionCode,
"dataDir": apps[i].dataDir,
"systemApp": apps[i].systemApp,
"installTimeMillis": apps[i].installTimeMillis,
"updateTimeMillis": apps[i].updateTimeMillis,
"icon": icon.icon,
// "category": apps[i].category
});
}
print(_json);
}
void writeJsonfile() async {
print("Writing json file : ");
_filePath = await _localFile;
print("json before encoding : ");
print("$_json");
jsonString = jsonEncode(_json);
print("jsonString after encoding : ");
print(jsonString);
_filePath.writeAsString(
jsonEncode(jsonString),
);
}
Future<List<Object>> Apps() async {
print("Reading Json file");
_filePath = await _localFile;
_fileExists = await _filePath.exists();
print('0. File exists? $_fileExists');
if (_fileExists) {
try {
String jsonString = await _filePath.readAsString();
_json = jsonDecode(jsonString);
print('printing json file after reading : ');
print(_json);
return _json;
} catch (e) {
// Print exception errors
print('Tried reading _file error: $e');
// If encountering an error, return null
}
} else {}
}
@override
void initState() {
super.initState();
appDetail();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Reading and Writing data')),
body: Column(
children: <Widget>[
IconButton(icon: Icon(Icons.ac_unit), onPressed: Apps),
_json.length >= 1
? GridView.builder(
shrinkWrap: true,
physics: ScrollPhysics(),
scrollDirection: Axis.vertical,
itemCount: _json.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 5, childAspectRatio: 2.0),
itemBuilder: (BuildContext context, int index) {
print("Checking");
print(_json[index]["icon"].runtimeType);
var icon = _json[index]["icon"];
return Column(
children: <Widget>[
Expanded(child: Text(_json[index]["appName"])),
Expanded(child: Image.memory(icon)),
],
);
})
: Text("No Data Found"),
],
));
}
}
我在将图像从本机模块 (Android) 传递到 Flutter 时遇到了同样的问题。 (我正在制作一个插件)
默认情况下,Flutter 将处理来自底层平台的数据类型并将其映射到 Dart 中的适当数据类型,检查此 table here 以查看数据类型。
但我的情况听起来像是 Flutter 拦截了类型 byte[]
的值作为 List<dynamic>
所以只需将它从 List<dynamic>
转换为 List<Int>
Flutter 可以处理它的地方。
- 只要复制这个方法并给它你的列表,它就会转换 &return Unit8List 可以在 Flutter 中的任何地方使用,例如
image.memory()
.
Uint8List _getImageBinary(dynamicList) {
List<int> intList = dynamicList.cast<int>().toList(); //This is the magical line.
Uint8List data = Uint8List.fromList(intList);
return data;
}