Jump to content
Sign in to follow this  
Magno

Trying to share a text file

Recommended Posts

I read almost every topic of the internet about this, but no clue and actually I have 2 issues... My Android app, Delphi CE, needs to save a file into the shared folder and it works fine (using TPath.GetSharedDocumentsPath), but I need to eventually share it and here I have the issues, first my app can't touch that file for sharing, but I can read and write it perfectly. The error is that known " android.os.FileUriExposedException: file:///storage/emulated/0/Documents/myfile.txt exposed beyond app through ClipData.Item.getUri()".

 

Ok, so I thought that my app can read the file I could clone a copy into the "sandbox" (TPath.GetDocumentsPath) and try to share and this is my second issue, because it seems to save the copy there but when I try to check the folder in phone the path .../files is empty. My Android is running the version 11 and SDK 26.

 

The sharing function I am using can be the issue, of course:

procedure ShareFile(FileName: string);
   Intent: JIntent;
   fileuri: JParcelable;
   Uri, Data: Jnet_Uri;
begin
   Intent := TJIntent.Create;
   Intent.setAction(TJIntent.JavaClass.ACTION_SEND);
   Intent.addFlags(TJIntent.JavaClass.FLAG_GRANT_READ_URI_PERMISSION);
   Data := TJnet_Uri.JavaClass.parse(StringToJString(FileName));
   Intent.setType(StringToJString('vnd.android.cursor.dir/*'));
   fileuri := JParcelable(TJnet_Uri.JavaClass.fromFile(TJFile.JavaClass.init(StringToJString(FileName))));
   Intent.putExtra(TJIntent.JavaClass.EXTRA_STREAM, fileuri);
   TAndroidHelper.Activity.startActivity(Intent);
end;

I am not even sure if the vnd is correct. If someone could help I would be very glad.

 

Share this post


Link to post
Posted (edited)
On 2/26/2021 at 7:11 PM, Magno said:

I read almost every topic of the internet about this, but no clue and actually I have 2 issues... My Android app, Delphi CE, needs to save a file into the shared folder and it works fine (using TPath.GetSharedDocumentsPath), but I need to eventually share it and here I have the issues, first my app can't touch that file for sharing, but I can read and write it perfectly. The error is that known " android.os.FileUriExposedException: file:///storage/emulated/0/Documents/myfile.txt exposed beyond app through ClipData.Item.getUri()".

 

Ok, so I thought that my app can read the file I could clone a copy into the "sandbox" (TPath.GetDocumentsPath) and try to share and this is my second issue, because it seems to save the copy there but when I try to check the folder in phone the path .../files is empty. My Android is running the version 11 and SDK 26.

 

The sharing function I am using can be the issue, of course:


procedure ShareFile(FileName: string);
   Intent: JIntent;
   fileuri: JParcelable;
   Uri, Data: Jnet_Uri;
begin
   Intent := TJIntent.Create;
   Intent.setAction(TJIntent.JavaClass.ACTION_SEND);
   Intent.addFlags(TJIntent.JavaClass.FLAG_GRANT_READ_URI_PERMISSION);
   Data := TJnet_Uri.JavaClass.parse(StringToJString(FileName));
   Intent.setType(StringToJString('vnd.android.cursor.dir/*'));
   fileuri := JParcelable(TJnet_Uri.JavaClass.fromFile(TJFile.JavaClass.init(StringToJString(FileName))));
   Intent.putExtra(TJIntent.JavaClass.EXTRA_STREAM, fileuri);
   TAndroidHelper.Activity.startActivity(Intent);
end;

I am not even sure if the vnd is correct. If someone could help I would be very glad.

Edit: I still didn't find any solution, but the code bellow seems to be "more" correct, I replicate from similar in Java but the message now is like "invalid format", as I am trying to share a text file to WhatsApp, eg. Bellow the new code:

 

   if FileExists(FileName) then
   begin
      Intent := TJIntent.Create;
      Intent.setAction(TJIntent.JavaClass.ACTION_SEND);  Intent.setType(StringToJString('*/*'));
      Intent.putExtra(TJIntent.JavaClass.EXTRA_STREAM,  StringToJString('content://'+FileName));
      SharedActivity.startActivity(TJIntent.JavaClass.createChooser(Intent, StrToJCharSequence('Share with...')));
   end;
