Retrieving file on sdcard with this path: "/document/primary:..." - java

I'm trying to read contents of a CSS file, which is on my SDCARD.
I'm selecting the file from a action:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("text/css");
startActivityForResult(intent, 1);
Here I grab the path:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
SharedPreferences sharedPref = PreferenceManager
.getDefaultSharedPreferences(getActivity().getApplicationContext());
SharedPreferences.Editor editor = sharedPref.edit();
if (requestCode == 1) {
if(resultCode == Activity.RESULT_OK){
Log.d("FilePicker", data.getData().toString());
editor.putString("custom_style_file", data.getData().getPath());
editor.commit();
}
if (resultCode == Activity.RESULT_CANCELED) {
//Write your code if there's no result
}
}
}
I get the following path /document/primary:CustomCSS/myCustom.css
Then i try to read the contents of the file with this function:
public static String readFromSDcard(String path) {
File sdcard = Environment.getExternalStorageDirectory();
//Get the text file
File file = new File(sdcard, path);
//Read text from file
StringBuilder text = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
}
br.close();
}
catch (IOException e) {
//You'll need to add proper error handling here
}
Log.d("Read from file", text.toString());
return text.toString();
}
The function returns nothing, and I'm not sure what I'm doing wrong here.

//You'll need to add proper error handling here
If you do so you will see why your function returns nothing.
For instance:
text.append("IOException: " + e.getMessage() + "\n");
Your path:
/document/primary:CustomCSS/myCustom.css
That is not a file syctem path but a content provider path.
So get a content resolver and then let it open an input stream for the file. After that you can use the usual code to read the contents.
Google for getContentResolver().openInputStream().

Make sure you have the the read storage permission in your manifest file
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Related

not able to get full real path with name of selected file [duplicate]

This question already has answers here:
Android Kotlin: Getting a FileNotFoundException with filename chosen from file picker?
(5 answers)
Android - Get real path of a .txt file selected from the file explorer
(1 answer)
Closed 2 years ago.
I am not geting currect path var name "FilePath" im geting value E/File path: /document/29 but my selected file stored in downloads folder file name is "test.xlsx" i need original path with file name with file extention to pass in FileInputStream().I am not able to fix it ...can anybody give the code
btnimport.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent fileintent = new Intent(Intent.ACTION_GET_CONTENT);
fileintent.setType("*/*");
try {
startActivityForResult(fileintent, requestcode);
} catch (ActivityNotFoundException e) {
lbl.setText("No activity can handle picking a file. Showing alternatives.");
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data == null)
return;
switch (requestCode) {
case requestcode:
String FilePath = data.getData().getPath();
Log.e("File path", FilePath);
if (FilePath.contains("/root_path"))
FilePath = FilePath.replace("/root_path", "");
Log.e("New File path", FilePath);
try {
if (resultCode == RESULT_OK) {
AssetManager am = this.getAssets();
InputStream inStream;
Workbook wb = null;
try {
inStream = new FileInputStream(FilePath);
Log.e("Extension",FilePath.substring(FilePath.lastIndexOf(".")));
if (FilePath.substring(FilePath.lastIndexOf(".")).equals(".xls")) {
Log.e("File Type", "Selected file is XLS");
wb = new HSSFWorkbook(inStream);
}
else if (FilePath.substring(FilePath.lastIndexOf(".")).equals(".xlsx")) {
Log.e("File Type", "Selected file is XLSX");
wb = new XSSFWorkbook(inStream);
}
else {
wb = null;
lbl.setText("Please select a valid Excel file");
return;
}
inStream.close();
i need original path with file name with file extention to pass in FileInputStream().
No you do not need 'a real path' as you better use the obtained uri to open an input stream.
InputStream is = getContentResolver().openInputStream(data.getData());
Use that stream as if it was your wanted stream.

How to read and write to SD card?

I have an app that can open and edit binary file from external SD card. I want to have possibility to save this file back from where it was opened.
I have added permissions in manifest file and I also ask user for permission.
Thanks to those permissions I can open file and get the data but when I want to save file to external SD card there is an error: java.io.FileNotFoundException: /storage/3834-3433/file.bin: open failed: EACCES (Permission denied).
Here is code for granting permission:
public boolean isStoragePermissionGranted() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
return true;
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
}
else {
return true;
}
}
Here is the code for choosing and getting file path:
button.setOnClickListener(v -> {
intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
startActivityForResult(intent, 200);
});
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case 200:
if (resultCode == RESULT_OK) {
String filePath = Objects.requireNonNull(data.getData()).getPath();
filePathMain = filePath;
}
break;
}
}
And this is the part of code to save file:
void byteArrayToFile() {
try (OutputStream out = new FileOutputStream(filePathMain)) {
out.write(outBytes);
} catch (IOException e) {
e.printStackTrace();
}
}
I have no idea why it allows me to open file but not to write when I have <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />.
I also had to run this app on the real device because when I run this on emulator there is an error that it can't find the file I choose.
I could really use some help on this. Thank You.
Based on #CommonsWare comment I changed from ACTION_GET_CONTENT to ACTION_OPEN_DOCUMENT to get a file Uri.
Also used ContentResolver to read:
InputStream inputStream = getContentResolver().openInputStream(uri);
and write to file:
ParcelFileDescriptor pfd = getContentResolver().openFileDescriptor(uri, "w");
FileOutputStream fileOutputStream = new FileOutputStream(pfd.getFileDescriptor());
And now it's working properly.

