Open PDF file in external app with write permissions - android

I'm using Launcher.Default.OpenAsync(OpenFileRequest request) to open a PDF file in an external PDF editor. The file loads correctly, but to edit the document this external app asks you to make a copy and edit over that copy, not the original file. I can edit the original file if I open the PDF using the device (Galaxy Tab S6 Lite) file explorer but it's not possible to do the same if I open the same file from my MAUI app.
I see OpenFileRequest constructor asks for a ReadOnlyFile. Is there a way I could create an "OpenFileRequest" with write permissions, or an alternative way to launch the document editor with the file so I can edit it without having to create a copy?
Example code:
var filename = "example.pdf";
var file = new ReadOnlyFile(filename);
var openFileRequest = new OpenFileRequest("PDF Document", file);
await Launcher.Default.OpenAsync(openFileRequest);

I have tried to edit the pdf file with the Pdf Editor in some other apps. But all of them need to save as another file. So it seems only the file explorer can edit the original file.
In addition, the ReadOnlyFile is inherited from the FileBase. So you can try:
var filename = "example.pdf";
var file = new ReadOnlyFile(filename);
var openFileRequest = new OpenFileRequest("PDF Document", file as FileBase);
await Launcher.Default.OpenAsync(openFileRequest);
Actually, the other app doesn't have the permission to write the file in your app. You can refer to this case which is about editing pdf with external application does not overwrite existing file.
I can't find any native android api about grant the others app the write permission of the existing file. This should be the android permission limit.

Related

Xamarin.essentials FilePicker copies selected external file to cache folder

