Android Question SOLVED FileUriExposedException - exposed beyond app through Intent.getData()

alon

Active Member
Licensed User
Longtime User
Hi,

I was trying to find a solution to the error massage I am getting when I am trying to open a file:
"exposed beyond app through Intent.getData()"

I put every PERMISSION that I found in the forum that might cause the error
But with not much luck.


Can someone please help


Thanks
B4X:
'This code will be applied to the manifest file during compilation.
'You do not need to modify it in most cases.
'See this link for for more information: https://www.b4x.com/forum/showthread.php?p=78136
AddManifestText(
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="28"/>
<supports-screens android:largeScreens="true" 
    android:normalScreens="true" 
    android:smallScreens="true" 
    android:anyDensity="true"/>
    
    
  <uses-permission android:name="android.permission.INTERNET"/>
  <uses-permission android:name="android.permission.CALL_PHONE"/>    
  <uses-permission android:name="android.permission.CAMERA"/>
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  <uses-permission android:name="android.permission.READ_MEDIA_STORAGE"/>
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
 
      

    )


AddActivityText(AttachedFiles,
<intent-filter>
  <action android:name="android.intent.action.PICK" />
  <category android:name="android.intent.category.DEFAULT" />
  <data android:mimeType="image/*" />
</intent-filter>
<intent-filter>
  <action android:name="android.intent.action.GET_CONTENT" />
  <category android:name="android.intent.category.DEFAULT" />
  <category android:name="android.intent.category.OPENABLE" />
  <data android:mimeType="image/*" />
</intent-filter>
)



CreateResource(layout, checkbox,
  <CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/ChkSaveLogin"

  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:button="@null"
  android:drawableRight="?android:attr/listChoiceIndicatorMultiple"

  android:tag="ChkSaveLogin" />
)

CreateResourceFromFile(Macro, Core.NetworkClearText)

SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
'End of default text.
AddManifestText(<uses-feature android:name="android.hardware.location.gps"/>)

'====================================
'    23-04-2019 = Push Notifications
CreateResourceFromFile(Macro, FirebaseAnalytics.GooglePlayBase)
CreateResourceFromFile(Macro, FirebaseAnalytics.Firebase)
CreateResourceFromFile(Macro, FirebaseNotifications.FirebaseNotifications)
'====================================
AddApplicationText(
  <provider
  android:name="android.support.v4.content.FileProvider"
  android:authorities="$PACKAGE$.provider"
  android:exported="false"
  android:grantUriPermissions="true">
  <meta-data
  android:name="android.support.FILE_PROVIDER_PATHS"
  android:resource="@xml/provider_paths"/>
  </provider>
)
CreateResource(xml, provider_paths,
   <files-path name="name" path="shared" />
)

