Android Question File.DirDefaultExternal

Federico Agosta

Member
Licensed User
Hi all,
I'm improving my app for to save and open PDF file
With android:targetSdkVersion="14" was fine, but after increase targetSdkVersion to 26 not work

In the past I saved and read directly from DirRootExternal but now I cannot.

Now I'm using DirDefaultExternal but when I try to read the PDF file appear an error:

android.os.FileUriExposedException: file:///storage/emulated/0/Android/data/federico.completo.it/files/PP_2018-10-09-2307.pdf exposed beyond app through Intent.getData()

For to save I use:

B4X:
PDFWriter1.ConverseDocument
    Dim now As String
    DateTime.DateFormat = "yyyy-MM-dd-HHmm"
      now = DateTime.now
    
       MyTime = DateTime.Date(now) 
    PDFWriter1.outputToFile(File.DirDefaultExternal, "PP_" & MyTime & ".pdf",PDFContent,"ISO-8859-1")
    ToastMessageShow("Saved. ",False)
For to read I use:

B4X:
Sub show_click
    Dim i As Intent 
    i.Initialize(i.ACTION_VIEW, "file://" & File.Combine(File.DirDefaultExternal,"PP_" & MyTime & ".pdf" ))
    i.SetType("application/pdf")
    i.WrapAsIntentChooser("Scegliere PDF Viewer")
    StartActivity(i)
    Return
End Sub
I cannot go ahead, someone can give me a new method ?
Please help
Thanks a lot in advance
 

npsonic

Active Member
Licensed User
Test this

B4X:
Sub show_click
    Dim i As Intent
    i.Initialize(i.ACTION_VIEW, CreateFileProviderUri(File.DirDefaultExternal, "PP_" & MyTime & ".pdf"))
    i.SetComponent("android/com.android.internal.app.ResolverActivity")
    i.SetType("application/pdf")
    i.Flags = 1
    StartActivity(i)
End Sub
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
 

Federico Agosta

Member
Licensed User
1. You should never use File.DirDefaultExternal:
Runtime Permissions (Android 6.0+ Permissions)

2. Use this class: [class] FileProvider - share files
Thank for your reply, but if I use in Manifest the code showed the app immediately crash.
This is my manifest:
B4X:
AddManifestText(
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="26"/>
<supports-screens android:largeScreens="true"
    android:normalScreens="true"
    android:smallScreens="true"
    android:anyDensity="true"/>)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
SetApplicationAttribute(android:theme, "@android:style/Theme.Holo.Light")

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,
   <files-path name="name" path="shared" />
)
What am I doing wrong ?
 

Federico Agosta

Member
Licensed User
Check the unfiltered log.
There must be an error if the app crashes.
Sorry, but I don't know very well, what you are asking me.
I disable the filter on the log windows, but there are a lot of row of sentence and never stop.
What should I looking for ?

Thanks for understanding my difficulty.
 

npsonic

Active Member
Licensed User
Sorry, but I don't know very well, what you are asking me.
I disable the filter on the log windows, but there are a lot of row of sentence and never stop.
What should I looking for ?

Thanks for understanding my difficulty.
If you are not sure how to find exception that was cause of crash you can always do this.

Add this to your Starter service
B4X:
'Return true to allow the OS default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
    File.WriteString(File.DirInternal,"exception",Error & CRLF & StackTrace)
    Return True
End Sub
Add this to your Main Activity to method Activity_Create
B4X:
If File.Exists(File.DirInternal,"exception") Then
    Msgbox(File.ReadString(File.DirInternal,"exception"),"Exception")
    File.Delete(File.DirInternal,"exception")
End If
, so it will look something like this
B4X:
Sub Activity_Create(FirstTime As Boolean)
    If File.Exists(File.DirInternal,"exception") Then
        Msgbox(File.ReadString(File.DirInternal,"exception"),"Exception")
        File.Delete(File.DirInternal,"exception")
    End If
        
    
    'Your other code   
        

End Sub
Now every time your app has crashed you will see crash message when starting app again.
 

Federico Agosta

Member
Licensed User
Solved:

Thanks a lot to everybody
My mistake about crash. (I've not used Fileprovider module)
Thanks to the example of Erel I improved my App.
 
Top