由于. XAPK文件包含1 base_apk以及obb文件和其他一些额外的. apk文件。通过将. XAPK文件转换为zip,然后提取它让我安装base_apk,但该APK实际上并不工作,因为它没有正确安装它的其他额外的APK。我如何才能正确安装. XAPK文件的所有APK。(下面的代码是在 dart 语言,因为它是FlutterAPK)。
这是我的代码:
import 'dart:io';
import 'package:archive/archive.dart';
import 'package:package_archive_info/package_archive_info.dart';
import 'package:path_provider/path_provider.dart';
abstract class XapkInstaller { static install({ required String apkPath }) async {
late List<FileSystemEntity> allFiles, apkFiles;
late PackageArchiveInfo appInfo;
late String appPackageName;
Directory tempDir = await getTemporaryDirectory();
String tempPath = tempDir.path;
String appName = apkPath.split("/").last.replaceAll(".xapk", "");
String zipFilePath = tempDir.path + "/${appName}_zip";
// this function convert xapk in zip file and moves in appname_zip dirctory
_moveFile(File(apkPath), zipFilePath, appName);
final bytes = File(zipFilePath + "/$appName" + ".zip").readAsBytesSync();
final archive = ZipDecoder().decodeBytes(bytes);
// Extract the contents of the Zip archive to disk app cache.
for (final file in archive) {
final String filename = file.name;
if (file.isFile) {
final data = file.content as List<int>;
File(tempDir.path + "/$appName" + "/$filename")
..createSync(recursive: true)
..writeAsBytesSync(data);
} else {
Directory(tempPath).create(recursive: true);
}
}
final Directory myDir = Directory(tempDir.path + "/$appName");
allFiles = myDir.listSync(recursive: true, followLinks: true);
apkFiles =
allFiles.where((element) => element.path.endsWith('.apk')).toList();
for (int x = 0; x < apkFiles.length; x++) {
final String filePath = apkFiles[x].path;
try {
appInfo = await PackageArchiveInfo.fromPath(filePath);
appPackageName = appInfo.packageName;
} catch (e) {
appInfo = PackageArchiveInfo(
appName: "", packageName: "", version: "", buildNumber: "");
}
if (appInfo.appName.isNotEmpty &&
appPackageName == App.apkName(apkPath: filePath)) {
try {
// moving real app from extracting folder to APKdojo folder
File(filePath)
.copySync(await App.getApksDirectory() + "/$appName.apk");
// moving obb file to android/obb folder
_moveObbToAndroidDir(allFiles, appPackageName);
// showing popup to install app
await OpenFile.open(filePath);
// deleting .xapk file after moving real extracted app in the APKdojo folder and obb file into android folder
File(await App.getApksDirectory() + "/$appName" + ".xapk").delete();
} catch (e) {
//error in installing
}
}
}
// clearing cache file after installing xapk
Future.delayed(const Duration(seconds: 180), () {
tempDir.deleteSync(recursive: true);
tempDir.create();
}); }
static _moveFile(File sourceFile, String newPath, String appname) async {
if (!Directory(newPath).existsSync()) Directory(newPath).createSync();
final String zipFilePath = "$newPath/" + appname + ".zip";
try {
return sourceFile.copySync(zipFilePath);
} on FileSystemException {
// if rename fails, copy the source file and then delete it
await sourceFile.copy(zipFilePath);
await sourceFile.delete();
} }
static _moveObbToAndroidDir(
List<FileSystemEntity> allFiles, String appPackageName) async {
for (int x = 0; x < allFiles.length; x++) {
final fileExtension = allFiles[x].path.split("/").last.split(".").last;
if (fileExtension == "obb") {
String filepath = allFiles[x].path;
String obbFileName = filepath.split("/").last.split(".").first;
String obbDirPath = await App.internalStoragePath() +
"/Android" +
"/obb" +
"/$appPackageName";
// creating the directory inside android/obb folder to place obb files
if (!Directory(obbDirPath).existsSync()) {
Directory(obbDirPath).createSync();
}
// rename path should also contains filename i.e. whole path with filename and extension
final String renamePath = obbDirPath + "/" + obbFileName + ".obb";
try {
// syncronus copying
File(filepath).copySync(renamePath);
} on FileSystemException {
// in case of exception copying asyncronushly
await File(filepath).copy(renamePath);
}
}
} } }
1条答案
按热度按时间nvbavucw1#
如果你还在尝试安装一个. xapk文件,我分享一段代码来帮助我。我使用的软件包:
archive(用于所有作为zip逻辑的提取)
device_apps(在您没有所需权限的情况下打开设置应用程序)
open_filex(使用Android Intent打开apk文件)
package_archive_info(从. apk包中获取信息)
path_provider(获取目录和路径)
permission_handler(请求安装权限)
和file_picker,因为我使用这个包通过一个选中的文件启动了这个方法。
我已经试过了,它工作正常,所以记得更新AndroidManifest文件的权限,你就万事俱备了。