-1

I can open files on Android with the Delphi code shown below. But when I compile it at API 26, it gives the error I added in the picture below. How can I solve this problem?

ExtFile := AnsiLowerCase(StringReplace(TPath.GetExtension(yol), '.', '',[]));
mime := TJMimeTypeMap.JavaClass.getSingleton();
ExtToMime := mime.getMimeTypeFromExtension(StringToJString(ExtFile));
Intent := TJIntent.Create;
Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);
Intent.setDataAndType(StrToJURI('file:' + yol), ExtToMime);
SharedActivity.startActivity(Intent);

Thank you so much for your help. I'm glad that I finally came across this kind of understanding person on this platform. I tried the .pas file you sent. but I see a different error window. I share my codes and the error. thank you so much.

var
  ExtFile,yol,deger,id:string;
  mime: JMimeTypeMap;
  ExtToMime: JString;
  Intent: JIntent;
  javafile:JFile;
begin
  yol:='/sdcard/SkyWiFiDownload/sancak.jpg';
  javafile:=TJFile.JavaClass.init(StringToJString(yol));
  ExtFile := AnsiLowerCase(StringReplace(TPath.GetExtension(yol), '.', '',[]));
  mime := TJMimeTypeMap.JavaClass.getSingleton();
  ExtToMime := mime.getMimeTypeFromExtension(StringToJString(ExtFile));
  Intent := TJIntent.Create;
  id:=JStringToString(TAndroidHelper.Context.getApplicationContext.
  getPackageName) + '.fileprovider';
  deger:=JURIToStr(TJFileProvider.JavaClass.getUriForFile(
  TAndroidHelper.Context,StringToJString(id),javafile));
  Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);
  Intent.setFlags(1);
  Intent.setDataAndType(StrToJURI(deger), ExtToMime);
  SharedActivity.startActivity(Intent);
end;  


(source: resmim.net)

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Codder71
  • 23
  • 1
  • 9
  • 1
    Possible duplicate of [android.os.FileUriExposedException: file:///storage/emulated/0/test.txt exposed beyond app through Intent.getData()](https://stackoverflow.com/questions/38200282/android-os-fileuriexposedexception-file-storage-emulated-0-test-txt-exposed) – Dalija Prasnikar Jun 10 '18 at 14:56
  • I have studied this connection. but FireMonkey unfortunately did not create :( – Codder71 Jun 10 '18 at 17:02
  • FireMonkey didn't create what? Linked question answers your question in its current form. It tells you why you have FileUriExposedConnection error and how you can solve it. If you have tried to apply answers from there, then please edit the question and add what you tried. – Dalija Prasnikar Jun 10 '18 at 18:44
  • I've tried. but the subject code was closed, saying it was not ready. I can not get a tour guide on this site. I can not tell the problems. There is something wrong with you. – Codder71 Jun 10 '18 at 22:15
  • I think Codder71 means that he does not have Delphi code for FileProvider. I've published an import for it here: https://github.com/DelphiWorlds/KastriFree/blob/master/API/DW.Androidapi.JNI.FileProvider.pas. If there's still a problem I'll look into creating an example – Dave Nottage Jun 11 '18 at 02:44
  • Have you added a Provider section? As per: https://medium.com/@ali.muzaffar/what-is-android-os-fileuriexposedexception-and-what-you-can-do-about-it-70b9eb17c6d0 – Dave Nottage Jun 14 '18 at 00:28
  • You should also format your code properly; it looks horrendous – Dave Nottage Jun 14 '18 at 00:50
  • @DaveNottage I've edited the Android manifest and xml file. As for the layout of the codes, it's really hard to add. He says he left 4 spaces but it is not appropriate. Sorry for that. I am adding the AndroidManifest file and the xml file to the subject. You should check a problem. Thanks you. – Codder71 Jun 14 '18 at 11:20
  • @DaveNottage thank you so much. problem solved. Sorry, it originated from a line in the AndroidManifest file. I wonder how we can add functions that are not here. Where can I find detailed information on this topic? I want to make some .pas files. Where should we pay attention – Codder71 Jun 14 '18 at 23:26
  • I suggest watching this video: https://www.youtube.com/watch?v=GcuYc7F0lIU. It has information about how to import Java classes from Android SDKs – Dave Nottage Jun 15 '18 at 00:56
  • @DaveNottage thank you so much. I will watch. – Codder71 Jun 15 '18 at 15:04

1 Answers1

1

I've finally come up with the necessary steps to make this work. Firstly, you will need to modify your AndroidManifest.Template.xml file to add a Provider section like this:

...
    <application android:persistent="%persistent%" 
        android:restoreAnyVersion="%restoreAnyVersion%" 
        android:label="%label%" 
        android:debuggable="%debuggable%" 
        android:largeHeap="%largeHeap%"
        android:icon="%icon%"
        android:theme="%theme%"
        android:hardwareAccelerated="%hardwareAccelerated%">
        <!-- **** ADD THIS SECTION **** -->
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.embarcadero.yourAppName.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths"/>
        </provider>

<%application-meta-data%>
        <%services%>
...

For the value:

  android:authorities="com.embarcadero.yourAppName.fileprovider"

Change: com.embarcadero.yourAppName to whatever your package name is.

You will also need to create a file: provider_paths.xml. Mine looks like this:

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

..and add it to your projects deployment using the Deployment Manager, with a Remote Path value of: res\xml\

Change your Delphi code from:

Intent.setDataAndType(StrToJURI(deger), ExtToMime);

to:

Intent.setDataAndType(TAndroidHelperEx.UriFromFile(javafile), ExtToMime);

TAndroidHelperEx comes from this unit:

https://github.com/DelphiWorlds/KastriFree/blob/master/Core/DW.Android.Helpers.pas

It relies on this unit:

https://github.com/DelphiWorlds/KastriFree/blob/master/API/DW.Androidapi.JNI.FileProvider.pas

Dave Nottage
  • 3,411
  • 1
  • 20
  • 57