From dfe97372c3ea84e7a90c78f65010a9384a56de42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20F=C3=BClling?= Date: Fri, 24 Apr 2020 20:19:59 +0200 Subject: [PATCH] [#68] fix support for rar < 5 archives --- app/build.gradle | 2 + app/src/main/AndroidManifest.xml | 13 +++-- .../lerk/lrkFM/activities/IntroActivity.java | 8 ++- .../lerk/lrkFM/tasks/archive/ArchiveUtil.java | 58 ++++++++++++++----- app/src/main/res/values/strings.xml | 4 +- .../lrkFM/activities/FileActivityTest.java | 2 +- 6 files changed, 64 insertions(+), 23 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index b2aa1167..75d6a312 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -72,6 +72,8 @@ dependencies { implementation 'org.tukaani:xz:1.8' implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.core:core:1.2.0' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'com.github.junrar:junrar:4.0.0' testImplementation 'junit:junit:4.13' testImplementation 'org.mockito:mockito-core:3.3.3' androidTestImplementation('androidx.test.espresso:espresso-core:3.2.0', { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index dcb51331..a90bdbd5 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -10,13 +10,14 @@ + tools:ignore="GoogleAppIndexingWarning"> + @@ -28,12 +29,14 @@ android:launchMode="singleInstance"> + - + + @@ -49,10 +52,12 @@ android:name=".activities.IntroActivity" android:label="@string/title_activity_intro" android:theme="@style/AppTheme.NoActionBar" /> - + diff --git a/app/src/main/java/io/lerk/lrkFM/activities/IntroActivity.java b/app/src/main/java/io/lerk/lrkFM/activities/IntroActivity.java index 125fd236..d88cd140 100644 --- a/app/src/main/java/io/lerk/lrkFM/activities/IntroActivity.java +++ b/app/src/main/java/io/lerk/lrkFM/activities/IntroActivity.java @@ -4,10 +4,12 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.os.Bundle; + import androidx.annotation.Nullable; -import com.google.android.material.floatingactionbutton.FloatingActionButton; -import androidx.core.app.ActivityCompat; import androidx.appcompat.widget.Toolbar; +import androidx.core.app.ActivityCompat; + +import com.google.android.material.floatingactionbutton.FloatingActionButton; import io.lerk.lrkFM.R; import io.lerk.lrkFM.activities.file.FileActivity; @@ -35,7 +37,7 @@ protected void onCreate(Bundle savedInstanceState) { final boolean permissionGranted = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; FloatingActionButton fab = findViewById(R.id.fab); - if(permissionGranted) { + if (permissionGranted) { fab.setImageResource(R.drawable.ic_chevron_right_white_24dp); } fab.setOnClickListener(view -> { diff --git a/app/src/main/java/io/lerk/lrkFM/tasks/archive/ArchiveUtil.java b/app/src/main/java/io/lerk/lrkFM/tasks/archive/ArchiveUtil.java index 9c1ee98b..9dfd8207 100644 --- a/app/src/main/java/io/lerk/lrkFM/tasks/archive/ArchiveUtil.java +++ b/app/src/main/java/io/lerk/lrkFM/tasks/archive/ArchiveUtil.java @@ -1,8 +1,12 @@ package io.lerk.lrkFM.tasks.archive; +import android.net.IpSecManager; import android.os.Looper; import android.util.Log; +import com.github.junrar.Junrar; +import com.github.junrar.exception.RarException; + import org.apache.commons.compress.archivers.ArchiveException; import org.apache.commons.compress.archivers.ArchiveInputStream; import org.apache.commons.compress.archivers.ArchiveStreamFactory; @@ -35,7 +39,7 @@ class ArchiveUtil { private static final String TAG = ArchiveUtil.class.getCanonicalName(); - boolean doExtractArchive(String path, FMFile f) throws BlockingStuffOnMainThreadException { + boolean doExtractArchive(String destination, FMFile f) throws BlockingStuffOnMainThreadException { if (Looper.myLooper() == Looper.getMainLooper()) { throw new BlockingStuffOnMainThreadException(); } @@ -43,7 +47,29 @@ boolean doExtractArchive(String path, FMFile f) throws BlockingStuffOnMainThread FileType fileType = f.getFileType(); if (fileType != FileType.ARCHIVE_P7Z) { - fileType.newHandler(getArchiveExtractionCallback(path, result, fileType)).handle(f); + if(fileType == FileType.ARCHIVE_RAR) { + fileType.newHandler(fmFile -> { + File archiveFile = fmFile.getFile(); + File destinationFile = new File(destination); + if (!destinationFile.exists()) { + if (destinationFile.mkdirs()) { + Log.i(TAG, "Folder created: '" + destinationFile.getAbsolutePath() + "'"); + } else { + Log.e(TAG, "Unable to create folder: '" + destinationFile.getAbsolutePath() + "'"); + } + } + try { + Junrar.extract(archiveFile, destinationFile); + result.set(true); + } catch (RarException | IOException e) { + Log.e(TAG, "Unable to extract rar file '" + fmFile.getAbsolutePath() + "'!", e); + result.set(false); + } + }).handle(f); + } else { + // handle archives using commons compress + fileType.newHandler(getArchiveExtractionCallback(destination, result, fileType)).handle(f); + } } else { fileType.newHandler(fi -> { SevenZFile sevenZFile; @@ -54,20 +80,24 @@ boolean doExtractArchive(String path, FMFile f) throws BlockingStuffOnMainThread if (entry.isDirectory()) { continue; } - File curfile = new File(path, entry.getName()); + File curfile = new File(destination, entry.getName()); File parent = curfile.getParentFile(); - if (!parent.exists()) { - if (parent.mkdirs()) { - Log.i(TAG, "Folder created: '" + parent.getAbsolutePath() + "'"); - } else { - Log.e(TAG, "Unable to create folder: '" + parent.getAbsolutePath() + "'"); + if (parent != null) { + if (!parent.exists()) { + if (parent.mkdirs()) { + Log.i(TAG, "Folder created: '" + parent.getAbsolutePath() + "'"); + } else { + Log.e(TAG, "Unable to create folder: '" + parent.getAbsolutePath() + "'"); + } } + FileOutputStream out = new FileOutputStream(curfile); + byte[] content = new byte[(int) entry.getSize()]; + sevenZFile.read(content, 0, content.length); + out.write(content); + out.close(); + } else { + throw new IOException("Unable to get parent file for '" + curfile.getAbsolutePath() + "'!"); } - FileOutputStream out = new FileOutputStream(curfile); - byte[] content = new byte[(int) entry.getSize()]; - sevenZFile.read(content, 0, content.length); - out.write(content); - out.close(); } result.set(true); } catch (IOException e) { @@ -120,7 +150,7 @@ private Handler getArchiveExtractionCallback(String path, AtomicBoolean result.set(true); } } catch (IOException | ArchiveException e) { - Log.e(TAG, "Error extracting " + fileType.getExtension()); + Log.e(TAG, "Error extracting " + fileType.getExtension(), e); result.set(false); } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1e325d23..4d4e858b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -46,7 +46,7 @@ Unable to register context menu File exists The existing file will be overwritten. Are you sure that you want to continue? - @android:string/yes + Yes Delete Are you sure that you want to delete: Move @@ -188,4 +188,6 @@ Vibration Length Configure the length of vibration when toasts appear. Currently: Configure the length of vibration when toasts appear. + Use Storage Access Framework + 9.]]> diff --git a/app/src/test/java/io/lerk/lrkFM/activities/FileActivityTest.java b/app/src/test/java/io/lerk/lrkFM/activities/FileActivityTest.java index acba4a17..41cb19ff 100644 --- a/app/src/test/java/io/lerk/lrkFM/activities/FileActivityTest.java +++ b/app/src/test/java/io/lerk/lrkFM/activities/FileActivityTest.java @@ -8,7 +8,7 @@ */ public class FileActivityTest { - private static final String PATH_SE0 = "/storage/emulated/0"; + private static final String PATH_SE0 = "/storage"; //TODO: learn Mockito and implement tests!