I am getting a FileNotFoundException but the file is there

When I try to open a file that I selected via an Intent I get this error:
java.io.FileNotFoundException:
/document/primary:Android/data/com.oli.myapp/Files/test.xml: open
failed: ENOENT (No such file or directory)
I don't know why this happens. The file exists because I selected it. Here is my Code:
File selection:
Intent chooseFileXML = new Intent(Intent.ACTION_GET_CONTENT);
Uri uri = Uri.parse(new Helper(FunctionsActivity.this).getPathToAppFolder());
chooseFileXML.setDataAndType(uri, "text/xml");
Intent intentXML = Intent.createChooser(chooseFileXML, getString(R.string.importXMLDatei));
startActivityForResult(intentXML, REQUEST_CODE_IMPORT_XML_FILE);
Code to get it:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
switch (requestCode){
case REQUEST_CODE_IMPORT_XML_FILE:
if(resultCode == RESULT_OK){
String Fpath = data.getDataString();
File file = new File(Fpath);
Intent intent = new Intent(FunctionsActivity.this, CreateActivity.class);
intent.setAction(Intent.ACTION_DEFAULT);
intent.setData(Uri.parse(file.toURI().toString()));
startActivity(intent);
}
break;
}
}
EDIT:
Uri uri = data.getData();
DocumentFile documentFile = DocumentFile.fromSingleUri(this, uri);
String type = documentFile.getType();
if(type.equals("text/xml")){
try {
InputStream inputStream = getContentResolver().openInputStream(uri);
if(inputStream == null){
throw new Exception();
}
BufferedReader r = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder total = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
total.append(line).append('\n');
}
//Could read the file with no problems
createWithXMLCode(total.toString());
}catch (Exception e){
e.printStackTrace();
//TODO
}
}else{
//TODO
}
ACTION_GET_CONTENT gives you a Uri. What the user chooses through ACTION_GET_CONTENT does not have to be a file at all, let alone one you can access. In this case, you are getting a Uri back with a content scheme, which is very common.
Use a ContentResolver and methods like getInputStream() to work with the content represented by that Uri.

Parse: cannot upload file

