Search code examples
androiddelphiandroid-fileprovider

How can I find the cause of the error: "failed to find configured root that contains"


I have an error and I can't find the cause of it. Error while generating Uri.

I looked through several topics on this topic, which were discussed here. However, the error could not be corrected. I think there is a typo somewhere. How can I find where I am wrong?

var
files: Tfile;
lIntent: JIntent;
lJRecipient: TJavaObjectArray<JString>;
lURI: Jnet_Uri;
LAuthority: JString;
lJFile: JFile;
lFileName: string;
lFilePath: string;
lFilePathFileName: string;
Surf : TBitmapSurface;
begin
 lFileName := Concat('Foto','Code' ,'.jpg') ;
 lFilePath := System.IOUtils.TPath.GetPublicPath;
 lFilePathFileName := System.IOUtils.Tpath.Combine(lFilePath, lFileName) ;
 Surf:=TBitMapSurface.Create;
 SaveParams.Quality:=100;
 try
  Surf.Assign(imResult.Bitmap);
  TbitMapCodecManager.SaveToFile(lFilePathFileName, Surf, @SaveParams);
finally
  Surf.Free;
end;

  lIntent:= TJIntent.Create;
  lIntent.setType(StringToJString('message/rfc822'));
  lIntent.setAction(TJIntent.JavaClass.ACTION_SEND);
  lIntent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK);
  lIntent.putExtra(TJIntent.JavaClass.EXTRA_EMAIL, lJRecipient);
  lIntent.putExtra(TJIntent.JavaClass.EXTRA_SUBJECT, StringToJString('Text'));
  lIntent.putExtra(TJIntent.JavaClass.EXTRA_TEXT, StringToJString('.....'));
  LAuthority := StringToJString(JStringToString(
  TAndroidHelper.Context.getApplicationContext.getPackageName)+'.fileprovider');
  lJFile:= TJFile.JavaClass.init(StringToJString(lFileName));
  lUri := TJFileProvider.JavaClass.getUriForFile(
    TAndroidHelper.Context,  LAuthority, lJFile);

I have included in the manifest file

<provider
                android:name="android.support.v4.content.FileProvider"
                android:authorities="com.embarcadero.ScanDecoder.fileprovider"
                android:grantUriPermissions="true"
                android:exported="false">
                <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/filepaths" />
            </provider>

Created a file \res\xml\filepaths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="MyFoto" path="."/>
</paths>  

I tried changing the path in the file to the following. I am still getting this error.

path="."
path="./"
path="files/"
path=".files/"

Where have I gone wrong?


Solution

  • @Dave Nottage suggested the correct way to work with FileProvider. The xml manifest and provider paths are generated automatically when you enable the "Secure File Sharing" option in the list of rights in the project options. Now it works. I provide a working solution.

    procedure TestSendEmail();
    {$IF DEFINED(ANDROID)}
     var
      lIntent: JIntent;
      lJRecipient: TJavaObjectArray<JString>;
      lURI: Jnet_Uri;
      lFileName: string;
      lFilePath: string;
      lFilePathFileName: string;
    
      Delim :Char;
    //  Surf : TBitmapSurface;
    {$ENDIF}
    
    
    begin
     lFileName := Concat('MyFile' ,'.jpg') ;
     lFilePath := System.IOUtils.TPath.GetPublicPath ;
     lFilePathFileName := System.IOUtils.Tpath.Combine(lFilePath, lFileName) ;
     Surf:=TBitMapSurface.Create;
     SaveParams.Quality:=100;
     try
       Surf.Assign(imResult.Bitmap);
     // Save file
       TbitMapCodecManager.SaveToFile(lFilePathFileName, Surf, @SaveParams);
     finally
       Surf.Free;
     end;
    {$IF DEFINED(ANDROID)}
      lJRecipient:= TJavaObjectArray<JString>.Create(1);
      lJRecipient.Items[0]:= StringToJString('xxxxxxx@yyyy.com');
    
      lIntent:= TJIntent.Create;
    
      lIntent.setType(StringToJString('message/rfc822'));
      lIntent.setAction(TJIntent.JavaClass.ACTION_SEND);
      lIntent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK);
      lIntent.putExtra(TJIntent.JavaClass.EXTRA_EMAIL, lJRecipient);
      lIntent.putExtra(TJIntent.JavaClass.EXTRA_SUBJECT, StringToJString('Subj'));
      lIntent.putExtra(TJIntent.JavaClass.EXTRA_TEXT, StringToJString('Text'));
    
      lUri:= TAndroidHelper.JFileToJURI(
          TJFile.JavaClass.init(StringToJString(lFilePathFileName)));
    
      lIntent.putExtra(TJIntent.JavaClass.EXTRA_STREAM,TJParcelable.Wrap(lUri)) ;
    
      try
        TAndroidHelper.Activity.startActivity(lIntent);
      except
        on E: Exception do
        begin
          ShowMessage( E.Message);
        end;
      end;
    {$ENDIF}
    end;