Convert an internal Uri to a File in Android? - java

I have an app that allows the user to select a file from the file chooser. The problem lies when I try to turn that Uri to a File, it creates something that I can't use (/document/raw:/storage/emulated/0/Download/CBTJourney-Backup/EntriesBackup1570487830108) I would like to get rid of everything before raw: but the right way. Where ever I try to copy from that file using InputStream, it doesn't copy anything. It's like the file doesn't exist. Any ideas?
public void chooseDatabaseFile() {
Intent intent = new Intent();
intent.addCategory(Intent.CATEGORY_OPENABLE);
// Set your required file type
intent.setType("*/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Choose Database to Import"),GET_FILE_PATH);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == GET_FILE_PATH && data != null) {
if(resultCode == RESULT_OK){
Uri currFileURI = data.getData();
if(currFileURI == null) {
return;
}
else{
String databasePath = currFileURI.getPath();
// TODO: Determine if actual database
importDatabase(new File(databasePath));
// File produces "/document/raw:/storage/emulated/0/Download/CBTJourney-Backup/EntriesBackup1570487830108"
}
}
}
}

Have you tried changing your mimetype?
Otherwise take a look at:
Convert file: Uri to File in Android

Related

pdfviewer doesnt open File

myfile.exists() return TRUE, however I couldn't open the pdf:
File myfile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
+ File.separator + fileString ); //fileString=sample.pdf
Log.i("here", fileString + "---"+ myfile.exists());
pdfView = findViewById(R.id.pdfViewer);
pdfView.fromFile(myfile)
.defaultPage(0)
.spacing(2)
.load();
I'm using this library for Pdf view in android.
implementation 'com.github.barteksc:android-pdf-viewer:3.2.0-beta.1'
If you wish, I can post all-working snippet code.
(using pdfView.fromUri() works fine but only once. My aim is to pick a .pdf from Intent.ACTION_OPEN_DOCUMENT once and save the uri of it for next usage.
Instead of pdfView.fromFile(), I used pdfView.fromUri(),
pdfView = findViewById(R.id.pdfViewer);
//pdfView.fromFile(myfile)
pdfView.fromUri(Uri.parse(getIntent_uri))
.defaultPage(0)
.spacing(2)
.load();
then after picking file, in onActivityResult() I used takePersistableUriPermission() for make the uri permanent accessible.
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable #org.jetbrains.annotations.Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_PDF_FILE && resultCode == Activity.RESULT_OK && data != null) {
Uri uri = data.getData();
getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
special thanks to #CommonsWare

Android selecting document from device but not able to get the file name with the extension type

I want the user to be able to upload pdf and image file to server and after
selecting the file I want to display the name of the file and the type wether it's .pdf
or .png
But the file extension is not included in the file path
This is how I start the intent
btnUploadDocument.setOnClickListener(view -> {
Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
chooseFile.addCategory(Intent.CATEGORY_OPENABLE);
chooseFile.setType("image/*|application/pdf");
chooseFile = Intent.createChooser(chooseFile, "Choose a file");
startActivityForResult(chooseFile, REQ_UPLOAD_DOCUMENT);
});
and here's how I get the data returned
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == REQ_UPLOAD_DOCUMENT && resultCode == RESULT_OK && data != null){
Uri path = data.getData();
try {
InputStream inputStream = FTLBookingActivity.this.getContentResolver().openInputStream(path);
byte[] pdfInBytes = new byte[inputStream.available()];
inputStream.read(pdfInBytes);
String encodedPDF = Base64.encodeToString(pdfInBytes, Base64.DEFAULT);
Toast.makeText(this, "Document Selected", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I tried selecting an image and the path was having below value
content://media/external/images/media/599
But the file extension is not included in the file path
There is no "file path", as this is not a file.
I want to display the name of the file and the type wether it's .pdf or .png
Use DocumentFile.fromSingleFile() to wrap your Uri in a DocumentFile. You can then use getName() and getType() on the DocumentFile to get a display name and MIME type, respectively.

AndroidStudio getExternalStoragePublicDirectory in API 29

In API 29, getExternalStoragePublicDirectory was deprecated so that I have to find way to convert the following code to API 29
String pathSave = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
+ new StringBuilder("/GroupProjectRecord_")
.append(new SimpleDateFormat("dd-MM-yyyy-hh_mm_ss")
.format(new Date())).append(".3gp").toString();
Thanks for your help!
As mentioned in android docs
Apps can continue to access content stored on shared/external storage
by migrating to alternatives such as
Context#getExternalFilesDir(String)
Try with this method.
public void getFilePath(Context context){
String path = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
+ new StringBuilder("/GroupProjectRecord_")
.append(new SimpleDateFormat("dd-MM-yyyy-hh_mm_ss")
.format(new Date())).append(".3gp").toString();
Log.d(TAG, "getFilePath: "+path);
}
In API 29 and above doing anything with Paths outside of the apps private storage won't work.
See https://developer.android.com/training/data-storage/files/external-scoped for details
So to save you need to do something like:-
// OnClick Save Button
public void Save(View view){
// Ask for a new filename
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
// Restrict to openable items
intent.addCategory(Intent.CATEGORY_OPENABLE);
// Set mimeType
intent.setType("text/plain");
// Suggest a filename
intent.putExtra(Intent.EXTRA_TITLE, "text.txt");
// Start SAF file chooser
startActivityForResult(intent, 1);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent resultData) {
super.onActivityResult(requestCode, resultCode, resultData);
if (requestCode == 1 && resultCode == RESULT_OK) {
Log.d("SAF", "Result code 1");
if (resultData != null) {
Uri uri = resultData.getData();
Log.d("SAF", uri.toString());
// Now write the file
try {
ParcelFileDescriptor pfd =
this.getContentResolver().
openFileDescriptor(uri, "w");
// Get a Java FileDescriptor to pass to Java IO operations
FileDescriptor fileDescriptor = pfd.getFileDescriptor();
// Read Input stream
FileOutputStream fileOutputStream =
new FileOutputStream(fileDescriptor);
// .....
} catch (Exception e){
// Do something with Exceptions
}
} else {
Log.d("SAF", "No Result");
}
}
}

how to pick a file in SD card?

I'm trying to make an app with Android Studio that can select a file in SD card and get its path, like an OpenFileDialog, I've tried this:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("file/*");
startActivityForResult(intent, PICKFILE_REQUEST_CODE);
However, it does not work, how can I do it ?
Try this:
Intent mediaIntent = new Intent(Intent.ACTION_GET_CONTENT);
mediaIntent.setType("*/*"); //set mime type as per requirement
startActivityForResult(mediaIntent,0);
You can change type according to your need.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 0
&& resultCode == Activity.RESULT_OK) {
Uri uri = data.getData();
Log.d("", "Video URI= " + videoUri);
}
}

Picture File on RESULT_CANCELED

I want to be able to track image file names when a picture has been taken with the default Camera Glassware. This is so I can delete them when finished. I have the following code:
...
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, TAKE_PICTURE_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == TAKE_PICTURE_REQUEST && resultCode == RESULT_OK) {
String imgPath = data.getStringExtra(Intents.EXTRA_PICTURE_FILE_PATH);
mService.addToImageQueue(imgPath);
}
else if (requestCode == TAKE_PICTURE_REQUEST && resultCode == RESULT_CANCELED) {
...
}
}
If I tap, the resultCode returns RESULT_OK. When I dismiss (swipe down), I get the resultCode RESULT_CANCELED. This is how I intended it to work, except it still generates the image file even if the resultCode is RESULT_CANCELED... I honestly feel like this might be a bug since I tried to use data.getStringExtra(Intents.EXTRA_PICTURE_FILE_PATH); and got a NullPointerException. Am I doing something wrong? Is there a way to get this file name even on RESULT_CANCELED?
You could create a temporary file first (look at the createImageFile() method in this tutorial). If successfully created, do two things:
Save the path of this file to a String.
Include this file's URI in the intent extra (putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile))).
If resultCode is RESULT_CANCELED, you can now trace back to the path of the temporary file and call delete() on it.
Here is some sample code:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) {
Log.v("MainActivity", "Result successful.");
} else if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_CANCELED) {
Log.v(TAG, "Result canceled. Uri of file is " + mCurrentPhotoPath);
File file = new File(mCurrentPhotoPath);
if (file.exists()) {
Log.v(TAG, "File exists.");
if(file.delete()) {
Log.v(TAG, "File was successfully deleted!");
} else {
Log.v(TAG, "File not successfully deleted.");
}
} else {
Log.v(TAG, "File does not exist!");
}
}
}
Note: For new File(mCurrentPhotoPath) to work, remove "file:" from the beginning of mCurrentPhotoPath.

Categories

Resources