Getting error message "Resource is not public" - android

So I'm trying to use the built-in drawable timepicker_up_btn for api level 7. It is in the actual res folder in the sdk, and I can use other resources from that folder. But I get the error message "Resource is not public".
It seems like Google is trying to limit the use of this resource. I would think they don't care if I use it in an Android application and it makes the overall look of my application similar to stock Android.
Anyway, is this fixable? Can I somehow use a non-public resource without copying it to my project? And what is the deal with copying stock resources to own projects? Illegal? Frowned upon? Or go ahead we don't care?

The best thing to do is to copy the files to our application. I was told by some Google employees that you should not reference the resources, rather copy them to your application.
One of the reasons for this is that if you reference a whole bunch of icons for your application, you are not guaranteed that every one of these is updated at the same time when new versions of the SDK is released. You might end up with some up-to-date fancy icons and some old ones :)

Is there any way to use not public android resources in my application?
You can reference them like this
android:drawable="#*android:drawable/pressed_application_background_static"
but it is not recommended, because private resources are likely to be renamed or removed in the future.

Technically you can copy the resource from SDK folder to your own resource folder and then use it as your own. Though I am not sure whether it's a violation of the copyright.

Related

Android Studio - What is the Java Resources Folder?

I know there are two well-known folders where one can put resources.
The first is the /assets folder, the documentation says:
Contains file that should be compiled into an .apk file as-is. You can navigate this directory in the same way as a typical file system using URIs and read files as a stream of bytes using the AssetManager. For example, this is a good location for textures and game data.
The second is the /res folder, the documentation says:
Contains application resources, such as drawable files, layout files, and UI string. See Application Resources for more information.
Now i was wondering, there is a third option to create a resource folder "New > Folder > Java Resources Folder"
To me i looks like some part of the Android Plugin in IntelliJ because it has a little Android symbol in front of it .
Any ideas what the use of it could be? I couldn't find any documentation about it.
My first guess would be to use it in situations where you want to supply resources to a JVM Test.
In standard java world
Resources can be embedded directly in "your source tree" and used with Class's method getResource (see java documentation for a more precise description).
In android world
This practice is not recommanded (do not work at all, because such resources are removed from generated APK). You can still declare Java resources folders (see build.gradle :
sourceSets {
main {
resources.srcDirs = ['src/main/java/yourresourcesfolder']
}
}
And the result in the apk :
Conclusion
As resources's folder tree is removed,using java's resource folder become from my point of view, useless (in an android projet). Using android's asset folder is a better choice (also avoid resource's name conflict, but it's an another story :D )
This post is a bit old, but I want to bring an answer that explain one use case for the java resources directory on Android. If this folder exists in the options of a project it's because something can be done with it...
Enters the Service Loader, that helps to connect other services (aka libraries) into your main app, it can be used as a Gateway for your Android library to extend the functionality of a feature, exposing only the interfaces or abstract classes, with the Service Loader providing the implementation instead of your project having direct access to them.
Here is an example of how it's implemented. So, in summary the folder (META-INF/services) and files you have to create in order to use the Service Loader on an Android App, NEED to be inside this Java Resources Folder, otherwise your provider won't be able to see any implementation.
You can see it working in my sample here if you want to check it out: https://github.com/difereto-globant/test-library-feature/tree/1.0.9.

Can someone actually explain the workings of Resource.Designer.cs?

I routinely have problems during project builds where Resource.Designer gets generated but will no longer compile. My search engine shows that I'm not the only one that has this problem, but I've also not found any reliable "fix" for when it happens.
For example, right now I have a project that works just fine, but if I add a reference to a NuGet library (that I created) then the app will no longer compile because of loads of errors in Resource.Designer.cs.
On another project, I simply upgraded Xamarin Forms and now I can no longer compile, again due to a load of errors in Resource.Designer.cs.
Of course the immediate issue is "how do I fix the errors in these projects" but really I want to understand what is fundamentally going on here. What causes Resource.Designer to get generated and regenerated? What algorithm is used to decide what items get put into that file? Why do we so often end up with a file getting generated that then cannot actually compile? Why is it not getting the references it needs for those items?
I'd really like to understand this at a fundamental level so that once I get past the current thing causing me headaches, I can avoid it in the future when it comes up again (and I most certainly will come up again).
Resource.Designer.cs is synonymous with R.java in Android. Which of course is an application's resources that are referred to by a generated constant Resource ID.
These items are usually defined in your Xamarin.Android's .csproj via:
<AndroidResgenClass>Resource</AndroidResgenClass> (This might be outdated)
or
<AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile> (Current)
This is part of the Android Build process in which the aapt tooling will generate respective constant resource IDs per each resource defined in your project(res/ - Android, Resources/ - Xamarin.Android). These are then processed into binary form and embedded into the .apk. Thus the Resource.designer.cs is generated after a successful aapt.
It then goes a bit further to define a Resource in a specific Resource Type:
http://code.google.com/android/reference/android/R.html
anim
animator
array
attr
bool
color
dimen
drawable
fraction
id
integer
interpolator
layout
menu
mipmap
plurals
raw
string
style
styleable
transition
xml
Since aapt is called in the Android Build tooling, it is highly recommended to not manually invoke it unless you understand the complete Android build process.
https://developer.android.com/studio/command-line/index.html
As far as an "Algorithm", I don't think it's really that complex other than simply mapping a Resource ID to a resource as defined above. There are some complexities in the sense of Merging Resources in a project. For example a library project -> your application project:
The build tools merge resources from a library module with those of a dependent app module. If a given resource ID is defined in both modules, the resource from the app is used.|
If conflicts occur between multiple AAR libraries, then the resource from the library listed first in the dependencies list (toward the top of the dependencies block) is used.
To avoid resource conflicts for common resource IDs, consider using a prefix or other consistent naming scheme that is unique to the module (or is unique across all project modules).
https://developer.android.com/studio/projects/android-library.html#Considerations
Given the majority of people's issues with Resource.designer.cs, they typically come from a point of view of understanding where actual third-party Resources come from and how they are supported. Here are some tips that I personally use:
Ensure your Application project is compiled against the latest API version. Typically this will be the <TargetFrameworkVersion> MSBuild property. One of my colleagues has an amazing blog post that stands the test of time about this factor:
http://redth.codes/such-android-api-levels-much-confuse-wow/
Find where the Resource is coming from. Does it come from an official NuGet package? When was the Resource introduced into the Android framework? (Useful for mostly Material Design items).
For example, if I had an error message regarding colorPrimary, I might check what API it was introduced in:
Added in API level 21
https://developer.android.com/reference/android/R.attr.html#colorPrimary
Thus we now know we require API 21+ at minimum to use this item.
Take a deep dive into the dependencies you are loading into your project. You can use a decompiler like dotPeek to look through an assembly and see what Resources it's trying to give your project. Additionally you can look at the cache of respective .aar and view it's res/ folder. This is mostly useful for larger bindings like the Android Support / Google Play Services ones. For smaller projects, look for the /res string inside the decompiled .dll
For example let's take a look at com.android.support:appcompat-v7:24.2.1:
First we need to find the cache on our machine:
AppData\Local\Xamarin\Xamarin.Android.Support.v7.AppCompat\24.2.1\embedded\res (If you get stuck here on OSX, I wrote a guide awhile back about finding these paths here - https://developer.xamarin.com/guides/android/troubleshooting/resolving-library-installation-errors/)
So we can now look through all of the respective Resources this library is trying to give to us.
Finally the last item is that people tend to delete the Resource.designer.cs file from their project. After the aapt process is complete, it will generate a new one or it will fail on aapt. It is up to you to figure out whether that step passed or not (i.e. Check the main project Resources folder for the newly generated Resource.designer.cs file so you can re-include it into your project).

Using image resources which don't comply to Android's naming scheme

I need to use image resources from an iOS application that I'm porting to Android. Unfortunately they all have dashes in the file name, which causes errors.
I can't rename the resources because they're shared with the iOS codebase, and having duplicate resources is a no-go.
Is there a way I can get around this naming requirement?
There's no way to get around the naming requirement, but you could use symlinks.
(I'm a bit confused, though, and kind of assume you must already be either copying the files or using symlinks. How else could you build both your Android and iOS apps, given the different directory structures required for each?)

Android use of resources from an external file

I have a non-standard Android application that has a requirement to load resources from an external file that is not part of the application apk. These resources will be packaged separately and delivered as its own package.
There are a few different types of items that will be part of this external resource bundle. One of those items includes the localized strings.xml file. This philosophy allows the change of a string / translation that does not affect the deployment of the application (in other words, application.apk stays in tact, but the only difference is a new strings.xml).
I've been searching around, and this doesn't seem possible. Is there any way? Or does this philosophy mean completely abandoning the resources all together and writing a custom layer to pull these strings and other external resources from a file?
The application is for Honeycomb platform.
Thanks in advance for any advise.
The best way to do this, I think, is to package your resources as a ContentProvider. See the guide topic Content Providers for how to get started doing this.

Is there a way to add or change Android apps language after packaging it into an APK?

In the case of a windows application(EXE/DLL), we can change or add language resources within the binary without re-compiling it. Can the same be done in case of an Android application? Is there any editor available to make this happen?
My plan is to develop the application in English and then release it to the sales department, where they will be responsible for the localization of the application without compiling and packaging it into a new APK. I just want to split the development part and localization part of the app.
The correct way to localize is to create a string resource for your base language and then have that localized and reimported into your project for every language that you support.
Much more detail can be found in the Localization documentation.
I don't believe there is a safe/supported way to inject localized strings into your app after it's been built.
No. You can not, because once your apk is signed then modifying it after this (you can always do that as apk is just a zip file) will corrupt the signed binary.
When having multiple languages with your application you have to build them into the application itself. Android uses XML files to store strings used within your application. Android allows you to add language localization files containing local specific strings. You can't do this without recompiling your project so you'll want to do it as a future update or right from the start. But you can't have the marketing department do it, that's just not a good idea.
As others have said, the short answer is no. The long(er) answer is sort of. If you pack all your language resources into remote XML that can be updated from the web, then with a little bit of forethought you can do all sorts of live updates to your app's strings, graphics, etc.
So if you want to use the standard R.string method for everything it will be a little difficult. I think it's possible to do something funky with a dynamic classloader for the assets and static dex classes (basically classes of data with just inline byte arrays that can be decoded after). However that would still require compiling. See Custom Class Loading in Dalvik for more info.
Another approach would be more of a standard Java implementation. Java has a class known as ResourceBundle. You could create a ResourceBundle from a property file (key-value plain text, or even property xml). Then these files could be loaded outside the apk, via a network connection or sdcard or other file type resource and deleted as necessary. You will have to write the loader code for it, but that's going to happen with any solution. This solution will be less performant and outside the standard design methods for android but it will solve the problem being asked to solve. Like you won't be able to use R.string or #string/whatever for any of these resources but I think you may be able to write an adapter to such resources (like your own TextView extension and whatever that would allow all of this). It's a matter mostly of how much work you want to invest in solving this actual problem.
Honestly I would opt for trying to distribute whole apks with only the targeted language if you are trying to save space, but then there is no way to change locale for the app at runtime :(

Categories

Resources