Android Question Fileprovider - permission denied

Phayao

Member
Licensed User
Hello,

probably this was discussed before but I could not find a solution :-(
I simply want to use the camera with intent together with the fileprovider class to take a picture and save it in file.dirrootexternal.
B4X:
#Region  Project Attributes
   #ApplicationLabel: CameraIntent plus FileProvider
   #VersionCode: 1
   #VersionName:
   'SupportedOrientations possible values: unspecified, landscape or portrait.
   #SupportedOrientations: unspecified
   #CanInstallToExternalStorage: False
   #BridgeLogger: true
#End Region

#Region  Activity Attributes
   #FullScreen: False
   #IncludeTitle: True
#End Region

Sub Process_Globals
   Private ion As Object
   Private const tempImageFile As String = "tempimage.jpg"
   Private imageFolder As String
   Private lastPicture As Bitmap
   Dim piclocation As String = File.DirRootExternal&"/pic"   <=== THE EXTERNAL FILE
End Sub

Sub Globals
   Private ImageView1 As ImageView
End Sub

Sub Activity_Create(FirstTime As Boolean)
   If FirstTime Then
       imageFolder = Starter.rp.GetSafeDirDefaultExternal("shared") 'shared folder as set in the manifest editor
   End If
   Activity.LoadLayout("1")
   If lastPicture.IsInitialized Then ImageView1.Bitmap = lastPicture
End Sub

Sub Button1_Click
   TakePicture
End Sub

Sub TakePicture
   Dim i As Intent
   i.Initialize("android.media.action.IMAGE_CAPTURE", "")
   File.Delete(imageFolder, tempImageFile)
   Dim p As Phone
   Dim u As Object
   Log("SDK Version: "&p.SdkVersion)
   If p.SdkVersion < 24 Then
       Dim uri As Uri
       uri.Parse("file://" & File.Combine(imageFolder, tempImageFile))
       u = uri
   Else
       u = CreateFileProviderUri(imageFolder, tempImageFile)
   End If
   i.PutExtra("output", u) 'the image will be saved to this path
   Try
       StartActivityForResult(i)
   Catch
       ToastMessageShow("Camera is not available.", True)
       Log(LastException)
   End Try
End Sub

'result arrives here
Sub ion_Event (MethodName As String, Args() As Object) As Object
   If Args(0) = -1 Then
       Try
           Dim in As Intent = Args(1)
           If File.Exists(imageFolder, tempImageFile) Then
               lastPicture = LoadBitmapSample(imageFolder, tempImageFile, ImageView1.Width, ImageView1.Height)
               ImageView1.Bitmap = lastPicture
           Else If in.HasExtra("data") Then 'try to get thumbnail instead
               Dim jo As JavaObject = in
               lastPicture = jo.RunMethodJO("getExtras", Null).RunMethod("get", Array("data"))
           End If
       Catch
           Log(LastException)
       End Try
   End If
   If lastPicture.IsInitialized Then
       ImageView1.Bitmap = lastPicture
       ' copy to picture dir:
       Try
           ' http://www.b4x.com/android/forum/threads/bug-content-chooser-does-not-work-always.25620/
           Dim b As Bitmap
           Dim out As OutputStream
           Dim filename As String = "Testimage from CameraIntent.png"
           out = File.OpenOutput(piclocation, filename,False)
           b.Initialize3(lastPicture)
           b.WriteToStream(out, 100, "PNG")
           out.Close
           Msgbox("Image written to: "&filename,"IMAGE SAVE")
       Catch
           Msgbox( LastException,"ERROR writing "&filename)  <===== THIS ERROR HAPPENS
       End Try
   End If
   Return Null
End Sub

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


Sub StartActivityForResult(i As Intent)
   Dim jo As JavaObject = GetBA
   ion = jo.CreateEvent("anywheresoftware.b4a.IOnActivityResult", "ion", Null)
   jo.RunMethod("startActivityForResult", Array As Object(ion, i))
End Sub

Sub GetBA As Object
   Dim jo As JavaObject
   Dim cls As String = Me
   cls = cls.SubString("class ".Length)
   jo.InitializeStatic(cls)
   Return jo.GetField("processBA")
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)
  
End Sub
The starter.bas:
B4X:
#Region  Service Attributes
   #StartAtBoot: False
   #ExcludeFromLibrary: True
#End Region

Sub Process_Globals
   'These global variables will be declared once when the application starts.
   'These variables can be accessed from all modules.
   Public rp As RuntimePermissions
   Public Provider As FileProvider
End Sub

Sub Service_Create
   Provider.Initialize
End Sub

Sub Service_Start (StartingIntent As Intent)

End Sub

'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
   Return True
End Sub

Sub Service_Destroy

End Sub
the Manifest file:
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="5" 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$")
CreateResourceFromFile(Macro, Themes.DarkTheme)
'End of default text.

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" />
)
Error is: java.io.FileNotFoundException

I'm using SKD version 25 on a samsung Tab A.
Maybe some other guys are having this problem as well ?

Help is very much appreciated,

Chris
 
Last edited:

Computersmith64

Well-Known Member
Licensed User
The only difference between your manifest declaration & mine is I don't have "external-files-path" in the CreateResource:

B4X:
CreateResource(xml, provider_paths,
   <files-path name="name" path="shared" />
)
- Colin.
 

Erel

Administrator
Staff member
Licensed User
I've updated the example based on FileProvider class.
 
Top