Quote

 

 

Edited by Magno

Share this post


Link to post

Ok, I finally did something, at least. Now I can share files with WhatsApp, but it will fail to Telegram or other apps that could receive a file:

procedure TForm1.ShareFile(const FileName: String);
Var
{$IFDEF ANDROID}
   Intent: JIntent;
   FileUri: Jnet_Uri;
   ListArqs: JArrayList;
{$ENDIF}
begin
{$IFDEF ANDROID}
   
   ListArqs := TJArrayList.Create;
   FileUri := TJNet_Uri.JavaClass.fromFile(TJFile.JavaClass.init(StringToJString(FileName)));
   ListArqs.Add(0, FileUri); // if intend to send more file change the index (default 0)
   try
      Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_SEND);
      Intent.setType(StringToJString('image/text/plain'));
      Intent.putParcelableArrayListExtra(TJIntent.JavaClass.EXTRA_STREAM, ListArqs);
      Intent.setPackage(StringToJString('com.whatsapp'));
      // Intent.setPackage(StringToJString('org.telegram.messenger'));
      Intent.addFlags(TJIntent.JavaClass.FLAG_GRANT_READ_URI_PERMISSION);
      SharedActivity.startActivity(TJIntent.JavaClass.createChooser(Intent, StrToJCharSequence('')));
   except
      on E: Exception do
         ShowMessage(E.Message);
   end;
{$ENDIF}
end;

 

Share this post


Link to post
7 hours ago, Cristian Peța said:

And what if you omit this line?


Intent.setPackage(StringToJString('com.whatsapp'))

It will open the share sheet so I could choose what app to share with. Now, if I select WhatsApp it works, if I select Telegram I receive the "unsupported content" message. For some reason Telegram wont accept the same parameters used for WhatsApp. Testing with Signal won't even return an error, it at least let me select a contact.

 

I think the something is still missing here. So far I could not find any answer. The reason I am specifying that target intent for WhatsApp is because not all app could receive a sharing, and for email it is a kind different.

 

Share this post


Link to post
Posted (edited)

This "image/text/plain" is strange for me.

You can try this. This will enable share for image and text. If you need only text delete the "image/* "

22 hours ago, Magno said:

Intent.setType(StringToJString('image/* text/plain'));

This setType() will filter the applications that supports that type.

Edited by Cristian Peța

Share this post


Link to post

I just tried Intent.setType(StringToJString('image/* text/plain')), well the result is the same. At very first I tried Intent.setType(StringToJString('text/plain')) and it will be used because the type file is ascii text. Maybe Telegram can have another way to receive a text file, which is different from Whatsapp.

Share this post


Link to post

Well, reading an answer at Stackoverflow (https://stackoverflow.com/questions/56952411/sharing-image-and-link-through-intent-for-whatsapp-telegram-etc) is said:

Quote

The definition of "correctly" is up to the developers of those other apps, not you. What they do with the extras on your Intent is up to them, not you. What they do with those extras will vary based on the app, the app version, and possibly device/OS characteristics. You have no control over any of that. You simply provide the data and let the developers of the other apps do what they want with it.

So, as I thought, now if I really need to send to Telegram I must figure out how to correctly input the information there. At least the sharing file is working.

Share this post


Link to post

Well, I quit trying to doing it myself and now I am using Kastri lib (https://github.com/DelphiWorlds/Kastri) I works like a charm!!

 

The second part is about receiving a text from another app, like a selected text. I already can do it, but just if I close my app and so the event will be triggered. Once I change to other app, select text and share, it won't work. I was guessing if OnActive should solve that but no, it's never triggered again, same onShow, only onPaint but that's crazy. Is there another way once my Android application returns focus to me check the intent? I tried implement the Brain Long solution (http://blong.com/Articles/DelphiXE7NFC/NFC.htm#ReceivingIntents) but I was unable to.. 😞

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×