Merge pull request #2803 from kiwix/Issue#2405

File picker feature is added.
This commit is contained in:
gouri-panda 2022-04-30 11:54:10 +05:30 committed by GitHub
commit 9a227f532d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 100 additions and 0 deletions

View File

@ -19,7 +19,10 @@
package org.kiwix.kiwixmobile.nav.destination.library
import android.Manifest
import android.content.ActivityNotFoundException
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
@ -29,10 +32,12 @@ import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ActionMode
import androidx.appcompat.widget.Toolbar
import androidx.core.content.ContextCompat
import androidx.core.net.toUri
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
@ -42,6 +47,7 @@ import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.fragment_destination_library.file_management_no_files
import kotlinx.android.synthetic.main.fragment_destination_library.go_to_downloads_button_no_files
import kotlinx.android.synthetic.main.fragment_destination_library.select_file
import kotlinx.android.synthetic.main.fragment_destination_library.zim_swiperefresh
import kotlinx.android.synthetic.main.fragment_destination_library.zimfilelist
import org.kiwix.kiwixmobile.R
@ -53,11 +59,13 @@ import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.viewModel
import org.kiwix.kiwixmobile.core.extensions.toast
import org.kiwix.kiwixmobile.core.main.CoreMainActivity
import org.kiwix.kiwixmobile.core.navigateToSettings
import org.kiwix.kiwixmobile.core.utils.FILE_SELECT_CODE
import org.kiwix.kiwixmobile.core.utils.LanguageUtils
import org.kiwix.kiwixmobile.core.utils.REQUEST_STORAGE_PERMISSION
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
import org.kiwix.kiwixmobile.core.utils.dialog.DialogShower
import org.kiwix.kiwixmobile.core.utils.dialog.KiwixDialog
import org.kiwix.kiwixmobile.core.utils.files.FileUtils
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BookOnDiskDelegate
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskAdapter
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem
@ -67,6 +75,7 @@ import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.Re
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestNavigateTo
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestSelect
import org.kiwix.kiwixmobile.zim_manager.fileselect_view.FileSelectListState
import java.io.File
import javax.inject.Inject
private const val WAS_IN_ACTION_MODE = "WAS_IN_ACTION_MODE"
@ -139,6 +148,67 @@ class LocalLibraryFragment : BaseFragment() {
go_to_downloads_button_no_files.setOnClickListener {
offerAction(FileSelectActions.UserClickedDownloadBooksButton)
}
select_file.setOnClickListener {
showFileChooser()
}
}
private fun showFileChooser() {
val intent = Intent().apply {
action = Intent.ACTION_GET_CONTENT
type = "*/*"
addCategory(Intent.CATEGORY_OPENABLE)
}
try {
startActivityForResult(
Intent.createChooser(intent, "Select a zim file"),
FILE_SELECT_CODE
)
} catch (ex: ActivityNotFoundException) {
activity.toast(resources.getString(R.string.no_app_found_to_open), Toast.LENGTH_SHORT)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
FILE_SELECT_CODE -> {
data?.data?.let { uri ->
getZimFileFromUri(uri)?.let(::navigateToReaderFragment)
}
}
else -> super.onActivityResult(requestCode, resultCode, data)
}
}
private fun getZimFileFromUri(
uri: Uri
): File? {
val filePath = FileUtils.getLocalFilePathByUri(
requireActivity().applicationContext, uri
)
if (filePath == null || !File(filePath).exists()) {
activity.toast(R.string.error_file_not_found)
return null
}
val file = File(filePath)
return if (!FileUtils.isValidZimFile(file.path)) {
activity.toast(R.string.error_file_invalid)
null
} else {
file
}
}
private fun navigateToReaderFragment(file: File) {
if (!file.canRead()) {
activity.toast(R.string.unable_to_read_zim_file)
} else {
activity?.navigate(
LocalLibraryFragmentDirections.actionNavigationLibraryToNavigationReader()
.apply { zimFileUri = file.toUri().toString() }
)
}
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {

View File

@ -77,5 +77,17 @@
app:layout_constraintStart_toStartOf="@+id/file_management_no_files"
app:layout_constraintTop_toBottomOf="@+id/file_management_no_files" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/select_file"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_marginBottom="60dp"
android:contentDescription="@string/app_name"
android:src="@drawable/ic_add_blue_24dp"
app:backgroundTint="@color/black"
app:fabSize="auto"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -6,4 +6,5 @@
<string name="cannot_open_file">Failed to open file\nPlease try looking for this file in the Device Tab of your Library</string>
<string name="send_files_title">Send Files</string>
<string name="receive_files_title">Receive Files</string>
<string name="no_app_found_to_open">No app found to select zim file!</string>
</resources>

View File

@ -42,3 +42,5 @@ const val OLD_PROVIDER_DOMAIN = "org.kiwix.zim.base"
// For Storage select dialog
const val INTERNAL_SELECT_POSITION = 0
const val EXTERNAL_SELECT_POSITION = 1
const val FILE_SELECT_CODE = 5

View File

@ -36,6 +36,8 @@ import org.kiwix.kiwixmobile.core.extensions.toast
import java.io.BufferedReader
import java.io.File
import java.io.IOException
import java.lang.Exception
import java.util.ArrayList
object FileUtils {
@ -105,6 +107,11 @@ object FileUtils {
if (documentId[0] == "primary") {
return "${Environment.getExternalStorageDirectory()}/${documentId[1]}"
}
return try {
"${getSdCardMainPath(context)}/${documentId[1]}"
} catch (ignore: Exception) {
null
}
} else if ("com.android.providers.downloads.documents" == uri.authority)
return try {
documentProviderContentQuery(context, uri)
@ -235,6 +242,13 @@ object FileUtils {
"".also { e.printStackTrace() }
}
@JvmStatic fun isValidZimFile(filePath: String): Boolean =
filePath.endsWith(".zim") || filePath.endsWith(".zimaa")
@JvmStatic fun getSdCardMainPath(context: Context): String =
"${context.getExternalFilesDirs("")[1]}"
.substringBefore(context.getString(R.string.android_directory_seperator))
@SuppressLint("WrongConstant")
@JvmStatic fun getPathFromUri(activity: Activity, data: Intent): String? {
val uri: Uri? = data.data

View File

@ -45,6 +45,7 @@
<string name="server_started_message" tools:keep="@string/server_started_message">Enter this ip address into your browser to access the server %s</string>
<string name="share_host_address">Share URL via other applications</string>
<string name="error_file_not_found">Error: The selected ZIM file could not be found.</string>
<string name="unable_to_read_zim_file">Unable to read this zim file!</string>
<string name="zim_not_opened">Unable to open zim file</string>
<string name="error_file_invalid">Error: The selected file is not a valid ZIM file.</string>
<string name="error_article_url_not_found">Error: Loading article (Url: %1$s) failed.</string>