B4X:
'
Sub FTP_DownloadCompleted (ServerPath As String, Success As Boolean)
    Starter.FTP.Close
    Log(ServerPath & ", Success=" & Success)
    If Success = False Then
        Log(LastException.Message)
    Else
        Try
            
            Dim sFileType As String 
            sFileType = ServerPath.SubString(ServerPath.Length-4)
            If sFileType.SubString2(0,1) = "." Then
                sFileType = sFileType.SubString(1)
            End If
            ServerPath = "tmpFile." & sFileType
            Dim i As Intent
            i.Initialize(i.ACTION_VIEW, "file://" & File.Combine(Starter.TargetFolder & "/",  ServerPath))
            i.SetComponent("android/com.android.internal.app.ResolverActivity")
            
            Dim types As Map
            types.Initialize
            
            types.Put("apk","application/vnd.android.package-archive")
            types.Put("au","audio/basic")
            types.Put("avi","video/msvideo, video/avi, video/x-msvideo")
            types.Put("bmp","image/bmp")
            types.Put("bz2","Application/x-bzip2")
            types.Put("css","text/css")
            types.Put("dtd","Application/xml-dtd")
            '            types.Put("doc","Application/msword")
            types.Put("doc","application/msword")
            '            types.Put("docx","Application/vnd.openxmlformats-officedocument.wordprocessingml.document")
            types.Put("docx","application/msword")
            types.Put("dotx","Application/vnd.openxmlformats-officedocument.wordprocessingml.template")
            types.Put("es","Application/ecmascript")
            types.Put("exe","Application/octet-stream")
            types.Put("gif","image/gif")
            types.Put("gz","Application/x-gzip")
            types.Put("hqx","Application/mac-binhex40")
            types.Put("html","text/html")
            types.Put("jar","Application/java-archive")
            types.Put("jpg","image/jpeg")
            types.Put("js","Application/x-javascript")
            types.Put("midi","audio/x-midi")
            types.Put("mp3","audio/mpeg")
            types.Put("mpeg","video/mpeg")
            types.Put("ogg","audio/vorbis, Application/ogg")
            types.Put("pdf","application/pdf")
            types.Put("pl","Application/x-perl")
            types.Put("png","image/png")
            types.Put("potx","Application/vnd.openxmlformats-officedocument.presentationml.template")
            types.Put("ppsx","Application/vnd.openxmlformats-officedocument.presentationml.slideshow")
            types.Put("ppt","Application/vnd.ms-powerpointtd>")
            types.Put("pptx","Application/vnd.openxmlformats-officedocument.presentationml.presentation")
            types.Put("psv","Application/postscript")
            types.Put("qt","video/quicktime")
            types.Put("ra","audio/x-pn-realaudio, audio/vnd.rn-realaudio")
            types.Put("ram","audio/x-pn-realaudio, audio/vnd.rn-realaudio")
            types.Put("rdf","Application/rdf, Application/rdf+xml")
            types.Put("rtf","Application/rtf")
            types.Put("sgml","text/sgml")
            types.Put("sit","Application/x-stuffit")
            types.Put("sldx","Application/vnd.openxmlformats-officedocument.presentationml.slide")
            types.Put("svg","image/svg+xml")
            types.Put("swf","Application/x-shockwave-flash")
            types.Put("tar.gz","Application/x-tar")
            types.Put("tgz","Application/x-tar")
            types.Put("tiff","image/tiff")
            types.Put("tsv","text/TAB-separated-values")
            types.Put("txt","text/plain")
            types.Put("wav","audio/wav, audio/x-wav")
            types.Put("xlam","Application/vnd.ms-excel.addin.macroEnabled.12")
            types.Put("xls","application/vnd.ms-excel")
            types.Put("xlsb","Application/vnd.ms-excel.sheet.binary.macroEnabled.12")
            types.Put("xlsx","application/vnd.ms-excel")
            '            types.Put("xltx","Application/vnd.openxmlformats-officedocument.spreadsheetml.template")
            types.Put("xltx","vnd.ms-excel")
            types.Put("xml","Application/xml")
            types.Put("zip","Application/zip, Application/x-compressed-zip")
            
            If types.ContainsKey(sFileType) Then
                i.SetType(types.Get(sFileType))
            Else
                i.SetType("application/vnd.android.package-archive")
            End If
'            
    
            StartActivity(i)
        Catch
            Log(LastException)
        End Try
    End If
End Sub
 

MarcoRome

Expert
Licensed User
Longtime User
Yes missing....

B4X:
            .....
            Dim out As OutputStream = File.OpenOutput(File.DirRootExternal, "document." & estensione, False)
            File.Copy2(Job.GetInputStream, out)
            out.Close '<------ very important
            Dim apro As Int
            apro = Msgbox2("Do you want Open Document in attachment ?", "Message", "Yes","","No", Null)
            If apro = DialogResponse.POSITIVE Then
                Dim i As Intent
                i.Initialize(i.ACTION_VIEW, "file://" & File.Combine(File.DirRootExternal & "/", "document."& estensione))
                .....
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
it will not work with your code @MarcoRome as you are using a file uri. File uris are no longer allowed and you need to use FileProvider.
 
Upvote 0

alon

Active Member
Licensed User
Longtime User
Yes missing....

B4X:
            .....
            Dim out As OutputStream = File.OpenOutput(File.DirRootExternal, "document." & estensione, False)
            File.Copy2(Job.GetInputStream, out)
            out.Close '<------ very important
            Dim apro As Int
            apro = Msgbox2("Do you want Open Document in attachment ?", "Message", "Yes","","No", Null)
            If apro = DialogResponse.POSITIVE Then
                Dim i As Intent
                i.Initialize(i.ACTION_VIEW, "file://" & File.Combine(File.DirRootExternal & "/", "document."& estensione))
                .....


The file is already downloaded i dont need to Copy the file from the job I am using ftp download.
and the intent Initialize is also the same.
 
Upvote 0

MarcoRome

Expert
Licensed User
Longtime User
it will not work with your code @MarcoRome as you are using a file uri. File uris are no longer allowed and you need to use FileProvider.

Right what you say dear Don. But it was to make it clear that:
1. The file should be saved on your device and then opened with the intent
 
Last edited:
Upvote 0

MarcoRome

Expert
Licensed User
Longtime User
Insert this code in your manifest:

B4X:
'Aggiunto per Gestione File esterni ( act_menu )
AddManifestText(<uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="18" />
)

