Android Question VIEW IMAGE INTENT (targetSdkVersion 26)

wildfandango

Member
Licensed User
Longtime User
Hi, all

Before the change of targetSdkVersion to 26 the following code showed an image through an attempt using the default image viewer.

B4X:
Dim viewINT As Intent
dim img,dr,fn as String

dr = File.DirDefaultExternal
fn = "sample.jpg"

img = "file://" & File.Combine(dr, fn)
viewINT.Initialize(viewINT.ACTION_VIEW,img)
viewINT.SetType("image/*")
Try
     StartActivity(viewINT)
Catch
     ToastMessageShow("ERROR:" & CRLF & img,True)
End Try


After the change now gives error:
android.os.FileUriExposedException: file:///storage/emulated/0/Android/data/app/files/sample.jpg exposed beyond app through Intent.getData()

After reading a couple of posts I changed file combine to cfpURI, but dont open nothing...

B4X:
Dim viewINT As Intent
dim img,dr,fn as String

dr = File.DirDefaultExternal
fn = "sample.jpg"

img = cfpURI(dr, fn)
viewINT.Initialize(viewINT.ACTION_VIEW,img)
viewINT.SetType("image/*")
Try
     StartActivity(viewINT)
Catch
     ToastMessageShow("ERROR:" & CRLF & img,True)
End Try

Sub cfpURI(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

What's the right way to do it now?

thx in advance!
 

DonManfred

Expert
Licensed User
Longtime User
Check this example: https://www.b4x.com/android/forum/t...ut-fileuriexposedexception.72538/#post-461501

Make sure to copy the file to the shared folder before you try to open it with the intent.

B4X:
Sub Button1_Click
    'copy the file to the shared folder
    File.Copy(File.DirAssets, "b4a.png", Starter.shared, "b4a.png")
    Dim in As Intent
    in.Initialize(in.ACTION_SEND, CreateFileProviderUri(Starter.shared, "b4a.png"))
    in.Flags = 1
    StartActivity(in)
End Sub
 
Upvote 0

wildfandango

Member
Licensed User
Longtime User
Hi, have made the following changes and it works!:

in the project manifest, add the following lines:
B4X:
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" />
)

in the intent sub:

B4X:
Sub intentIMAGE(img As String)
    Dim viewINT As Intent
    Dim rp As RuntimePermissions
    Dim dr,fn As String

    ' Shared folder
    dr = rp.GetSafeDirDefaultExternal("shared")
   
    fn = "image_product.jpg"
    If img.ToLowerCase.Contains(".jpg") Then fn = "image_product.jpg"
    If img.ToLowerCase.Contains(".png") Then fn = "image_product.png"
   
    ' Delete previous image
    If File.Exists(dr, fn) Then File.Delete(dr,fn)
   
    ' Copy to new pad
    If File.Exists(File.DirDefaultExternal, img) Then File.Copy(File.DirDefaultExternal, img, dr, fn)
   
   
    ' the intent
    If File.Exists(dr, fn) Then
       
        viewINT.Initialize(viewINT.ACTION_VIEW,cfpURI(dr, fn))
        viewINT.Flags = 1

        Try
            StartActivity(viewINT)
        Catch
            ToastMessageShow("Error on intent:" & CRLF & img,True)
        End Try

    Else
        ToastMessageShow("Error on path:" & CRLF & img,False)
    End If
End Sub  


' CreateFileProviderUri
Sub cfpURI(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


Thx!!!
 
Upvote 0
Top