For the last 2 weeks I've been successfully converting a WPF application to a Xamarin.forms android app. Everything works as intended except for 1 thing. I've been searching the web for a few days for a solution but I can't find a working solution.
This is my current setup:
Xamarin.Froms android app
Target android version: Android 10.0
Minimum android version: Android 7.0
Xamarin.Essentials version: 1.6.0
READ_EXTERNAL_STORAGE permission
WRITE_EXTERNAL_STORAGE permission
My app should be able to open a selected file, using the Xamarin.Essientials FilePicker, Do some stuff and save the File again to the same path. The file selection is handled in the following code:
var pickresult = await FilePicker.PickAsync();
if (pickresult != null)
{
try
{
var result = await pickresult.OpenReadAsync();
var reader = new StreamReader(result);
var jsonstring = reader.ReadToEnd();
ConfigData = JsonConvert.DeserializeObject<ProjectData>(jsonstring);
PLC_Data.ProjectLoaded = true;
L_LoadedProject.Text = pickresult.FileName;
ProjectData.Filepath = pickresult.FullPath;
reader.Close();
result.Close();
//Load login page
B_Next.IsEnabled = true;
}
This is where the problem occurs. Let me clearify what happens step by step:
The FilePicker opens a File picking window.
I navigate to my preferred file in the "download" folder, could be any folder.
The file is read and converted to an object
The file path is saved
when i check the filepath i get the following string:
"/storage/emulated/0/Android/data/com.FAIS.motorconfigapp/cache/2203693cc04e0be7f4f024d5f9499e13/303bc84665374139b6303c03255e9018/config1.json"
So the FilePicker copies the "External" file to the App cache folder and returns the filepath from the Apps cache folder. When i check this folder there is indeed a copy of my selected file inside it. Reading from and writing to this file works as it should.
Now the actual question:
Why does the FilePicker copy my selected file to his cache folder and how can i prevent it?
The user should be able to select a file from anywere on the device and find the updated file in the same location.
I've checked all my settings and in my opinion everyting should be correct so i don't get why a copy is created. Does anyone have an idea?
If you need more settings, pictures, versions please ask.
Thanks in advance

FileReader is not able to read a file from camera - Xamarin + WebView

I have an APP that is only a container for a VUE PWA. In one page the user could upload some file. I implemented the following solution to give the user the option to select a file from Galery or take a new photo.
https://blog.verslu.is/xamarin/xamarin-forms-xamarin/building-a-hybrid-app-with-xamarin-forms/
The problem is the FileReader is not able to read the file when the user takes a new photo with the camera. if the user selects an existing file, the upload works well. This is the error:
FileReader:
message: "The requested file could not be read, typically due to permission problems that have occurred after a reference to a file was acquired."
name: "NotReadableError"
I noticed one difference: when the user selects a file from galery, the URI path that the APP sent to the WebView looks like the following:
{content://com.android.providers.media.documents/document/image%3A32681}
When the user takes a new photo:
file:///storage/emulated/0/Pictures/JBSTRIP/IMG_637273232207442660.jpg
Anyone had the same problem? I didn't found any solution from web.
Thanks a lot!
I solved the problem.
I changed the directory where the picture from camera is saved:
Instead get the path using:
File imageStorageDir = new File (Android.OS.Environment.GetExternalStoragePublicDirectory (
Android.OS.Environment.DirectoryPictures), "APP");
I used the APP's folder:
File imageStorageDir = new File (_context.GetExternalFilesDir(Android.OS.Environment.DirectoryPictures), "APP");

Where should I choose to save text file in android?

I hope to export my data as a text file and save it to disk in Android, so I need to choose which folder I will save the file to.
I hope that a normal user can find the folder easily and the app does not need special permission to create the folder.
I have read some document, it seems that there are 3 ways: Context.getFilesDir().getAbsolutePath(), Environment.getExternalStorageDirectory().getAbsolutePath() and Context.getExternalFilesDir(null).
You know some android users don't install SD card, so it seems that Environment.getExternalStorageDirectory().getAbsolutePath() and Context.getExternalFilesDir(null) are be excluded.
Am I only to choose Context.getFilesDir().getAbsolutePath()? or is there a better way? Thanks!
BTW, From the document Android - Where to save text files to?
Save it in internal phone storage, here no users and applications can access these files(unless if phone is rooted). But these files will be deleted one's the user selectes clear data from Settings -> Apps -> .
It seems that normal users can't access the saved text files if I use Context.getFilesDir().getAbsolutePath(), is it right?
Use this if you want a path that the user can modify and can have access
getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath();
More documentation here.
EDIT:
This is how use in case error in some devices:
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS);
String fname = "TEXT.txt";
File file = new File(path, fname);
if (!path.exists()) {
//noinspection ResultOfMethodCallIgnored
path.mkdir();
}
// YOUR CODE FOR COPY OR CREATE THE FILE TXT in PATH WITH THE VARIABLE file ABOVE

Exported Text File Invisible?

I have an android app where I am writing data (csv format) to the filesystem for export.
The app writes the file without any problem (I can see it in the file manager app). The issue is when I plug my device into my PC, the file doesn't show up?
I am writing to the downloads directory using this code to get the file path:
public File getDataStorageDir() {
// Get the directory for the user's public pictures directory.
File base = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
base = new File(base, "F3F");
base.mkdirs();
File file = new File(base.getAbsolutePath() + String.format("/%s.txt", mRace.name));
return file;
}
I can export the file to dropbox or email it, but I would also like to be able to plug in via usb and drag it off the filesystem. Could this be something to do with permissions?
Thanks

creating folder in android emulator

I am developing an android application. I need to create a folder in the internal memory, but when I try to create the folder I get the error below. I am running in an emulator.
mkdir failed for /mnt/New Folder , read only file system
I have tried many paths, but still the error persists. The only folder that I am able to create is called "cache", but I cannot browse it by my file chooser activity.
Any idea where is the suitable place to create folders without any permissions?
You can achieve it by this from a Context object (like Activity).
File files_folder = getFilesDir();
File files_child = new File(files_folder, "files_child");
files_child.mkdirs();
File created_folder = getDir("custom", MODE_PRIVATE);
File f1_child = new File(created_folder, "custom_child");
f1_child.mkdirs();
The function
getFilesDir()
will get the folder data/data/yourpackagename/files in internal memory. And the function
getDir("custom", MODE_PRIVATE)
will create a folder name app_custom in your app internal folder.
Answered by Minhtdh
I guess what you call internal memory is atualy the external memory (which can be open by
file chooser activity, the real internal memory only can be open if you have rooted)
If that true, you should chek those belows:
- first, you will need the write storeage permission in Manisfest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
- then you should use `
String path =
Environment.getExternalStorageDirectory().getAbsolutePath() +
"/yourfoldername"
`
than
mnt/yourfoldername
at last you should use mkdirs to create folder than mkdir

Categories

Resources