anggrayudi / simplestorage Goto Github PK
View Code? Open in Web Editor NEW💾 Simplify Android Storage Access Framework for file management across API levels.
License: Apache License 2.0
💾 Simplify Android Storage Access Framework for file management across API levels.
License: Apache License 2.0
Library version: 0.x.x
OS version: [Android 10]
Device model: [Redmi Note 8]
Describe the bug
I want to request access for SD card, so I am calling storage.requestStorageAccess(REQUEST_CODE, StorageType.SD_CARD) .
But if user selects the root directory of internal storage, onRootPathPermissionGranted is still being called.
To Reproduce
Hello, how can I get the actual file from response (onFileSelected) ? I need the File type not the DocumentFile. Thanks in advance.
Library version: newest
Describe the bug
com.anggrayudi.storage.file.AutoIncrementFileName should not use string comparison like that: .maxOfOrNull { it }
. MaxOf method should be used only for number comparison. At this moment this should be done by search for the biggest number by regex expression.
To Reproduce
Folder with two files:
SomeFile (9).pdf
SomeFile (10).pdf
autoIncrementFileName method return SomeFile (10).pdf
as new file instead SomeFile (11).pdf
When I clone the repo I get this Gradle Sync error its doesn't compile.
Caused by: groovy.lang.MissingPropertyException: Could not get unknown property 'anggrayudi_maven_username' for Credentials [username: null] of type org.gradle.internal.credentials.DefaultPasswordCredentials_Decorated.
Android Studio - 4.1.2
OS - macOS Catalina
It is currently not possible (to my knowledge) to request multiple mime types from file picker.
https://developer.android.com/reference/android/content/Intent.html#EXTRA_MIME_TYPES
I use the itextpdf library to create a PDF document. This is an itextpdf document e.g. 'pdfDoc'.
How can I convert this document into DocumentFile that I can store with SimpleStorage?
DocumentFile dfPdf = (DocumentFile) pdfDoc; gives an error: 'Inconvertible types'.
I have found working with download/document types a bit harder than with normal media type files. Since some methods are market with Q > for download functions. I have wrote the below as a workaround helper functions I think could also help others with this, what do you think? @anggrayudi
fun createDocument(context: Context, file: FileDescription): DocumentFile? {
var subFolder = ""
documentsSubfolder?.let {
subFolder = "${it}/${file.subFolder}"
} ?: run {
subFolder = file.subFolder
}
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
MediaStoreCompat.createDownload(context, file = com.anggrayudi.storage.media.FileDescription(file.name, subFolder, file.mimeType))?.toDocumentFile()
} else {
subFolder += "/${file.name}"
DocumentFileCompat.createFile(context, basePath = subFolder, mimeType = file.mimeType)
}
}
fun fetchDocument(context: Context, subFolder: String = "", name: String): DocumentFile? {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
MediaStoreCompat.fromFileName(context, MediaType.DOWNLOADS, name)?.toDocumentFile()
} else {
var basePath = ""
documentsSubfolder?.let {
basePath = "${it}/${subFolder}"
} ?: run {
basePath = subFolder
}
basePath += "/${name}"
DocumentFileCompat.fromSimplePath(context, basePath)
}
}
Trying to copy a file to target path with utility method but can't pass filecallback
DocumentFileUtils.copyFileTo(getContext(),
DocumentFile.fromFile(getTargetDirFile()),
file.getName(),
new FileCallback()
);
Any help appreciated
I'm trying to allow user to choose a folder from SAF and display the files in chosen folder
But I couldn't find enough documentation
I only want to read the folder contents
Is write storage permission required?
Is Request Storage Access needed?
After user chooses the folder how can i access it?
DocumentFileCompat.fromSimplePath()
might be the solution but I'm failing to come to a solution
Is this project interoperable with Java?
The current approach involves using onActivityResult()
But it's deprecated now
https://stackoverflow.com/questions/62671106/onactivityresult-method-is-deprecated-what-is-the-alternative
Can we get the SimpleStorage intent, eg
ActivityResultLauncher<Intent> launchSomeActivity = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
storage.onActivityResult(result);
}
});
public void openYourActivity() {
Intent intent =storage.getFilePickerIntent();
launchSomeActivity.launch(intent);
}
test.php
is saved as test.php.bin
with 0.5.2 and DocumentFileUtils.moveFileTo
temp path was: /data/user/0/com.fmsys.snapdrop/cache/test8924247327830305609.php
mime is: text/php
DocumentFileUtils.moveFileTo(DocumentFile.fromFile(tempFile), this, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "test.php", new FileCallback(...));
Hello! When I copy a folder to a directory containing a folder of the same name, a conflict arises that can be resolved with "Replace, Merge, Create New, Skip Duplicate". In my case, the "Merge" method will do. Unfortunately, this method will not allow you to perform the classic merging of folders, when the folders are saved and the files are replaced with new ones. Maybe I didn’t figure it out completely, but I didn’t find a way to do something like that.
Android Studio Arctic Fox | 2020.3.1 Patch 1
OS - macOS 10.15.7
After adding random strings in gradle.properties:
anggrayudi_maven_username=abc
anggrayudi_maven_password=xyz
Still getting below errors
Unable to find method ''com.android.tools.r8.D8Command$Builder com.android.tools.r8.D8Command$Builder.addMainDexRules(java.util.List, com.android.tools.r8.origin.Origin)''
'com.android.tools.r8.D8Command$Builder com.android.tools.r8.D8Command$Builder.addMainDexRules(java.util.List, com.android.tools.r8.origin.Origin)'
Gradle's dependency cache may be corrupt (this sometimes occurs after a network connection timeout.)
Re-download dependencies and sync project (requires network)
The state of a Gradle build process (daemon) may be corrupt. Stopping all Gradle daemons may solve this problem.
Tried Multiple Time didn't work
Stop Gradle build processes (requires restart)
Your project may be using a third-party plugin which is not compatible with the other plugins in the project or the version of Gradle requested by the project.
Tried Multiple Time didn't work
In the case of corrupt Gradle processes, you can also try closing the IDE and then killing all Java processes.
Did't work
Will there be multiple files picker?
I have created an image using the below code.
val imageMediaFile = MediaStoreCompat.createImage(this, FileDescription("image1.jpg", subFolder = "Imgur Images", mimeType = "image/jpg"), ImageMediaDirectory.PICTURES)!!
Later I would get the image back, and I use:
val fetched = MediaStoreCompat.fromFileNameContains(this, mediaType = MediaType.IMAGE, containsName = "image1.jpg")
However this always returns null, am I doing something wrong?
I'm trying to use a library like Fetch (https://github.com/tonyofrancis/Fetch) to download: photos, videos, audios and documents to the filesystem. What is the correct way to generate a path for simple storage to download to?
findViewById<FloatingActionButton>(R.id.fab).setOnClickListener {
val tsLong = System.currentTimeMillis() / 1000
val ts = tsLong.toString()
val url = "https://unsplash.com/photos/FQq88kJLoyI/download?force=true"
val mediaFile = MediaStoreCompat.createImage(this, FileDescription("image${ts}.jpg", subFolder = "Bramti Images", mimeType = "image/jpg"), ImageMediaDirectory.PICTURES)
// val intent = Intent(applicationContext, DownloadService::class.java)
// intent.putExtra("downloadUrl", url)
val path = mediaFile!!.absolutePath
// intent.putExtra("saveFilePath", path)
enqueueDownload(url, path)
}
}
private fun enqueueDownload(url: String, filePath: String) {
request = Request(url, filePath)
fetch.attachFetchObserversForDownload(request.id, this)
.enqueue(request, { result -> request = result }, { result -> Log.d("MainActivity", "SingleDownloadActivity Error: %1${result}s") })
}
I hope theres a sample apk or demo so we can try how it works on android11
Adding this lib as dependency throws build error
Build error More than one file was found with OS independent path 'META-INF/core-ktx_release.kotlin_module'.
Library version: 0.9.0
OS version: [Android 10]
Device model: [Vivo v11 Pro]
Describe the bug
Getting getAbsolutePath{}
as blank but the name is there.
To Reproduce
implementation "com.anggrayudi:storage:0.9.0"
private lateinit var storage: SimpleStorageHelper
storage = SimpleStorageHelper(this)
storage.onStorageAccessGranted = { _, root ->
Toast.makeText(
this,
getString(
R.string.ss_selecting_root_path_success_without_open_folder_picker,
root.getAbsolutePath(this)
),
Toast.LENGTH_SHORT
).show()
}
storage.onFileSelected = { _, file ->
Toast.makeText(baseContext, "File selected: ${file.fullName}", Toast.LENGTH_SHORT)
.show()
val fileLocation = file.getAbsolutePath(this@UploadDocument)
logUtil.logV(">>>>> the name is : ${file.name}")
logUtil.logV(">>>>> if file : ${file.isFile}")
logUtil.logV(">>>>> the location : $fileLocation")
gotFile(
File(fileLocation)
)
}
storage.openFilePicker(REQUEST_CODE_PICK_FILE, "image/*", "application/pdf")
Stacktrace
V: >>>>> the name is : IMG-20210712-WA0000.jpg
V: >>>>> if file : true
V: >>>>> the location :
Does it work on Android 11?
Hey :)
Nice work! And thanks very much for the simplificity.
Are there any plans for compability with jetpack compose / ComponentActivity to requesting storage access with SimpleStorage
Greets
Viktor
Does simple storage support detect usb mass storage? such as usb pen drive or hdd external storage devices.
when i try listing using DocumentFileCompat.getStorageIds(context), it only shows storage volume in /storage/...
Any suggestion read/write file from/to usb mass storage? or this SimpleStorage library will extend to usb mass storage reader also?
If copying the same file to same destionation with
@Override
public void onConflict(@NotNull DocumentFile destinationFile, @NotNull FileCallback.FileConflictAction action) {
action.confirmResolution(ConflictResolution.REPLACE);
}
the app tombstones
Works only the first time...
What feature you want to suggest?
The library currently pulls in the material-dialogs library as an api
dependency, and forces it onto the classpath of users of the library. I want it to be dropped, since it both inflates APK sizes for most users as well as pollutes autocomplete results when using APIs such as Material Design Components' MaterialAlertDialogBuilder
.
Your solution
Your current alternative
None
i use new SimpleStorageHelper(this).requestStorageAccess(SimpleStorageHelper.REQUEST_CODE_STORAGE_ACCESS,false);
but the folder picker opens afterwards anyway
Unzip feature should be added next update since File util didnt work anymore in Android11
Library version: 0.12.0
OS version: [Android 11]
Describe the bug
[cannot move , copy file or folder in java Is get a ""]
moveFile(source1, destinationFolder1); and is values below by (log.d).
(androidx.documentfile.provider.SingleDocumentFile@7831242 , androidx.documentfile.provider.TreeDocumentFile@36b1253)
my code is
DocumentFile source1, destinationFolder1;
findViewById(R.id.btnStartMoveFile).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("TAG", String.valueOf(source1)+ " "+destinationFolder1);
moveFile(source1, destinationFolder1);
}
});
private void moveFile(DocumentFile source, DocumentFile destinationFolder) {
DocumentFileUtils.moveFileTo(source, getApplicationContext(), destinationFolder, null, new FileCallback() {
@Override
public void onCompleted(@NotNull Object result) {
Toast.makeText(getBaseContext(), "File copied successfully", Toast.LENGTH_SHORT).show();
}
@Override
public void onFailed(ErrorCode errorCode) {
Toast.makeText(getBaseContext(), "Failed copying file: "+errorCode.toString(), Toast.LENGTH_SHORT).show();
}
});
}
storageHelper.setOnFileSelected((requestCode, files) -> {
//String message = "File selected: " + DocumentFileUtils.getFullName(files.get(0));
//Toast.makeText(getBaseContext(), message, Toast.LENGTH_SHORT).show();
TextView textView = findViewById(R.id.layoutMove_srcFile).findViewById(R.id.tvFilePath);
textView.setText(DocumentFileUtils.getFullName(files.get(0)));
source1 = files.get(0);
return null;
});
storageHelper.setOnFolderSelected((requestCode, folder) -> {
//String message = "Folder selected: " + DocumentFileUtils.getAbsolutePath(folder, JavaActivity.this.getBaseContext());
//Toast.makeText(JavaActivity.this.getBaseContext(), message, Toast.LENGTH_SHORT).show();
TextView textView = findViewById(R.id.layoutMoveFile_targetFolder).findViewById(R.id.tvFilePath);
textView.setText(DocumentFileUtils.getAbsolutePath(folder,getBaseContext()));
destinationFolder1 = folder;
return null;
});
Stacktrace
D/TAG: androidx.documentfile.provider.SingleDocumentFile@255705c androidx.documentfile.provider.TreeDocumentFile@9c50f65
I/.storage.sampl: Thread[6,tid=7486,WaitingInMainSignalCatcherLoop,Thread*=0xe2e8b610,peer=0x13040268,"Signal Catcher"]: reacting to signal 3
I/.storage.sampl: Wrote stack traces to tombstoned
Hi!
I'm trying to create a new audio file using MediaStoreCompat.createAudio()
so I can write bytes to it using MediaFile.openOutputStream()
. It works well on Android 11, but when running on Android 9, my code crashes with the following error:
java.lang.NoClassDefFoundError: Failed resolution of: Landroid/provider/MediaStore$Downloads;
at com.anggrayudi.storage.media.MediaType.(MediaType.kt:18)
at com.anggrayudi.storage.media.MediaStoreCompat.createAudio(MediaStoreCompat.kt:58)
Here's the piece of code that causes the crash:
private val fileDesc = FileDescription(name, LIBRARY_FOLDER, MIME_TYPE_WAV)
private val tmpMediaFile: MediaFile? = MediaStoreCompat.createAudio(context, fileDesc, AudioMediaDirectory.MUSIC, true)?.apply {
isPending = true
}
The problem seems to be that the MediaType
enum declares the DOWNLOADS
entry using MediaStore.Downloads
(added in API level 29), thus making it non-accessible from earlier versions. My expectation was that using MediaStoreCompat
(and the SimpleStorage library as a whole) would allow me to work with "files" regardless of runtime API versions (or at least with minSDK >= 21).
Am I missing something? Is there a way to achieve my goal using MediaStoreCompat
or any other API from SimpleStorage?
Thanks!
enum class MediaType(val readUri: Uri, val writeUri: Uri) {
IMAGE(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, MediaStore.Images.Media.getContentUri(MediaStoreCompat.volumeName)),
AUDIO(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, MediaStore.Audio.Media.getContentUri(MediaStoreCompat.volumeName)),
VIDEO(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, MediaStore.Video.Media.getContentUri(MediaStoreCompat.volumeName)),
@RequiresApi(Build.VERSION_CODES.Q)
DOWNLOADS(MediaStore.Downloads.EXTERNAL_CONTENT_URI, MediaStore.Downloads.getContentUri(MediaStoreCompat.volumeName))
}
My setup:
compileSDKversion = 30
minSDKversion = 21
targetSDKversion = 29
simple_storage_version = '0.5.3'
I don't know if this issue is related to SimpleStorage, so if you think this issue isn't pertinent, feel free to close it as you want!
So I'd like to write to a file (I'm doing a text editor), so I made this function :
fun writeToFile(context: Context, documentFile: DocumentFile, content: String) {
val bf = documentFile.openOutputStream(context)!!.bufferedWriter()
bf.write(content)
}
And I know this function is executed (putting a print with the content works) but the content isn't written to the file
package com.victorb.androidtexteditor
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.text.Editable
import android.view.Menu
import android.view.MenuItem
import android.widget.EditText
import android.widget.Toast
import android.widget.Toolbar
import androidx.documentfile.provider.DocumentFile
import com.anggrayudi.storage.SimpleStorageHelper
import com.anggrayudi.storage.file.*
import com.google.android.material.textfield.TextInputEditText
import java.io.BufferedReader
import java.io.FileReader
class MainActivity : AppCompatActivity() {
private lateinit var storageHelper: SimpleStorageHelper
private lateinit var openedFile: DocumentFile
override fun onCreate(savedInstanceState: Bundle?) {
// Default actions
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Set up toolbar
val toolbar = findViewById<androidx.appcompat.widget.Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
// Set Simple Storage helper
storageHelper = SimpleStorageHelper(this, savedInstanceState)
// When a file is opened
storageHelper.onFileSelected = { _: Int, documentFile: DocumentFile ->
openedFile = documentFile
val content = getFileContent(this, documentFile)
findViewById<EditText>(R.id.editTextTextMultilineContent).setText(content)
toolbar.title = documentFile.name
}
// Ask for a file
storageHelper.openFilePicker(1, "text/*")
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_toolbar, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.item_save_file -> {
val content = findViewById<EditText>(R.id.editTextTextMultilineContent).text.toString()
writeToFile(this, openedFile, content)
Toast.makeText(this, "Saved file successfully", Toast.LENGTH_LONG).show()
}
}
return super.onOptionsItemSelected(item)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
storageHelper.storage.onActivityResult(requestCode, resultCode, data)
}
override fun onSaveInstanceState(outState: Bundle) {
storageHelper.storage.onSaveInstanceState(outState)
super.onSaveInstanceState(outState)
}
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
storageHelper.storage.onRestoreInstanceState(savedInstanceState)
}
}
package com.victorb.androidtexteditor
import android.content.Context
import androidx.documentfile.provider.DocumentFile
import com.anggrayudi.storage.file.openInputStream
import com.anggrayudi.storage.file.openOutputStream
fun getFileContent(context: Context, documentFile: DocumentFile): String {
val sb = StringBuilder()
val bf = documentFile.openInputStream(context)!!.bufferedReader()
var line = bf.readLine()
while (line != null) {
sb.append(line)
line = bf.readLine()
}
return sb.toString()
}
fun writeToFile(context: Context, documentFile: DocumentFile, content: String) {
val bf = documentFile.openOutputStream(context)!!.bufferedWriter()
bf.write(content)
}
i use DocumentFileUtils.moveFileTo
and in the
@Override
public void onCompleted(@NotNull Object file) {
DocumentFile documentFile = (DocumentFile) file;
...
intent.setDataAndType(file.getUri(), fileHeader.mime);
this always gives my an FileUriExposedException for exposing beyond the app (file:///
), how do i get a valid FileProvider from inside onCompleted?
dear sir, (please java)
please discribe a scenario of get content(Image or Video) uri or Accessable path in android 11 scope storage.
or add a this type example for your simpleStorage Library in java .
i am running in andorid 11 and i have not found any solution for get content (uri or accessable path) from ACTION_OPEN_DOCUMENT_TREE Intent.
please help. sir
Hello again! First, sorry for making a ton of issues
So I'm taking a file doing
// When a file is opened
storageHelper.onFileSelected = { _: Int, documentFile: DocumentFile ->
openedFile = documentFile
val content = getFileContent(this, documentFile)
findViewById<EditText>(R.id.editTextTextMultilineContent).setText(content)
toolbar.title = documentFile.name
}
// Ask for a file
storageHelper.openFilePicker(1, "text/*")
But when I try to edit it it says
java.lang.IllegalArgumentException: Media is read-only
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.victorb.androidtexteditor, PID: 16378
java.lang.IllegalArgumentException: Media is read-only
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:172)
at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:153)
at android.content.ContentProviderProxy.openAssetFile(ContentProviderNative.java:704)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1816)
at android.content.ContentResolver.openOutputStream(ContentResolver.java:1518)
at com.anggrayudi.storage.extension.UriUtils.openOutputStream(UriExt.kt:64)
at com.anggrayudi.storage.file.DocumentFileUtils.openOutputStream(DocumentFileExt.kt:656)
at com.anggrayudi.storage.file.DocumentFileUtils.openOutputStream$default(DocumentFileExt.kt:656)
at com.victorb.androidtexteditor.FileUtilsKt.writeToFile(FileUtils.kt:23)
at com.victorb.androidtexteditor.MainActivity.onOptionsItemSelected(MainActivity.kt:55)
at android.app.Activity.onMenuItemSelected(Activity.java:4269)
at androidx.fragment.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:384)
at androidx.appcompat.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:228)
at androidx.appcompat.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:109)
at androidx.appcompat.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:109)
at androidx.appcompat.app.ToolbarActionBar$2.onMenuItemClick(ToolbarActionBar.java:65)
at androidx.appcompat.widget.Toolbar$1.onMenuItemClick(Toolbar.java:207)
at androidx.appcompat.widget.ActionMenuView$MenuBuilderCallback.onMenuItemSelected(ActionMenuView.java:779)
at androidx.appcompat.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:834)
at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158)
at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:985)
at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:975)
at androidx.appcompat.widget.ActionMenuView.invokeItem(ActionMenuView.java:623)
at androidx.appcompat.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:151)
at android.view.View.performClick(View.java:7455)
at android.view.View.performClickInternal(View.java:7432)
at android.view.View.access$3600(View.java:810)
at android.view.View$PerformClick.run(View.java:28313)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7663)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
It does it with all the files
I use Android 11, and strangely in a A11 emulator it works, it does that on my real device only
How can I be sure I'll be able to edit the file?
Library version: 0.6.0
OS version: [Android 11]
Device model: [Samsung A71]
Describe the bug
When using copyFileTo (context, targetFolder, null, callback), it throws the override fun onFailed(errorCode: FileCallback.ErrorCode), with an error STORAGE_PERMISSION_DENIED.
This isn't happening with version 0.5.2
To Reproduce
DocumentFile copy to app specific files, not to the shared storage.
Stacktrace
[If applicable]
I have looked at the help i could find on SimpleStorage but cant seem to get started..
Any help available on implementing this into java,
selecting folders and files doesn't seem to work and thats before i try to grab the results, as i said im a little stuck right at the start.
Many thanks,
Hello! I have this code, which uses storageHelper.openFilePicker()
, and it asks me to open a folder anyway. I can select a folder and can't click on a file (it doesn't do anything), just like a folder picker. I guess it's an android issue?
class ListFilesActivity : AppCompatActivity() {
private lateinit var storageHelper: SimpleStorageHelper
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
storageHelper = SimpleStorageHelper(this, savedInstanceState)
storageHelper.requestStorageAccess()
storageHelper.onFileSelected = { i: Int, documentFile: DocumentFile ->
println(documentFile.name)
}
storageHelper.openFilePicker()
}
override fun onSaveInstanceState(outState: Bundle) {
storageHelper.storage.onSaveInstanceState(outState)
super.onSaveInstanceState(outState)
}
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
storageHelper.storage.onRestoreInstanceState(savedInstanceState)
}
}
missing constructor
Library version: 0.x.x
OS version: [Android 10]
Device model: [Samsung S20]
Describe the bug
[A clear and concise description of what the bug is]
I did not authorize any added apps applied by a unknown vendor
To Reproduce
[Explain the steps to reproduce]
Stacktrace
[If applicable]
I want to allow users to select only images(jpg, jpeg, png) and pdf files.
i want something like this -
storage.openFilePicker(REQUEST_CODE_PICK_FILE,"image/*,application/pdf")
As of now, I can only select only pdf or only images. not multiple.
What feature you want to suggest?
i want to upload file in server , but my upload mechanism if not supporting documentfile
so i want to convert documentfile to file so i can upload file
Your solution
currently i converting path for absolute path and use for upload
but this is not working each and every time
Your current alternative
i try to find convert documentfile to normal file but there is no solution or didn't get anything that help me
android 10
If you copy or move from folder A
to folder B
, folder B (1)
will be created in the same level directory of B
. the copied or moved files will be in folder B (1)
, and there is no such file in folder B
From translation
I would like to copy selected file to PRIVATE_STORAGE on Android 11 to get an allowed file to use later
storageHelper.setOnFileSelected((integer, documentFiles) -> {
DocumentFile sourceFile = documentFiles.get(0);
DocumentFileUtils.copyFileTo(sourceFile, context, **PRIVATE_STORAGE**, null, callBack);
return null;
});
Can you please help?
i use
DocumentFileUtils.moveFileTo(DocumentFile.fromFile(file), this, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), name, new FileCallback()
the source file is a jpg but doesnt have a file extension (image) the new name
contains an extension (image.jpg) but what i get in the downloads folder is image.jpg.bin
createDownload
function inside MediaStoreCompat
has the hardcoded folder name Environment.DIRECTORY_DOWNLOADS
Also, createDownload
@RequiresApi(Build.VERSION_CODES.Q)
I also tried createDownloadWithMediaStoreFallback
from DocumentFileCompat
which also stores the file in Downloads folder
So, how can I create a file inside the public Documents folder for all versions?
Library version: 0.12.0
OS version: Android 11
Device model: Emulator
compileSdkVersion 29
buildToolsVersion '28.0.3'
minSdkVersion 19
targetSdkVersion 29
On my Android project, on the launcher Activity, I use SimpleStorageHelper with onFileSelected. The onFileSelected method never runs.
The project is mainly written in Java, but I have added Kotlin support.
When I create a brand new project in Java, onFileSelected method runs.
When I create a brand new project in Kotlin, onFileSelected method runs.
In the aforementioned project, when I create a new Activity in Java and I use SimpleStorageHelper with onFileSelected in it, then I start this new Activity from the aforementioned Activity, the onFileSelected method runs!!
I have tried to use the Android Studio debugger. The debugger doesn't step into onFileSelected.
I cannot understand where is the problem.
Hello, when I have not grant access to the folder, I get the normal alert, I grant access, but I can't get the file.
If I try again I receive the following alert:
"You have no write access to this storage, thus selecting this folder is useless. Would you like to grant access to this folder?"
I don't want to write/move any file, I want only to pick a file.
On second launch of my app, when I try to pick the file, it works fine. I get this only in first time when I grant access.
Is this a bug? Can I restrict it to pick only files, not write/move?
Thanks in advance.
I got the callback in filePickerCallback onFileSelected. Now I want to read it and create a preview of this file to show on UI. How can I do that?
Any suggestion?
As of now i am getting
java.io.FileNotFoundException: /content:/com.android.providers.downloads.documents/document/raw%3A%2Fstorage%2Femulated%2F0%2FDownload%2FReceived%2FScreenshot_2021-05-12-12-13-57-317_com.android.chrome.jpg: open failed: ENOENT (No such file or directory)
Please also support adding code example for SimpleStoreHelper in Java. Thank you. I am looking forward to get your respond.
`class MainActivity : AppCompatActivity() {
private val storageHelper = SimpleStorageHelper(this)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
storageHelper.onFolderSelected = { requestCode, folder ->
// do stuff
}
storageHelper.onFileSelected = { requestCode, file ->
// do stuff
}
btnRequestStorageAccess.setOnClickListener { storageHelper.requestStorageAccess() }
btnOpenFolderPicker.setOnClickListener { storageHelper.openFolderPicker() }
btnOpenFilePicker.setOnClickListener { storageHelper.openFilePicker() }
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
// Mandatory for Activity, but not for Fragment & ComponentActivity
storageHelper.storage.onActivityResult(requestCode, resultCode, data)
}
override fun onSaveInstanceState(outState: Bundle) {
storageHelper.onSaveInstanceState(outState)
super.onSaveInstanceState(outState)
}
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
storageHelper.onRestoreInstanceState(savedInstanceState)
}
}
`
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.