For some time we have been receiving weird android.content.res.Resources$NotFoundException exception from our production application (via Play store).
The error commonly appears while trying to access to string resources declared in res/values.
To give a concrete example, in our Application subclass, we load a string ressources in onCreate() method (so at any app launch).
The string resource actually exists in res/values and the production application works fine on all our test devices so it cannot comes from a wrong generation of the R file.
We guessed it came from the fact the the values weren't redefined in other values package (like values-hdpi or other packages) and copying the string values into all packages actually stopped the exceptions.
Still, according to the Android documentation, if no specific values are found, the values of the default package are taken by default so we don't understand why this error occurs.
We are thinking it might be custom roms that don't operate 'normally' so I wanted to know if other people had the same issues or anyone had other suggestions.
There are so many Android devices with different configurations. So when we don't keep resources specific to corresponding matching device configuration[drawable-hdpi,values-en,layout-land etc] then android system looks into default configurations for that resource[drawable,values & layout].
So recommending to keep both default & configuration specific resources in respective locations.
Related
I have app module and one dynamic module named - "chat". I have a layout and fragment resides in chat module, in layout there is a android:textSize="#dimen/sp20" written. Dimen is defined in app module due to that it is showing incorrect text size when I run it. I debugged it, it is equal to 12sp (36 for xxhdpi device).
I tried to use dimen programtically but same result. (landing_page_toolbar_title.setTextSize(TypedValue.COMPLEX_UNIT_PX, resources.getDimension(com.sendbird.R.dimen.sp20))) . Carefully used "R" from app module package.
When I define the same value in chat module, it works perfectly. But it is not feasible for our scenario. I have tons of string, dimens, color resources with multiple configurations written in app module. Please share feasible solution.
Attaching screenshot for better understanding.
Can you try by updating your app module resources with the "app_sp20" prefix, it will be resolved mostly.
Common names are mostly overridden by SDKs/modules
Still, you face the problem then use reflection as the last option.
When a dynamic module is downloaded, it’s code and resources are placed at the app's internal storage. Maybe this storage has an inconsistent or outdated state (incl. cached resources from the app). If the problem occurs during depelopment / testing try to clear your app's internal storage.
Also make sure that you initialize SplitCompat correctly for your app and all activities / fragments of your dynamic module as described: here. Documentation is quite vague about what SplitCompat is actually doing but not initializing it correctly could also have impact on the access of app resources from dynamic modules.
If I added Slovak (SK) language (values-sk-rSK and values-sk) to the Android Wear 1.5 apks (framework-res.apk also), language wasn't set to SK automatically even I had SK on the phone.. so for change language on the Wear watches is needed to translate also Wear app on the phone to SK lang..? Or why my translation wasn't loaded on the watches..?
I have a lot of experiences with adding translation into the Android ROM for phones, but seems it works differently on Android Wear...
Thank you for any help...
As stated in this Localization Tips: Design your application to work in any locale documentation, if your application is missing even one default resource, it will not run on a device that is set to an unsupported locale.
For example, the res/values/strings.xml default file might lack one string that the application needs: When the application runs in an unsupported locale and attempts to load res/values/strings.xml, the user will see an error message and a Force Close button.
You may also check this link which explains challenges in resolving Language resources. Be noted that when your Java code refers to strings, the system would load strings from the default (en_US) resource file, even if the app has Spanish resources localized under es_ES. This is because when the system cannot find an exact match, it continues to look for resources by stripping the country code off the locale. Finally, if no match is found, the system falls back to the default, which is en_US.
Here's a related SO thread which might help.
In Android Studio 2.2.2 I have an error in AndroidManifest.xml file saying
Resources referenced from the manifest cannot vary by configuration
There is a StackOverflow question by someone else on this message but the answer only describes how to ignore it. What I want to know is what does it mean?
The line associated with the error says
android:versionName="#string/appvername"
what does the error mean and how do I prevent (not just ignore) it? What is a "configuration" in this context?
What is a "configuration" in this context?
Quoting the documentation:
You should always externalize resources such as images and strings from your application code, so that you can maintain them independently. Externalizing your resources also allows you to provide alternative resources that support specific device configurations such as different languages or screen sizes, which becomes increasingly important as more Android-powered devices become available with different configurations. In order to provide compatibility with different configurations, you must organize resources in your project's res/ directory, using various sub-directories that group resources by type and configuration.
So, a configuration is a mix of device capabilities and states that controls what resources get loaded. For example, the device locale settings determine which strings get used from your available string resources.
What I want to know is what does it mean?
Not every attribute in the manifest can be populated by a resource, because the system cannot handle varying values based on configuration.
For example, you cannot change the Java class name of an <activity> by using a string resource in android:name, with an eye towards using different Java classes with different screen sizes. While that's an interesting concept, Android is not set up to support that.
how do I prevent (not just ignore) it?
In this case, I think you are encountering an IDE bug. android:versionName should support string resources, as that is a user-facing value, and therefore you might want to translate the string. So, add tools:ignore="ManifestResource" to the <manifest> element, until the bug gets fixed.
We purchased the source code to a certain Android and iOS application and now need to re-brand it before releasing it on the app stores. I'm quite familiar with Android, so that side wasn't an issue. However, I've never touched iOS apps before, so I have a few questions.
On the Android side, we changed the application name by changing several string resources. Then we changed the package name in the manifest.xml file (to make this a unique application in the eyes of Google Play) along with changing the package names in the affected class files. And compile.
Would iOS applications require something similar? Is there an equivalent to the Android string resources where I can change strings in one place and they are reused throughout the application? Also do iOS applications have some sort of unique ID, the equivalent of the Android's package name in the manifest.xml file? If I change this unique ID, does it impact the code in any way (in Android the package name corresponds to the main application Java package that starts the application).
The package name you referred is called Bundle Identifier in iOS world.
It can be changed in Project settings, or directly in the project property list (.plist) in the Xcode project.
The original value may look like:
com.example.${PRODUCT_NAME:rfc1034identifier}
You can change it to whatever valid values you want (highly suggest you use reversed FQDN format).
Remember to clean & rebuild to project after changing this value, and all App ID, Provisioning Profiles and probably certificates have to be re-configured.
I have released an android app downloadable in the UK, but I wish to release a (very slightly different) version of the app for the U.S. Currently I believe I need to do the following for the new version of the app ...
1. Change the 'package' attribute in the manifest file to something different.
2. Ensure that on Google Play only the US can download the app.
Is there anything else I am yet to discover I need to do, or any other problems I am yet to consider?
Edit 19th July 13:19 GMT - I am currently warming towards using TelephonyManager.getNetworkCountryIso() as an initial country guess, and falling back on the locale if this fails (because of no SIM card). What do people think? Using GPS is also an option though, but is that overkill?
Since you say you're just changing a couple of strings (we'll think of the URL as just a string, too), I would suggest the following:
Create the resource directories res/values and res/values-en-rUS.
In each of these, create a strings.xml resource file
Define your default (UK specific) string values in the res/values directory, and your US specific string values in the res/values-en-rUS folder.
Then, to refer to these strings, simply use #string/my_string_name when referring to them from an XML document, or getResources().getString(R.string.my_string_name) when referring to them from code.
For more details on the types of resource qualifiers, check out this page, also for the list of qualified country codes you can use, see this page.
I'm sure anyone determined enough could change their region to US -- I'm honestly not sure offhand how the region is determined -- but for all intents and purposes this should do the trick without having to maintain two separate applications. I would just evaluate how critical it is that UK users be unable to access the US specific functions of the application, and with that in mind determine whether it is worth the maintenance of two applications.
EDIT Some more additional searching leads me to believe the region is locked into the build.prop file, which is not editable outside of rooting your device (i.e. it is not going to happen accidentally). That said, if it's still imperative that they have the correct option, I might suggest a popup dialog only on the first run of the application that confirms the locale with the user, saves it as a SharedPreference, and then choose your Strings programmatically based on that preference. That way you're still only maintaining one application, but you still have the flexibility of handling the two regions.
This is correct. The Play Store goes off of two things for who can download and if they can update. The first is the packagename com.andya.myukapp -> com.andya.myusapp should work, as long as none of your existing customers are expecting to switch freely between the two (assuming it's a paid app)
I eventually decided that the best policy was to use TelephonyManager to check the country of the Network.
TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
String networkCountryCode = tm.getNetworkCountryIso();
If that failed, I got the locale.
String locale = context.getResources().getConfiguration().locale.getCountry();
This would happen once at the start of the app. The results of this would then be saved and be configurable in the settings screen.