Android Question Open failed: ENOENT (No such file or directory)

Jordi Casas Armengol

Member
Licensed User
Longtime User
Hi!
Changing Manisfest <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="14"/> to <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="29"/> causes error once I install app on my device.
An Error has ocurred in sub:main_writeini (Java line.......) FileNotFoundExeption Open failed: /storage/emulated/0/Android/data/com.project.project/files/file.ini ENOENT (No such file or directory)
Any idea?
Thx!
 

DonManfred

Expert
Licensed User
Longtime User
1.
2.
 
Upvote 0

Sagenut

Expert
Licensed User
Longtime User
To access files in Your app directory without need to request permission to the user you can do this:
- Select RuntimePermission library from Libraries tree
- in Process_Globals add
B4X:
Private rp As RuntimePermissions
- to access your file use
B4X:
(rp.GetSafeDirDefaultExternal(""), "file.ini")
as DIR and FILENAME.
Example if your file is a List
B4X:
File.ReadList(rp.GetSafeDirDefaultExternal(""), "file.ini")
Anyway it's MANDATORY šŸ˜ to learn how to request permission, reading and understanding the Tutorials posted by @DonManfred.
Watch even the Video Tutorial contained in that posts, it's very clear.
 
Upvote 0

Jordi Casas Armengol

Member
Licensed User
Longtime User
Ok thanks both! After updating lots of files as B4A, SDK, tools... It works.
This app is so old and I found a scale module years ago but udating sdk It not works now. I get this error in app:
An error has ocurred in sub:scale_scaleview (java line: 186)
java.lang.ClassCastException:
android.widget.RelativeLayout$LayoutParams cannot be cast to anywheresoftware.b4a.BALayout$LayoutParams
Continue?

B4X:
'Scale Code module
' Version 1.5        2014.09.02
'
'
' Version 1.4        2013.11.29
' amended error with height and width <0
'
' Version 1.3        2013.11.16
' added ScaleAllX and ScaleViewX
' this scaling uses only the X scale factor
'
' Version 1.2     2013.09.18
' added HorizontalScrollView
'
' Version 1.1
' added other reference layouts
' the original AutoScale the reference screen is 320/480/160
' in the new version you can set any other screen like 800/1280/160
'
' Version 1.0 orginal

Sub Process_Globals
    Private cScaleX, cScaleY, cScaleDS As Double
    Private cRefWidth As Int
    Private cRefHeight As Int
    Private cRefScale As Double
End Sub

'Initializes the Scale factors
Public Sub Initialize
    Dim DeviceScale As Double
    DeviceScale = 100dip / 100
    
    cScaleX = (100%x/DeviceScale)/(cRefWidth/cRefScale)
    cScaleY = (100%y/DeviceScale)/(cRefHeight/cRefScale)
    cScaleDS = Sqrt(Power(cScaleX, 2) + Power(cScaleY, 2))
    cScaleDS = 1 + ((100%x + 100%y) / DeviceScale / ((cRefWidth  + cRefHeight - 50 * cRefScale) / cRefScale) - 1)
    
End Sub



'Scales the view v with the Rate set with SetRate
'or with the default Rate value of 0.3
'v must not be an Activity
Public Sub ScaleView(v As View)

    If IsActivity(v) Then
        Return
    End If
    
    v.Left = v.Left * cScaleX
    v.Top = v.Top * cScaleY
    If IsPanel(v) Then
        Dim pnl As Panel
        pnl = v
        If pnl.Background Is BitmapDrawable Then
            ' maintain the width/height ratio
            ' uses the min value of the scales
            If v.Width > 0 Then
                v.Width = v.Width * cScaleX
            End If
            If v.Height > 0 Then
                v.Height = v.Height * cScaleY
            End If
        Else
            If v.Width > 0 Then
                v.Width = v.Width * cScaleX
            End If
            If v.Height > 0 Then
                v.Height = v.Height * cScaleY
            End If
        End If
        ScaleAll(pnl, False)
    Else If v Is ImageView Then
        ' maintain the width/height ratio
        ' uses the min value of the scales
        If v.Width > 0 Then
                v.Width = v.Width * cScaleX
            End If
            If v.Height > 0 Then
                v.Height = v.Height * cScaleY
            End If
        Else
            If v.Width > 0 Then
                v.Width = v.Width * cScaleX
            End If
            If v.Height > 0 Then
                v.Height = v.Height * cScaleY
            End If
    End If

    If v Is Label Then 'this will catch ALL views with text (EditText, Button, ...)
        Dim lbl As Label = v
        If cScaleX<cScaleY Then
            lbl.TextSize = lbl.TextSize * cScaleX
        Else
            lbl.TextSize = lbl.TextSize * cScaleY
        End If
    End If

    If GetType(v) = "anywheresoftware.b4a.objects.ScrollViewWrapper$MyScrollView" Then
        ' test if the view is a ScrollView
        ' if yes calls the ScaleAll routine with ScrollView.Panel
        Dim scv As ScrollView
        scv = v
        ScaleAll(scv.Panel, False)
        scv.Panel.Height = scv.Panel.Height * cScaleY
    Else If GetType(v) = "anywheresoftware.b4a.objects.HorizontalScrollViewWrapper$MyHScrollView" Then
        ' test if the view is a HorizontalScrollView
        ' if yes calls the ScaleAll routine with HorizontalScrollView.Panel
        Dim hcv As HorizontalScrollView
        hcv = v
        ScaleAll(hcv.Panel, False)
        hcv.Panel.Width = hcv.Panel.Width * cScaleX
    Else If GetType(v) = "flm.b4a.scrollview2d.ScrollView2DWrapper$MyScrollView" Then
        ' test if the view is a ScrollView2D
        ' if yes calls the ScaleAll routine with ScrollView2D.Panel
