3

In earlier versions of Delphi (prior to 10.3 Rio), which targeted Android API < 24, it was possible to create file intents as shown in the answer to question opening the image with the external gallery using delphi

However, now that 10.3 targets Android API >= 24, that code, produces the error that is the subject of this question.

I endeavoured to answer the question at Delphi Use android fileprovider to send intent to open and image file with the default android gallery but that question was closed as a duplicate even though the answer the closer linked to, is in Android Java and not Delphi. My answer is below (which follows after a few protracted hours of research)

Freddie Bell
  • 2,186
  • 24
  • 43

1 Answers1

5
uses
  Androidapi.JNI.GraphicsContentViewText,
  Androidapi.JNI.Media,
  Androidapi.Helpers,
  Androidapi.JNI.Net,
  Androidapi.JNI.JavaTypes,
  Androidapi.JNI.App,
  Androidapi.JNI.Os,
  Androidapi.JNI.Support,
  System.IOUtils;

procedure TTabbedForm.Button1Click(Sender: TObject);
var
  Intent: JIntent;
  FileName, DestFileName: string;
  Data: Jnet_Uri;
  CompName: JComponentName;
  lFile: JFile;
const
  IMAGE_FILENAME = 'small_what.jpg';
begin

  FileName := System.IOUtils.TPath.GetPublicPath + PathDelim + IMAGE_FILENAME; // deployed to "assets"

  DestFileName := TPath.GetDownloadsPath + PathDelim + IMAGE_FILENAME;
  TFile.Copy(FileName, DestFileName, true);

  Intent := TJIntent.Create;
  Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);
  if TJBuild_VERSION.JavaClass.SDK_INT >= TJBuild_VERSION_CODES.JavaClass.N then
  begin
    lFile := TJFile.JavaClass.init(StringToJString(FileName));
    Intent.setFlags(TJIntent.JavaClass.FLAG_GRANT_READ_URI_PERMISSION);
    Data := TJFileProvider.JavaClass.getUriForFile(TAndroidHelper.Context,
      StringToJString('com.embarcadero.TestIntents.fileprovider'), lFile);
  end
  else
    Data := TJnet_Uri.JavaClass.parse(StringToJString('file://' + DestFileName));

  Intent.setDataAndType(Data, StringToJString('image/jpg'));

  try
    TAndroidHelper.Activity.startActivity(Intent);
  except
    on E: Exception do
    begin
      Label1.Text := E.Message;
    end;
  end;
Freddie Bell
  • 2,186
  • 24
  • 43
  • 1
    For the authority, it's more generic to use: StringToJString(JStringToString(TAndroidHelper.Context.getApplicationContext.getPackageName) + '.fileprovider') – Dave Nottage Feb 05 '19 at 19:31
  • That's cool Dave. I'm leaving it as it is, so that others can understand where that bit came form (the manifest) How about a vote up? – Freddie Bell Feb 06 '19 at 05:15
  • Thaks for this solution – grant1842 Feb 06 '19 at 12:28
  • @grant1842 You're welcome. Thanks for the challenge. I really wanted to know the answer too. – Freddie Bell Feb 06 '19 at 12:59
  • I am trying this solution. I am geting error onTJFileProvider. Here is my uses TJFileProvider Androidapi.JNI.JavaTypes, Androidapi.JNI.Os, Androidapi.JNI.Embarcadero, Androidapi.JNI.Provider, Androidapi.JNI.Net, Androidapi.JNI.Media, Androidapi.JNIBridge, FMX.ScrollBox; Thanks – grant1842 Feb 06 '19 at 17:25
  • You're missing Androidapi.JNI.Support. I have updated my answer to include all my Androidapi uses. – Freddie Bell Feb 06 '19 at 17:48
  • Thanks for the solution – grant1842 Feb 06 '19 at 20:59
  • @nolaspeaker Thank you for getting me on the path to dealing with the new content-provider requirements. My goal was different but you gave me the key info. One minor thing: the test you use to decide whether to go with the old or new way will fail on Android 6 or lower. The RHS of the expression gives rise to an Invoke error: method does not exists. I Just replaced with a constant of 24. – TomB Oct 20 '20 at 19:52
  • Yes of course, ironically, `TJBuild_VERSION_CODES.JavaClass.N` isn't defined in earlier versions of the SDK. – Freddie Bell Oct 21 '20 at 04:22
  • Hi. How to open a file for editing, so that the WPS / MS office can then save it to the same file? The file is located in a public folder! Any application sees this folder and this file. The file is opened from the regular explorer and can be saved with one click. But when opening it from my program, WPS / MS does not seem to know where it opened it from, and cannot save it in 1 click. You are faced with such a problem? – Станислав 000 Jul 23 '21 at 13:41
  • I just want to open the Excel file from my program, save it in the wps | ms office with one button (without selecting a new location). Then I can continue to work with this file in my program. – Станислав 000 Jul 23 '21 at 13:45