mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-08-03 18:56:44 -04:00
Merge pull request #2803 from kiwix/Issue#2405
File picker feature is added.
This commit is contained in:
commit
9a227f532d
@ -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) {
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user