B4A Library AndroidResources

There's a few threads on the forums about accessing the build in Android resources but i couldn't find any code that would allow me to get a built in Android resource drawable using the resource's name - all posted code required that you already know the resource id.

So after a bit of research i created this method:



The documentation for the android.R.drawable class can be found here: R.drawable | Android Developers

Another thing i've been trying to do recently is simply load an icon on a device with high density display but not have the Android OS automatically upscale the icon to a larger size and leave me with a pixelated poor quality icon.
I don't want the icon upscaled...

A solution is to add the icon to my project's Objects\res\drawable-nodpi - creating that folder if it doesn't exist.
But now how can i access that icon?

A new method derived from Barx's recent post here:



Drawables in the drawable-nodpi folder are NOT rescaled on low or high density devices.

While researching all of this i found that the android.R.string class contains localised versions of commonly used application text such as language versions of 'paste' and 'cancel'.
Another new method:

AndroidResources
Version:
1.6
  • AndroidResources
    Methods:
    • GetAndroidDrawable (ResourceName As String) As Drawable
      Get an android resource drawable by ResourceName.
      Returns Null if the Drawable is not found.
    • GetAndroidDrawableNames As List
      Get a List of all available android Drawable resource names.
    • GetAndroidDrawables (ResourceNames As Map) As Map
      Get one or more android resource Drawables.
      Pass a Map to this method where each Map key is an android Drawable resource name.
      The method will return the same Map object where the Map values are the android resource Drawables defined by the Map keys.
      If an android resource Drawable is not found the Map value will not be changed.
    • GetAndroidString (ResourceName As String) As String
      Get an android resource string by ResourceName.
      Returns Null if the String is not found.
    • GetAndroidStringNames As List
      Get a List of all available android String resource names.
    • GetAndroidStrings (ResourceNames As Map) As Map
      Get one or more android resource Strings.
      Pass a Map to this method where each Map key is an android String resource name.
      The method will return the same Map object where the Map values are the android resource Strings defined by the Map keys.
      If an android String is not found the Map value will not be changed.
    • GetApplicationDrawable (ResourceName As String) As Drawable
      Get an application resource Drawable by ResourceName.
      Returns Null if the Drawable is not found.
    • GetApplicationDrawables (ResourceNames As Map) As Map
      Get one or more application resource Drawables.
      Pass a Map to this method where each Map key is an application Drawable resource name.
      The method will return the same Map object where the Map values are the application resource Drawables defined by the Map keys.
      If an application resource Drawable is not found the Map value will not be changed.
    • GetApplicationRawResource (ResourceName As String) As InputStreamWrapper
      Get an application raw resource as an InputStream.
      The InputStream will not be initialized if the raw resource cannot be found.
    • GetApplicationResourceNames (ResourceType As String) As List
      Returns a List of Strings which are the application resource names for the ResourceType.
      ResourceType must be one of the android R class nested class names.
      ResourceType values such as color, drawable, integer, layout and string are valid.
      All nested R class classes are documented here:
      http://developer.android.com/reference/android/R.html
    • GetApplicationString (ResourceName As String) As String
      Get an application resource String by ResourceName.
      Returns Null if the String is not found.
    • GetApplicationStrings (ResourceNames As Map) As Map
      Get one or more application resource Strings.
      Pass a Map to this method where each Map key is an application String resource name.
      The method will return the same Map object where the Map values are the application resource Strings defined by the Map keys.
      If an application resource String is not found the Map value will not be changed.

The String returned by this new method will be in the language that the device has selected in Settings > Language & keyboard settings.
The documentation for the android.R.string class can be found here: R.string | Android Developers.

So i've created the library AndroidResources for everyone to use and if any library writers want to use any of these methods in their libraries then please do!



For some reason the forum would not accept the code snippets so check out the attached AndroidResources.txt file for the complete post!

Martin.
 

Attachments

  • AndroidResources.txt
    3 KB · Views: 1,658
  • AndroidResourcesDemo.zip
    28 KB · Views: 969
  • AndroidResources_v1_60.zip
    5.2 KB · Views: 1,531
Last edited:

yonson

Active Member
Licensed User
sorry thats me being an idiot, needed to use

GetApplicationDrawable

and not

getAndroidDrawable


please ignore the above but I'll put in the solution in case anyone else has problems
 

deltacode

Member
Licensed User
Hi Warwound

This is a great library, many thanks. Is there any chance you can add support to grab sound files from the raw directory ?
 

warwound

Expert
Licensed User
AndroidResources updated to version 1.50

This update adds support for accessing application raw resources:

GetApplicationRawResource (ResourceName As String) As InputStreamWrapper
Get an application raw resource as an InputStream.
The InputStream will not be initialized if the raw resource cannot be found.


Here's a simple example:

B4X:
Sub Process_Globals

End Sub

Sub Globals

