Android File Read / Write Permissions

Overall I’ve gotten the permissions / read / write sorted now, but have a related question.

I am trying to use an Intent to let the user choose a file. I have the code for this working and get the notification message with the URI of the chosen file.

What I haven’t quite got is converting that URI into a filename path. I can get the filename and extension portion, but not a path that’s suitable for general file functions.

..and you won’t be able to, however the URI can be used by ContentResolver as described here. Once the file is copied to a path accessible without using ContentResolver, you could then use regular Delphi file operations.

1 Like

In the Windows version of the app the media files can be anywhere. I wanted the mobile version to act the same UI wise, but this is probably the wrong way to think about it.

The other thing is how the user will add the media files to the mobile device. If they do it via Windows Explorer then the Documents and Downloads folders that are easily accessible are the shared ones.

I think using the app’s file explorer to locate the file and copy it to my app’s area is the only real way forward. Those file copies would be deleted along with the app when uninstalled which I guess is not an issue.

I’d like to provide a way for the user to export the app settings and those media files, so would have to copy them back out to a more accessible folder. Hopefully permissions won’t be an issue there.

David, you have my complete empathy on android and its file access! If I say what I reckon they have done to their file system in pure Australian, it will immediately be censored in ADUG! There are much better ways to do it, simpler for the user, and more intuitive. You are stuck with producing them then copying them to a directory made accessible with “intents”. Otherwise you may not even be able to access them by connecting to a computer! Make sure you delete them after copying, or you may clog up a lot of space!

1 Like

I’m still plodding away with this app and using the local folders is working well. Keeping the files locally (to the app) means the standard GetFiles works and I populate a TListView for the user to choose from.

The next step will be where I need to copy user added files from the shared folders, but hopefully the choose and copy operation will be easy enough to code with ContentResolver.

I’ve also gotten the hang of the Async versions of the message and input dialogs, but it did mean approaching the event flow a little differently.

Has anyone been able to set the initial folder when launching the file pick and save dialogs in Android? Here’s my procedures. It does work with the notification and I can save the file locally to the app. The title part doesn’t seem to have any visible effect in the pick procedure, but does set the filename in the save procedure.

// AFileType can be */* , 'audio/*' , 'image/*' etc
// ATitle doesn't seem to have a visible effect
// AInitialUri is not working yet
procedure RequestFilePick(AFileType: string; ATitle: string; AInitialFolder: string);
var
 Intent: JIntent;
 InitialUri: Jnet_Uri;
begin
  InitialUri := StrToJURI(AInitialFolder);
  Intent := TJIntent.Create;
  Intent.setType(StringToJString(AFileType));
  Intent.setAction(TJIntent.JavaClass.ACTION_OPEN_DOCUMENT);
  Intent.putExtra(TJIntent.JavaClass.EXTRA_TITLE, StringToJString(ATitle));
  Intent.putExtra(TJDocumentsContract.JavaClass.EXTRA_INITIAL_URI, JParcelable(InitialUri));
  TAndroidHelper.Activity.startActivityForResult(Intent, CON_IntentSelectFile);
end;

// AFileType can be */* , 'audio/*' , 'image/*' etc
// AFileName is the name of the file to save it as
// AInitialUri is not working yet
procedure RequestFileSave(AFileType: string; AFileName: string; AInitialFolder: string);
var
 Intent: JIntent;
 InitialUri: Jnet_Uri;
begin
  InitialUri := StrToJURI(AInitialFolder);
  Intent := TJIntent.Create;
  Intent.setType(StringToJString(AFileType));
  Intent.setAction(TJIntent.JavaClass.ACTION_CREATE_DOCUMENT);
  Intent.addCategory(TJIntent.JavaClass.CATEGORY_OPENABLE);
  Intent.putExtra(TJIntent.JavaClass.EXTRA_TITLE, StringToJString(TPath.GetFileName(AFileName)));
  Intent.putExtra(TJDocumentsContract.JavaClass.EXTRA_INITIAL_URI, JParcelable(InitialUri));
  TAndroidHelper.Activity.startActivityForResult(Intent, CON_IntentSaveFile);
end;