I want to make an app which have upload file function. But the problem is, I unable to find where did I do wrong.
First, choose the file
public void onClick(View arg0) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
// intent.addCategory(Intent.CATEGORY_OPENABLE);
try {
Log.d(TAG, "Select file");
startActivityForResult(
Intent.createChooser(intent, "Select a File to Upload"),
RESULT_LOAD_FILE);
} catch (android.content.ActivityNotFoundException ex) {
// Potentially direct the user to the Market with a Dialog
Toast.makeText(MainActivity.this, "Please install a File Manager.", Toast.LENGTH_SHORT).show();
}
// here
}
I guess there's no problem when choosing the file based on the logcat. But...
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
Log.d(TAG, requestCode+"/"+RESULT_LOAD_FILE+"/"+resultCode+"/"+RESULT_OK);
if (data != null) Log.d(TAG, data.toString());
else Log.d(TAG, "data null");
// get file name
String fileNameSegments[] = filePath.split("/");
fileName = fileNameSegments[fileNameSegments.length - 1];
// convert it to byte
byte[] fileByte = fileName.getBytes();
// Create the ParseFile
ParseFile file = new ParseFile(fileName, fileByte);
// Upload the image into Parse Cloud
file.saveInBackground();
// Create a New Class called "ImageUpload" in Parse
ParseObject fileupload = new ParseObject("FileUpload");
// Create a column named "ImageName" and set the string
fileupload.put("FileName", fileName);
// Create a column named "ImageFile" and insert the image
fileupload.put("DocFile", file);
// Create the class and the columns
fileupload.saveInBackground();
// Show a simple toast message
Toast.makeText(MainActivity.this, "File Uploaded", Toast.LENGTH_SHORT).show();
}
The logcat show requestCode, RESULT_LOAD_FILE, resultCode and RESULT_OK 1, 1, -1 and -1 respectively. And the data is not null, as in logcat: Intent { dat=content://com.android.externalstorage.documents/document/0A09-1112:Download/Contact n Tort.pdf flg=0x1 }
After I click the .pdf file, it triggered the toast Something went wrong but I can't find what the reason.
EDITED:
Throw null pointer exception after convert the file path to byte, when I remove the try catch block
it should be like this
Uri uri = data.getData();
// get path
filePath = uri.getPath();
// get file name
String fileNameSegments[] = filePath.split("/");
fileName = fileNameSegments[fileNameSegments.length - 1];
// convert it to byte
byte[] fileByte = fileName.getBytes();
// Create the ParseFile
ParseFile file = new ParseFile(fileName, fileByte);
// Upload the file into Parse Cloud
file.saveInBackground();
// Create a New Class called "FileUpload" in Parse
ParseObject fileUpload = new ParseObject("FileUpload");
// Create a column named "FileName" and set the string
fileUpload.put("FileName", fileName);
Log.d(TAG, "image file");
// Create a column named "ImageFile" and insert the image
fileUpload.put("DocFile", file);
// Create the class and the columns
fileUpload.saveInBackground();
Log.d(TAG, "toast");
// Show a simple toast message
Toast.makeText(MainActivity.this, "File Uploaded",
Toast.LENGTH_SHORT).show();
though the class not created in parse dashboard but I guess that need another post.

How to get file path of any text file and read it from SD card in Android?

I have got so many links related to image file but didn't get any text related. There is solution for specific text file to open but I need general solution and not hard coded file location on SD card. I'm building an Android app that gets (copyies) the link of the file in TextView and reads the content of that file in another TextView from SD card. One button which is used to open the SD card:
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("text/plain"); //open only for text file
intent.setAction(Intent.ACTION_GET_CONTENT);
//broadcast the supported media to choose for file to open
startActivityForResult(Intent.createChooser(intent, "Select file"), MY_INTENT_CLICK);
}
This is the code for onActivityResult()
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == MY_INTENT_CLICK) {
if (data == null) return;
//String sel_file_path;
String sel_file_path;
Uri sel_file_uri = data.getData();
sel_file_path = FileText.getPath (getApplicationContext(), sel_file_uri);
setTextViews (sel_file_path);
}
}
}
After getting the file path from FileText it views the link and content of text file using this method.
//show the link and display the content of the file
private void setTextViews(String sel_file_path) {
//copy the file link to textview
this.txtpath.setText("File path: " +sel_file_path);
//display the text file
try {
File file1 = new File(sel_file_path);
//System.out.println("Path : " + file1);
FileInputStream fis = new FileInputStream(file1);
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
String datatoread = "";
String inBuffer = "";
//Read the line of the file, store it in temporary variable and append it to inBuffer
while ((datatoread = br.readLine()) != null) {
inBuffer += datatoread + "\n";
}
txtdsp.setText(inBuffer);
br.close();
//Toast.makeText(getBaseContext(), "Load file reading", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_LONG).show();
}
Log.d("MainActivity", "File Path: "+sel_file_path);
}
I got the an error while running on a device:
no such file or directory

Categories