AddApplicationText(
  <provider
  android:name="android.support.v4.content.FileProvider"
  android:authorities="$PACKAGE$.provider"
  android:exported="false"
  android:grantUriPermissions="true">
  <meta-data
  android:name="android.support.FILE_PROVIDER_PATHS"
  android:resource="@xml/provider_paths"/>
  </provider>
)
CreateResource(xml, provider_paths,
   <external-files-path name="name" path="shared" />
)

This in Starter:

B4X:
'Per gestione file esterni
Public rp As RuntimePermissions
Public shared As String

Sub Service_Create
    'This is the program entry point.
    'This is a good place to load resources that are not specific to a single activity.
    shared = rp.GetSafeDirDefaultExternal("shared")
End Sub

This in your activity

B4X:
Sub CreateFileProviderUri (Dir As String, FileName As String) As Object
    Dim FileProvider As JavaObject
    Dim context As JavaObject
    context.InitializeContext
    FileProvider.InitializeStatic("android.support.v4.content.FileProvider")
    Dim f As JavaObject
    f.InitializeNewInstance("java.io.File", Array(Dir, FileName))
    Return FileProvider.RunMethod("getUriForFile", Array(context, Application.PackageName & ".provider", f))
End Sub

......
Case "allegato"
               
                ......
                Dim out As OutputStream = File.OpenOutput(Starter.shared, "Informativa_privacy." & estensione, False)
                File.Copy2(Job.GetInputStream, out)
                out.Close '<------ very important

                Dim i As Intent
                'i.Initialize(i.ACTION_VIEW, "file://" & File.Combine(File.DirRootExternal & "/", "document."& estensione))
                i.Initialize(i.ACTION_VIEW, CreateFileProviderUri(Starter.shared, "Informativa_privacy."& estensione))
                i.Flags = 1
                i.SetComponent("android/com.android.internal.app.ResolverActivity")
                Select estensione
                    Case "pdf"
                        i.SetType("application/pdf")
                    Case "docx"
                        i.SetType("application/vnd.openxmlformats-officedocument.wordprocessingml.document")
                        'i.SetType("application/msword")
                    Case "txt"
                        i.SetType("text/plain")
                    Case "jpg"
                        i.SetType("image/jpg")
                    Case "jpeg"
                        i.SetType("image/jpeg")
                End Select
                 
                StartActivity(i)
               
               
End Select
 
Last edited:
Upvote 0

MarcoRome

Expert
Licensed User
Longtime User
The file is already downloaded i dont need to Copy the file from the job I am using ftp download.
and the intent Initialize is also the same.

In your case ( FTP )

Insert this code in your manifest:

B4X:
'Aggiunto per Gestione File esterni ( act_menu )
AddManifestText(<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
)

AddApplicationText(
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="$PACKAGE$.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
)
CreateResource(xml, provider_paths,
<external-files-path name="name" path="shared" />
)



This in Starter:
B4X:
'Per gestione file esterni
Public rp As RuntimePermissions
Public shared As String

Sub Service_Create
'This is the program entry point.
'This is a good place to load resources that are not specific to a single activity.
shared = rp.GetSafeDirDefaultExternal("shared")
End Sub

This in your activity

B4X:
...
FTP.DownloadFile("/file.pdf", False, Starter.shared, "test.pdf") 
.....

Sub CreateFileProviderUri (Dir As String, FileName As String) As Object
    Dim FileProvider As JavaObject
    Dim context As JavaObject
    context.InitializeContext
    FileProvider.InitializeStatic("android.support.v4.content.FileProvider")
    Dim f As JavaObject
    f.InitializeNewInstance("java.io.File", Array(Dir, FileName))
    Return FileProvider.RunMethod("getUriForFile", Array(context, Application.PackageName & ".provider", f))
End Sub

Sub FTP_DownloadCompleted (ServerPath As String, Success As Boolean)
    Starter.FTP.Close
    Log(ServerPath & ", Success=" & Success)
    If Success = False Then
        Log(LastException.Message)
    Else
        Try
            
            Dim sFileType As String
            sFileType = ServerPath.SubString(ServerPath.Length-4)
            If sFileType.SubString2(0,1) = "." Then
                sFileType = sFileType.SubString(1)
            End If
            ServerPath = "tmpFile." & sFileType
            Dim i As Intent
            i.Initialize(i.ACTION_VIEW, CreateFileProviderUri(Starter.shared, "Informativa_privacy."& estensione))
            'i.Initialize(i.ACTION_VIEW, "file://" & File.Combine(Starter.TargetFolder & "/",  ServerPath))
            i.SetComponent("android/com.android.internal.app.ResolverActivity")
            ....
 
Upvote 0

alon

Active Member
Licensed User
Longtime User
Thanks you both - with your help I understand the problem, and now it works.

Thanks again
 
Upvote 0
Top