'        Dim scv2d As ScrollView2D
'        scv2d = v
'        ScaleAll(scv2d.Panel, False)
'        scv2d.Panel.Width = scv2d.Panel.Width * cScaleX
'        scv2d.Panel.Height = scv2d.Panel.Height * cScaleY
    Else If GetType(v) = "anywheresoftware.b4a.objects.ListViewWrapper$SimpleListView" Then
        ' test if the view is a ListView
        ' if yes scales the internal views
        Dim ltv As ListView
        ltv = v
        ScaleView(ltv.SingleLineLayout.Label)
        ltv.SingleLineLayout.ItemHeight = ltv.SingleLineLayout.ItemHeight * cScaleY
        
        ScaleView(ltv.TwoLinesLayout.Label)
        ScaleView(ltv.TwoLinesLayout.SecondLabel)
        ltv.TwoLinesLayout.ItemHeight = ltv.TwoLinesLayout.ItemHeight * cScaleY
        
        ScaleView(ltv.TwoLinesAndBitmap.Label)
        ScaleView(ltv.TwoLinesAndBitmap.SecondLabel)
        ScaleView(ltv.TwoLinesAndBitmap.ImageView)
        ltv.TwoLinesAndBitmap.ItemHeight = ltv.TwoLinesAndBitmap.ItemHeight * cScaleY
        ' center the image vertically
        ltv.TwoLinesAndBitmap.ImageView.Top = (ltv.TwoLinesAndBitmap.ItemHeight - ltv.TwoLinesAndBitmap.ImageView.Height) / 2
    Else If GetType(v) = "anywheresoftware.b4a.objects.SpinnerWrapper$B4ASpinner" Then
        ' test if the view is a Spinner
        ' if yes scales the internal text size
        Dim spn As Spinner
        spn = v
        If cScaleX<cScaleY Then
            spn.TextSize = spn.TextSize * cScaleX
        Else
            spn.TextSize = spn.TextSize * cScaleY
        End If
    End If
End Sub

'Scales all views in the given Activity or Panel with all its child views
'with the Rate set with SetRate
'or with the default Rate value of 0.3
'FirstTime must be True
'Example:
'<code>Sub ScaleAll(Activity, True)</code>
'Public Sub ScaleAll(act As Activity, FirstTime As Boolean)
Public Sub ScaleAll(pnl As Panel, FirstTime As Boolean)   
    Dim I As Int
    
    ' test if the activity object is a Panel
    If IsPanel(pnl) And FirstTime = True Then
        ' if yes scale it
        ScaleView(pnl)
    Else
        For I = 0 To pnl.NumberOfViews - 1
            Dim v As View
            v = pnl.GetView(I)
            ScaleView(v)
        Next
    End If
End Sub

'Scales all views in the given Activity or Panel with all its child views
'with the Rate set with SetRate
'or with the default Rate value of 0.3
'only the X scale is used, the vertical scale is the same as the horizontal scale
'FirstTime must be True
'Example:
'<code>Sub ScaleAll(Activity, True)</code>
'Public Sub ScaleAll(act As Activity, FirstTime As Boolean)
Public Sub ScaleAllX(pnl As Panel, FirstTime As Boolean)   
    Dim I As Int
    
    ' test if the activity object is a Panel
    If IsPanel(pnl) And FirstTime = True Then
        ' if yes scale it
        ScaleViewX(pnl)
    Else
        For I = 0 To pnl.NumberOfViews - 1
            Dim v As View
            v = pnl.GetView(I)
            ScaleViewX(v)
        Next
    End If
End Sub