End Sub

Sub Activity_Create(FirstTime As Boolean)
   Dim AndroidResources1 As AndroidResources
   Dim InputStream1 As InputStream
   Dim ResourceName As String="my_raw_resource"
  
   InputStream1=AndroidResources1.GetApplicationRawResource(ResourceName)
  
   If InputStream1.IsInitialized Then
     Log("Successfully found raw resource: "&ResourceName)
     Dim TextReader1 As TextReader
     TextReader1.Initialize(InputStream1)
     Dim Lines As List
     Lines=TextReader1.ReadList
     For Each Line As String In Lines
       Log(Line)
     Next
   Else
     Log("Failed to find raw resource: "&ResourceName)
   End If

End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

I created a text file, entered some text and saved it as Objects\res\raw\my_raw_resource.
(I also set the file's attributes to read-only to prevent the compiler from deleting the file).

The example gets this raw resource as an InputStream, initializes a TextReader with the InputStream and then logs the contents of the raw resource.

Version 1.50 of AndroidResources is attached to the first post in this thread.
The example project is attached to this post.

Martin.
 

Attachments

  • RawResources.zip
    6.6 KB · Views: 135

warwound

Expert
Licensed User
AndroidResources updated to version 1.60

This update adds a new method:

GetApplicationResourceNames (ResourceType As String) As List
Returns a List of Strings which are the application resource names for the ResourceType.
ResourceType must be one of the android R class nested class names.
ResourceType values such as color, drawable, integer, layout and string are valid.
All nested R class classes are documented here:
http://developer.android.com/reference/android/R.html


A simple example showing how to get all application String resource names:

B4X:
   Dim AndroidResources1 As AndroidResources
   Dim ApplicationStringNames As List=AndroidResources1.GetApplicationResourceNames("string")
   If ApplicationStringNames.IsInitialized Then
     For Each StringName As String In ApplicationStringNames
       Log(StringName)
     Next
   Else
     Log("ApplicationStringNames not initialized")
   End If

Version 1.60 is attached to the first post in this thread.

Martin.
 

peacemaker

Expert
Licensed User
Thanks, Martin. Donated with thanks again.
So, now init can be universal sub:


B4X:
Sub ResoursesInit
Dim ApplicationStringNames As List = Main.AndroidResources1.GetApplicationResourceNames("string")
If ApplicationStringNames.IsInitialized Then
    Main.ResourceStrings.Initialize
    For Each StringName As String In ApplicationStringNames
        'Log(StringName)
        Main.ResourceStrings.Put(StringName, "")
    Next
Else
    Log("ApplicationStringNames not initialized")
    ToastMessageShow("Fatal application error, contact developer, please.", True)
    DoEvents
    ExitApplication
    Return
End If

Main.ResourceStrings = Main.AndroidResources1.GetApplicationStrings(Main.ResourceStrings)
End Sub
 
Last edited:

bluedude

Well-Known Member
Licensed User
Hi warhound,

I want to use GetAndroidDrawable in an Addmenu but it seems it does not return the correct type? I want to load ic_action_overflow from an Android resources by its name.

Thanks in advance!
 

thedesolatesoul

Expert
Licensed User
Hi warhound,

I want to use GetAndroidDrawable in an Addmenu but it seems it does not return the correct type? I want to load ic_action_overflow from an Android resources by its name.

Thanks in advance!
Just to correct you, its warwound, not warhound.
GetAndroidDrawable will return a bitmap drawable, you can cast it to a bitmapdrawable and then take its bitmap.
B4X:
Dim bd as BitmapDrawable
bd = GetAndroidDrawable("xx")
Activity.AddMenuItem2("Open File", "OpenFile", bd.Bitmap)
 

bluedude

Well-Known Member
Licensed User
Hi,

Tried that with for example ic_action_overflow resource but it does not work. I'm using AddMenuItem3 to add it to the Stdactionbar.

Cheers.
 

warwound

Expert
Licensed User
Hi,

Tried that with for example ic_action_overflow resource but it does not work. I'm using AddMenuItem3 to add it to the Stdactionbar.

Cheers.

Use the GetAndroidDrawableNames method, it returns a List of all available android drawable resources.
Now iterate through the List and check if it contains an entry for 'ic_action_overflow'.

In theory every device contains the default android drawable resources BUT it's worth checking.

Can you post details of the device(s) that you're running this on?
Make, model and android version.

Martin.
 

bluedude

Well-Known Member
Licensed User
warwound, it seems the overflow icon does not exist :) Looks strange to me but could not find it.

Anyone?

Cheers.
 

warwound

Expert
Licensed User
Manufacturer are free to modify or omit some (maybe all but i think not!) built in resources when they create a new device.

