SAF распаковать файл на SDCard
Я хочу извлечь ZIP-файл (~896 Мб) в SDCard с помощью SAF. Для этого я уже получил разрешение и сохранил корневой URI в своем общем предпочтении. Изучив ваш код, я взял метод getDcumentFile() из вашего класса FileUtils. Все идет хорошо, но проблема в том, что процесс извлечения занимает ок. 1 час, чтобы извлечь этот файл в SDCard. Я прилагаю свой код извлечения здесь. Пожалуйста, дайте мне знать, если что-то не так.
public void start() {
destinationPath = PreferenceManager.getDefaultSharedPreferences(context).getString("PATH", null);
treeUri = Uri.parse(PreferenceManager.getDefaultSharedPreferences(context).getString("URI", null));
DocumentFile pickedDir = DocumentFile.fromTreeUri(context, treeUri);
DocumentFile zipd = pickedDir.findFile("POSexternal.zip");
unzipToSDcard(zipd);
}
public boolean unzipToSDcard(DocumentFile zipFile/*, File destinationDir*/) {
ZipFile zip = null;
try {
String path = SDCardUtil.getRealPathFromURI(context, zipFile.getUri());
zip = new ZipFile(path);
for (Enumeration e = zip.entries(); e.hasMoreElements(); ) {
// adding all the elements to be extracted to an array list
ZipEntry entry = (ZipEntry) e.nextElement();
ttl_size += entry.getSize();
arrayList.add(entry);
}
for (ZipEntry z_entry : arrayList) {
unzipEntry(zip, z_entry, destinationPath);
}
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
if (zip != null) {
try {
zip.close();
} catch (IOException ignored) {
ignored.printStackTrace();
}
}
}
return true;
}
private void unzipEntry(ZipFile zipfile, ZipEntry entry, String outputDir) throws Exception {
if (entry.isDirectory()) {
getDocumentFile(new File(outputDir, "/" + entry.getName()), true, context);
return;
}
File outputFile = new File(outputDir, entry.getName());
if (!outputFile.getParentFile().exists()) {
getDocumentFile(outputFile.getParentFile(), true, context);
}
DocumentFile df = getDocumentFile(outputFile, false, context);
InputStream inputStream = zipfile.getInputStream(entry);
OutputStream outputStream = context.getContentResolver().openOutputStream(df.getUri());
try {
int len = 0;
byte buf[] = new byte[8192];
while ((len = inputStream.read(buf, 0, buf.length)) > 0) {
outputStream.write(buf, 0, len);
totalBytesCopied += len;
int progress = (int) Math.round(((double) totalBytesCopied / (double) ttl_size) * 100);
publishProgress(entry.getName(), "" + progress);
}
} catch (IOException e) {
e.printStackTrace();
outputStream.close();
} finally {
// outputStream.flush();
// outputStream.close();
// inputStream.close();
}
}
public static DocumentFile getDocumentFile(final File file, final boolean isDirectory, Context context) {
String baseFolder = getExtSdCardFolder(file, context);
// boolean originalDirectory = false;
if (baseFolder == null) {
return null;
}
String relativePath = null;
try {
String fullPath = file.getCanonicalPath();
if (!baseFolder.equals(fullPath))
relativePath = fullPath.substring(baseFolder.length() + 1);
} catch (IOException e) {
return null;
} catch (Exception f) {
//continue
}
String as = PreferenceManager.getDefaultSharedPreferences(context).getString("URI", null);
Uri treeUri = null;
if (as != null) treeUri = Uri.parse(as);
if (treeUri == null) {
return null;
}
// start with root of SD card and then parse through document tree.
DocumentFile document = DocumentFile.fromTreeUri(context, treeUri);
// if (originalDirectory) return document;
Log.d("path:::", relativePath);
String[] parts = relativePath.split("\\/");
for (int i = 0; i < parts.length; i++) {
DocumentFile nextDocument = document.findFile(parts[i]);
if (nextDocument == null) {
if ((i < parts.length - 1) || isDirectory) {
nextDocument = document.createDirectory(parts[i]);
} else {
nextDocument = document.createFile("image", parts[i]);
}
}
document = nextDocument;
}
return document;
}