'Scales the view v with the Rate set with SetRate
'or with the default Rate value of 0.3
'only the X scale is used, the vertical scale is the same as the horizontal scale
'v must not be an Activity
Public Sub ScaleViewX(v As View)
    If IsActivity(v) Then
        Return
    End If
    
    v.Left = v.Left * cScaleX
    v.Top = v.Top * cScaleX

    If IsPanel(v) Then
        Dim pnl As Panel
        pnl = v
        If v.Width > 0 Then
            v.Width = v.Width * cScaleX
        End If
        If v.Height > 0 Then
            v.Height = v.Height * cScaleX
        End If
        ScaleAllX(pnl, False)
    Else
        If v.Width > 0 Then
            v.Width = v.Width * cScaleX
        End If
        If v.Height > 0 Then
            v.Height = v.Height * cScaleX
        End If
    End If
    
    If v Is Label Then 'this will catch ALL views with text (EditText, Button, ...)
        Dim lbl As Label = v
        If cScaleX<cScaleY Then
            lbl.TextSize = lbl.TextSize * cScaleX
        Else
            lbl.TextSize = lbl.TextSize * cScaleY
        End If
    End If

    If GetType(v) = "anywheresoftware.b4a.objects.ScrollViewWrapper$MyScrollView" Then
        ' test if the view is a ScrollView
        ' if yes calls the ScaleAll routine with ScrollView.Panel
        Dim scv As ScrollView
        scv = v
        ScaleAllX(scv.Panel, False)
        scv.Panel.Height = scv.Panel.Height * cScaleX
    Else If GetType(v) = "anywheresoftware.b4a.objects.HorizontalScrollViewWrapper$MyHScrollView" Then
        ' test if the view is a HorizontalScrollView
        ' if yes calls the ScaleAll routine with HorizontalScrollView.Panel
        Dim hcv As HorizontalScrollView
        hcv = v
        ScaleAllX(hcv.Panel, False)
        hcv.Panel.Width = hcv.Panel.Width * cScaleX
    Else If GetType(v) = "flm.b4a.scrollview2d.ScrollView2DWrapper$MyScrollView" Then
        ' test if the view is a ScrollView2D
        ' if yes calls the ScaleAll routine with ScrollView2D.Panel
'        Dim scv2d As ScrollView2D
'        scv2d = v
'        ScaleAllX(scv2d.Panel, False)
'        scv2d.Panel.Width = scv2d.Panel.Width * cScaleX
'        scv2d.Panel.Height = scv2d.Panel.Height * cScaleX
    Else If GetType(v) = "anywheresoftware.b4a.objects.ListViewWrapper$SimpleListView" Then
        ' test if the view is a ListView
        ' if yes scales the internal views
        Dim ltv As ListView
        ltv = v
        ScaleViewX(ltv.SingleLineLayout.Label)
        ltv.SingleLineLayout.ItemHeight = ltv.SingleLineLayout.ItemHeight * cScaleX
        
        ScaleViewX(ltv.TwoLinesLayout.Label)
        ScaleViewX(ltv.TwoLinesLayout.SecondLabel)
        ltv.TwoLinesLayout.ItemHeight = ltv.TwoLinesLayout.ItemHeight * cScaleX
        
        ScaleViewX(ltv.TwoLinesAndBitmap.Label)
        ScaleViewX(ltv.TwoLinesAndBitmap.SecondLabel)
        ScaleViewX(ltv.TwoLinesAndBitmap.ImageView)
        ltv.TwoLinesAndBitmap.ItemHeight = ltv.TwoLinesAndBitmap.ItemHeight * cScaleX
        ' center the image vertically
        ltv.TwoLinesAndBitmap.ImageView.Top = (ltv.TwoLinesAndBitmap.ItemHeight - ltv.TwoLinesAndBitmap.ImageView.Height) / 2
    Else If GetType(v) = "anywheresoftware.b4a.objects.SpinnerWrapper$B4ASpinner" Then
        ' test if the view is a Spinner
        ' if yes scales the internal text size
        Dim spn As Spinner
        spn = v
        If cScaleX<cScaleY Then
            spn.TextSize = spn.TextSize * cScaleX
        Else
            spn.TextSize = spn.TextSize * cScaleY
        End If
    End If
End Sub

'Returns True if the view v is a Panel otherwise False
'Needed to check if the view is a Panel or an Activity
Public Sub IsPanel(v As View) As Boolean
    If GetType(v) = "anywheresoftware.b4a.BALayout" Then
        Dim obj As Object
        obj = GetParent(v)
        If GetType(obj) = "android.widget.FrameLayout" Then
            Return False
        Else
            Return True
        End If   
    Else
        Return False
    End If
End Sub

'Returns True If the View v Is an Activity otherwise False
'Needed to check if the view is a Panel or an Activity
Public Sub IsActivity(v As View) As Boolean
    Dim obj As Object
    obj = GetParent(v)
    If GetType(obj) = "android.widget.FrameLayout" Then
        Return True
    Else
        Return False
    End If
End Sub

'Sets new reference screen values
'Default values are Width = 320, Height = 480 Scale = 1
Public Sub SetReferenceLayout(Width As Int, Height As Int, Scale As Double)
    If Width < Height Then
        cRefWidth = Width
        cRefHeight = Height
    Else
        cRefWidth = Width
        cRefHeight = Height
    End If
    cRefScale = Scale
    Initialize
End Sub

Sub GetParent(v As View) As Object
    Dim jobj = v As JavaObject
    Return jobj.RunMethod("getParent", Null)
End Sub
 
Upvote 0
Top