Multiple file sharing intent crashes when launched from ES File Explorer - android

I've written a small file sharing program in android where user can select multiple files for sharing via my app, either from native Android gallery or some file manager (like ES File Explorer). To start with, I'm just displaying the selected file paths in a TextView of MainActivity. Here is my code snippet:
if (Intent.ACTION_SEND_MULTIPLE.equals(getIntent().getAction())
&& getIntent().hasExtra(Intent.EXTRA_STREAM)) {
ArrayList<Parcelable> list = getIntent()
.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
for (Parcelable parcel : list) {
Uri uri = (Uri) parcel;
String sourcepath = getPath(uri);
filepathNameArray.add(sourcepath); //building file path name array from gallery
myTextView.append(sourcepath + "\n"); //displaying selected files' path in textView
}
}
The above code works fine when user selects multiple files from Gallery, but the app crashes when I select files (for sharing via my app) from ES File Explorer. Can anyone please suggest a workaround for this? Thanks for your help!

Related

Android webview - how to pass a large binray file to Javascript

I have a mobile app that wraps around the web-app, using webview.
The web-app has a button to open a large .zip file (e.g. 100 MB).
The user clicks a button, and selects a .zip file.
This triggers an onChange function with a variable of type File (Blob), which includes attributes like:
file name
file size
file type (application/zip)
The javascript code then parses the .zip file, extracts specific data within it and uses it within the web-app.
This works well within the web-app, when the app is called via the Chrome browser.
For example when operated in chrome browser on an Android phone, I can pull the .zip file and open it in the web-app.
I want to do the same but using the mobile app.
I am able to pick up the .zip file using a File Chooser, but I have problems to fetch the file from the Javascript code.
When calling fetch(fileUri) from the Javascript side I'm getting errors.
I'm using the following uri
/storage/emulated/0/Android/data/com.example/files/Download/file2.zip
The fetch succeeds but returns a blob with size of 165 (i.e. not the actual size of the file) which hosts the error message:
{
"error": "Not Found",
"message": "The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again."
}
The program flow is like so:
I select a .zip file via FileChooser.
In onActivityResult, the uri value is /document/msf:12858 (seen via uri = intent.getData();)
The uri needs to be mapped into a real path file url, such that the fileUrl will be passed to Javascript (via webview).
Javascript will then fetch the file using the fileUrl.
I searched how to get the real path file url when selecting a file with FileChooser, and found
this, and this links.
I wasn't able to get the real file path, so I decided to read the file and write it to another location, so I can get a file path. (this is not efficient and done just to check the functionality).
I create the new file using the following code:
InputStream stream = context.getContentResolver().openInputStream(uri);
File file2 = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "file2.zip");
writeBytesToFile(stream, file2);
I don't see any errors when creating the file, and when creating the file, the number of bytes that are read and written to the new file are as expected.
For file2, I get a value of:
/storage/emulated/0/Android/data/com.example/files/Download/file2.zip
Then, within the Javascript code I fetch this file path.
But I'm getting a Blob with the "file-not-found" content as above.
So:
How can I verify that the file is indeed created and that the path can be fetched from Javascript?
How can I get the real file path of the original selected file, so I don't have to read and write the original file to new location just to get the file path?
Thanks
EDIT1:
I have "Intent intent" and not "Intent data" in the signature of onActivityResult.
I replaced String filePath = intent.getData() with
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
try {
intent_to_resolve = new JSONObject();
if (resultCode == RESULT_OK) {
// try1
String filePath1 = intent.getData().toString();
Log.d("Verbose", "filePath1: " + filePath1);
// try2
String filePath2 = intent.toString();
Log.d("Verbose", "filePath2: " + filePath2);
...
I'm getting the following value for filePath:
filePath1: content://com.android.providers.downloads.documents/document/msf%3A12858
filePath2: Intent { dat=content://com.android.providers.downloads.documents/document/msf:12858 flg=0x43 }

Receiving single file from external app is unreadable, but readable when multiple

I have a problem when receiving a file from an external app. I've been following the tutorial on https://developer.android.com/training/sharing/receive.html and it works fine until I want to handle the image in my code.
The problem I have is if I select and send only one file to my app, I am not able to read it after converting it from URI to a FILE object. However, if I send two or more images (the very same image selected before plus an additional one from the same directory), then I actually can read the files (all of them).
Why is that? Even setting the file to setReadable(true); I can not read it afterwards.
Target SDK is 23 and yes, I already implemented the request for permission in the code that is needed from API 23+. So this can't be the problem.
I need to be able to read the received files no matter if it was only one or a list of multiple.
On a side note: if I send any amount of images from the Google Photos app (one or multiple), I never can read the file. Images sent from the "ES File Explorer" app are readable in the code but not readable if I only send one single file to my app.
Here is my code snippet of the problematic part:
// THIS PART WORKS. RECEIVING MULTIPLE FILES ARE READABLE IN THE CODE BELOW.
void handleSendMultipleImages(Intent intent) {
ArrayList<Uri> imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
if (imageUris != null) {
addImagesToNewOrExistingContact(imageUris);
}
}
// THIS PART DOES NOT WORK. I CAN NOT READ THE FILE IN THE CODE BELOW.
private void addImageToNewOrExistingContactDialog(Uri imageUri) {
ArrayList imageUris = new ArrayList<>();
imageUris.add(imageUri);
addImagesToNewOrExistingContact(imageUris);
}
private void addImagesToNewOrExistingContact(final ArrayList<Uri> imageUris) {
for (Uri uri : imageUris) {
File f = new File(uri.getPath());
f.setReadable(true);
f.setWritable(true);
boolean readd = f.canRead(); // FALSE, but why?
boolean exec = f.canExecute(); // FALSE, but why?
}
}
Files I tested this with:
Selected two files from "ES File Explorer" and sent them to my app:
file:///storage/emulated/0/Pictures/Adobe%C2%AE%20Photoshop%C2%AE%20Touch/1452348875289.jpg
file:///storage/emulated/0/Pictures/Adobe%C2%AE%20Photoshop%C2%AE%20Touch/1455733673513.jpg
Both canRead() = TRUE
Selected one file from "ES File Explorer" and sent it to my app:
content://media/external/images/media/33675
canRead() = FALSE
Actually the files content://media/external/images/media/33675 and file:///storage/emulated/0/Pictures/Adobe%C2%AE%20Photoshop%C2%AE%20Touch/1455733673513.jpg are the exact same files.
Selected two files from "Google Photos" and send them to my app:
content://com.google.android.apps.photos.contentprovider/0/1/shared%3A%2Flocal%253A4541959b-3222-4ee0-b838-67049141b864%2FV2xDV01jNWhWVDRCQXRMY202YTh3NFNES1N4M01R/REQUIRE_ORIGINAL/NONE/1290260075
content://com.google.android.apps.photos.contentprovider/0/1/shared%3A%2Flocal%253A20e65034-795f-4300-9472-64a598afc4c1%2FV2xDV01jNWhWVDRCQXRMY202YTh3NFNES1N4M01R/REQUIRE_ORIGINAL/NONE/1096770166
Both canRead() = FALSE
Thanks for any help in advance.
Use openInputStream(uri) on getContentResolver(). No need for a File class.

How to pick file from external storage using file picker in Android

I am having a problem with selecting image file from external storage using file picker in Android. This question is the consequence of this question - No such file or diectory error in image file upload using Retrofit in Android. What my problem is opening and reading file from external storage on activity result. I want to convert result URI into File.
I read a pdf file from download folder on activity result
Uri bookUri = data.getData();
if(bookUri!=null)
{
String filePath = bookUri.toString();//bookUri.toString()
String mime = app.getMimeType(filePath);
if(mime!=null && !mime.isEmpty() && (mime.toLowerCase()=="application/pdf" || mime.toLowerCase()=="application/txt" || mime.toLowerCase()=="application/text"))
{
bookFile = new File(bookUri.getPath());
ivBookFile.setImageResource(R.drawable.book_selected);
}
else{
Toast.makeText(getBaseContext(),"Unable to process file you have chosen.",Toast.LENGTH_SHORT).show();
}
}
As you can see I used new File(bookUri.getPath()); to convert into File. The above code works well. It is working. The problem is now I am trying to open an image file in DCIM/Camera folder on activity result.
This is the code I used
Uri selectedImageUri = data.getData();
if(selectedImageUri!=null)
{
try{
bmpCoverImage = MediaStore.Images.Media.getBitmap(getContentResolver(), selectedImageUri);
imageFile = new File(selectedImageUri.getPath());
if(bmpCoverImage!=null)
{
ivCoverImage.setImageBitmap(bmpCoverImage);
}
}
catch (IOException e)
{
Toast.makeText(getBaseContext(),"An error occurred with the file selected",Toast.LENGTH_SHORT).show();
}
}
As you can see I used new File(selectedImageUri.getPath()); like I did in reading pdf file. This time the code is not working. When I do operation with the file like in previous question, it gives me error.
I used this way also
imageFile = new File(Environment.getExternalStorageDirectory(),selectedImageUri.getPath());
I got the same error. How can I open the image file correctly from external storage? How can I convert the chosen file URI from external storage into File?
I am having a problem with selecting image file from external storage using file picker in Android
If you are referring to the code that you are using in this question, you are not "using file picker". You are using ACTION_GET_CONTENT, which has never been a "file picker", nor will it ever be a "file picker".
I want to convert result URI into File.
Usually, that is not necessary. But, if that is what you want to do:
use ContentResolver and openInputStream() to get an InputStream on the content represented by the Uri
create a FileOutputStream on your desired file
use Java I/O to copy the bytes from the InputStream into the FileOutputStream
The above code works well. It is working.
It works for the small number of devices that you tested, for the specific activities that the user chose to handle the ACTION_GET_CONTENT request. It will not work on most Android devices, and it will not work in most circumstances. The only time that code will work is if the Uri has a file scheme. Most of the time, it will not. Instead, it will have a content scheme, representing content supplied by a ContentProvider.
Please how can I open the image file correctly from external storage?
If you wish to continue using ACTION_GET_CONTENT, please understand that this has nothing to do with external storage specifically. You are not getting a file, on external storage or elsewhere. You are getting a Uri. This is akin to a URL, such as the URL for this Web page. Just as a URL does not necessarily point to a file on your hard drive, a Uri does not necessarily point to a file on the filesystem. Use a ContentResolver and DocumentFile to work with the Uri and the content that it identifies.
If you want to always get files on external storage (and nowhere else), then use an actual file picker library.

Open all image from specific folder in Android default gallery

My requirement is to open all images and video's of specific folder.
I have refereed this link, Now I am able to show a image in gallery but I want to show all images from a specific folder. Almost all link I have tried on stack but did not get success.
You can set path in File object initialize at that time.
File folder = new File("/sdcard/Photo/"); in this tutorial default path is /sdcard/photo/ at this place you can set your path then get your files.
I sinc it is not good idea but you may write your own searcher in all files on mobile phone for example
public ArrayList<File> getAllphotos(String path){
ArrayList<File> photoPath = new ArrayList<>();
File yourDir = new File(path);
for (File f : yourDir.listFiles()) {
String mas[] = f.toString().split("\\.");
if(mas[mas.length - 1].equalsIgnoreCase("png") || mas[mas.length - 1].equalsIgnoreCase("jpeg")){//or other formats
//it is picture
photoPath.add(f);
}
}
return photoPath;
}
call this wis iternal and external storage

To show multimedia content(e.g audio,video,jpeg) from custom folder to a Dialog as file explorer.

I am creating an android app, in which i have created a custom location in external storage ,for example /storage/emulated/0/myfolder/. And it contains my app files which are video,audio and pictures(.mp4,.3gpp,.jpeg).
Is there any way to show the contents of myfolder to a popup or some dialog in list manner.Which will behave like explorer and upon clicking any item in the list ,it will run in appropriate application(e.g video player,audio player or picture viewer).Any help would be appreciated.
File dir = new File(
Environment
.getExternalStoragePublicDirectory(File.separator),
"custom folder name");
String[] files = null;
if (dir.exists()) {
files = dir.list();
}
Now with this files array i extraceted each element and checked its extension to get the mime type and showed accordingly.It worked for me.Most simple code for what i want to achieve.

Categories

Resources