Most tutorials i have read recommend that you take a copy of the built in resource from the location of the android sdk on your computer and include that copy in your application.
That means you have a known drawable - one that definitely exists and one whose appearance you know.
If you don't take this approach you may find that the resource you are relying on is not present (as in your case) or has been modified.
A modified drawable might not 'fit in' with your app's design so again copy a know resource to your application is recommended by many.

I have another library that might be of interest to anyone following this thread:

Resources
Comment: Object for accessing application or system resources.
http://developer.android.com/reference/android/content/res/Resources.html
Version: 1
  • Resources
    Fields:
    • RESOURCE_SOURCE_APPLICATION As ResourceSource
      Constant field used to reference the application's resources.
    • RESOURCE_SOURCE_SYSTEM As ResourceSource
      Constant field used to reference the system's resources.
    Methods:
    • GetBoolean (ResourceId As Int) As Boolean
      Return a boolean associated with the resource ID.
    • GetColor (ResourceId As Int) As Int
      Return a color integer associated with the resource ID.
    • GetDimension (ResourceId As Int) As Float
      Retrieve a dimensional for the resource ID.
    • GetDimensionPixelOffset (ResourceId As Int) As Int
      Retrieve a dimensional for the resource ID for use as an offset in raw pixels.
    • GetDimensionPixelSize (ResourceId As Int) As Int
      Retrieve a dimensional for the resource ID for use as a size in raw pixels.
    • GetDrawable (ResourceId As Int) As Drawable
      Return a drawable object associated with the resource ID.
    • GetDrawableForDensity (ResourceId As Int, Density As Int) As Drawable
      Return a drawable object associated with the resource ID for the given screen density in DPI.
    • GetIdentifier (ResourceName As String, ResourceType As String, DefaultPackage As String) As Int
      Returns an integer resource identifier for the given resource name.
      A fully qualified resource name is of the form "package:type/entry".
      The first two components (package and type) are optional if ResourceType and DefaultPackage, respectively, are specified here.
      ResourceName - The name of the desired resource.
      ResourceType - Optional resource type to find, if "type/" is not included in the name.
      DefaultPackage - Optional default package to find, if "package:" is not included in the name.
      Returns 0 if no such resource was found. (0 is not a valid resource ID).
    • GetIntArray (ResourceId As Int) As Int[]
      Return the int array associated with the resource ID.
    • GetInteger (ResourceId As Int) As Int
      Return an integer associated with the resource ID.
    • GetQuantityString (ResourceId As Int, Quantity As Int) As String
      Returns the string necessary for grammatically correct pluralization of the resource ID for the quantity.
    • GetResourceEntryName (ResourceId As Int) As String
      Return the entry name for the resource identifier.
    • GetResourceName (ResourceId As Int) As String
      Return the full name for the resource identifier.
    • GetResourceNames (ResourceSource1 As ResourceSource, ResourceType As String) As List
      Returns a List containing resource names.
      ResourceSource1 - Either RESOURCE_SOURCE_APPLICATION or RESOURCE_SOURCE_SYSTEM.
      ResourceType - The type of resources to return resource names for, eg "string" or "drawable".
    • GetResourcePackageName (ResourceId As Int) As String
      Return the package name for the resource identifier.
    • GetResourceTypeName (ResourceId As Int) As String
      Return the type name for the resource identifier.
    • GetString (ResourceId As Int) As String
      Return the string value associated with the resource ID.
      It will be stripped of any styled text information.
    • GetStringArray (ResourceId As Int) As String[]
      Return the string array associated with the resource ID.
    • Initialize (ResourceSource1 As ResourceSource)
      Initialize the Resources object.
      ResourceSource1 - Either RESOURCE_SOURCE_APPLICATION or RESOURCE_SOURCE_SYSTEM.
    • IsInitialized As Boolean
    • OpenRawResource (ResourceId As Int) As InputStreamWrapper
      Open a data stream for reading a raw resource.
    Properties:
    • PackageName As String [read only]
      Returns the application package name.

This library is a wrapper for the android Resources class and offers a little extra functionality than my original AndroidResources library.
If anyone is interested then let me know and i'll upload it.

Martin.
 

andrewj

Active Member
Licensed User
Hi Martin,
Do you happen to know what I should look for to find the default colour of menus, so that I can match my own drop-downs to them/
Thanks
Andrew
 

Eme Fibonacci

Well-Known Member
Licensed User
    • GetQuantityString (ResourceId As Int, Quantity As Int) As String
      Returns the string necessary for grammatically correct pluralization of the resource ID for the quantity.

Hi,
Please, you still have a library that has the "GetQuantityString" functionality?
Can post and show how to use? Thank you very much.

Thank you.
 

warwound

Expert
Licensed User

Eme Fibonacci

Well-Known Member
Licensed User

peacemaker

Expert
Licensed User
Is it possible to get strings of any language existing in strings.xml files on the fly ?
For server app it needs to use all languages strings available.
 
Top