Android Question Problem with DirRootExternal

MetalOS

Member
Licensed User
Longtime User
Hello, I am having a problem with my application since my smartphone was updated to a new version of Android. Here is the error returned by the debugger.

B4X:
java.io.FileNotFoundException: /storage/emulated/0/File.pdf: open failed: ENOENT (No such file or directory)

Here is the code I use to save my file

B4X:
Dim out As OutputStream = File.OpenOutput(File.DirRootExternal, "File.pdf", False)
pdf.WriteToStream(out)
out.Close
pdf.Close

And here is what I indicated in my Manifest

B4X:
AddPermission(android.permission.MANAGE_EXTERNAL_STORAGE)
AddPermission(android.permission.WRITE_EXTERNAL_STORAGE)
AddPermission(android.permission.WRITE_MEDIA_STORAGE)
SetApplicationAttribute(android:requestLegacyExternalStorage, true)


The application is not published on the play store and has always worked for several years. From what I have read it seems that using DirRootExternal is no longer the correct method. How do I go about correcting this problem? Thank you in advance for your help.
 

BlueVision

Active Member
Licensed User
Longtime User
It depends on the target SDK-Level.
Try o use XUI.DefaultFolder.
Search the forum for DirRootExternal, you will find enough explanations.
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
And is it possible to find an example that uses XUI.DefaultFolder?
XUI.DefaultFolder is exactly the same as File.DirInternal. Most examples posted in recent years use it and require no permissions. The forum is full of projects that store data in xui.Defaultfolder(same as File.DirInternal)
 
Upvote 0

BlueVision

Active Member
Licensed User
Longtime User
You wrote about a new phone. As long as you do not try to publish this app on the playstore, using it for your own, try this:
If you recompiled your app with a newer version of B4A, you run into a problem with the SDK-Level. You can prevent this by limiting your app to SDK-level 28.
For this you have to edit within the manifest editor. Search for something like this:

B4X:
AddManifestText(
<uses-sdk android:minSdkVersion="5" android:targetSdkVersion="33"/>

Change the value of "33" to "28".

Keep in mind, this is not the recommended way, but it should force your new phone to run the app with the regulations for SDK 28. This is outdated and Google will not accept uploading this code to the playstore. But it gives you hopefully time to fix the problem in another way and to run your app on your new phone.

It is normal that newer versions of B4A force you to use an actual SDK-level, so the value for the target SdkVersion is changed in newer versions.
The IDE will give you a warning about an incorrect SDK-level with that change, forcing you to use an actual level. Nothing more.
 
Upvote 0

MetalOS

Member
Licensed User
Longtime User
Here is the content of my Manifest and I am already using version 28. Everything worked well until the Android update.


B4X:
AddManifestText(
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="28"/>
<supports-screens android:largeScreens="true" android:normalScreens="true" android:smallScreens="true" android:anyDensity="true"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" />
)

AddPermission(android.permission.MANAGE_EXTERNAL_STORAGE)
AddPermission(android.permission.WRITE_EXTERNAL_STORAGE)
AddPermission(android.permission.WRITE_MEDIA_STORAGE)
AddApplicationText(<uses-library android:name="org.apache.http.legacy" android:required="false"/>)
SetApplicationAttribute(android:requestLegacyExternalStorage, true)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
'End of default text.

SetApplicationAttribute(android:usesCleartextTraffic, "true")
SetApplicationAttribute(android:theme, "@style/MyAppTheme")

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" />
)   
    

CreateResource(values, theme.xml,
<resources>
    <style name="MyAppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">#494949</item>
        <item name="colorPrimaryDark">#494949</item>
        <item name="colorAccent">#AAAA00</item>
        <item name="windowNoTitle">true</item>
        <item name="windowActionBar">false</item>
    </style>
</resources>
)
 
Upvote 0

MetalOS

Member
Licensed User
Longtime User
Well I think I solved my problem thanks to your help. Here's what I changed.

That
B4X:
Dim out As OutputStream = File.OpenOutput(File.DirRootExternal, "File.pdf", False)
pdf.WriteToStream(out)
out.Close
pdf.Close

simply by that
B4X:
Dim out As OutputStream = File.OpenOutput(xui.DefaultFolder, "File.pdf", False)
pdf.WriteToStream(out)
out.Close
pdf.Close
 
Upvote 0

BlueVision

Active Member
Licensed User
Longtime User
Not sure. Only have a device with ANDROID 11 here. Maybe this does not work with ANDROID 13
Just had a look in one of my older apps. Same problem there. Try to set Max SDK to 29.
Also not sure about the lines 7, 8 and 9 in your manifest. Try to put an -> ' <- in front of line to "comment it out". Assuming it is needed only for very old versions.
Then try again.
 
Upvote 0

BlueVision

Active Member
Licensed User
Longtime User
No they don't force you at all.
You misunderstood probably because of my bad english. This is not a problem of B4A. I meant, the target SDK-Level is getting raised from time to time within B4A. So when you are using a newer version of B4A, it is already in there at the recommended level, to keep your app up do date with newer functions. Good thing. This prevents also a rejection by Google.
In opposite, you have to do a rework of your app from time to time for preventing outdating issues and making it fit for the new rules. And this is the point. Sometimes it is very hard to rewrite an app, working for many years, especially when using file operations. With the restrictions we now have it is sometimes impossible to make it work again on a newer SDK-level. And this is annoying. The code worked for years and now it is wrong because somebody decided it is wrong.

Best example is the download folder. Simply no longer reachable. Most applications put the content there, so it is an ideal place for exchanging files. It is no longer directly reachable on newer SDK-levels. So why not eliminating it completely? Excanging a file is becoming very complicated. In my opinion a very bad decision by Google.

This is no bashing to google, I did that often enough, because they are crapping a good operation system more and more for "reasons of security".
Ok, "the user" should decide were to place a file. Hopefully this file is reachable then.
But what is about the crapping of granted rights or permissions for installed apps? Is the user able to decide? No. When Google thinks it is time to remove a previously granted right or permission from an app, it is simply done. And this makes me angry. It is my phone, my apps (I paid for partially). This is my private room and Google is changing something without my permission? It is the same, when a person you don't know is able to rearrange your living room and paints the walls in a different colour...
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
You misunderstood probably because of my bad english
Yes I did. I agree with everything you just said. In my opinion Android was never a very good OS but as more and more stuff gets hidden from use I despair, which is one reason why I am no longer as active as I used to be.
 
Upvote 0

aidymp

Well-Known Member
Licensed User
Longtime User
Yes I did. I agree with everything you just said. In my opinion Android was never a very good OS but as more and more stuff gets hidden from use I despair, which is one reason why I am no longer as active as I used to be.

Its like buying a house, and every year, appliances and sometimes whole rooms just vanish! Until you no longer recognise the house you purchased, Then one day you wake up and its gone!
 
Upvote 0
Top