If I understand the documentation correctly, a call to Resources.getIdentifier() returns 0 in case the resource with name doesn't exist. An emulator with API level 8 works that way.
However, if I use an emulator with API level 16 it creates a new id for me. I can even call Resources.getResourceName() on it to get the name I used in Resources.getIdentifier(). If I call Resources.getString() it throws an exception.
int resourceId;
// both calls return the same value:
resourceId = resources.getIdentifier("com.testthisout:string/idontexist", null, null);
resourceId = resources.getIdentifier("idontexist", "string", "com.testthisout");
// with API-level 8 resourceId is 0.
// with API-level 16 it's something like 0x7f07005f now.
resources.getResourceName(resourceId); // returns "com.testthisout:string/idontexist"
resources.getString(resourceId); // BANG!!!
android.content.res.Resources$NotFoundException: String resource ID #0x7f07005f
at android.content.res.Resources.getText(Resources.java:229)
at android.content.res.Resources.getString(Resources.java:313)
at android.content.res.Resources.getString(Resources.java:341)
<my method here, no nested exception or something>
Resources.getIdentifier() returns incrementing numbers for all further calls to it with non-existing resource names and apparently it stores them somewhere.
I've already created a fresh emulator from scratch and still have the same behaviour. I have tests with robolectric in a different project (that is linked into my main project just like their guide explains), but it doesn't help if I close that project (I thought that their shadowing mechanism somehow causes issues). Cleaning and rebuilding the project doesn't help, there is no warning or error.
I need this functionality as I'm working with generic resource names and some more logic in the background.
Is this behaviour expected? Is there something that I'm doing wrong?
Related
No one of the translated strings are working at this moment, so the app always take the main strings file key.
Debugging, if i try to see the id of a key it returns a value. For example R.string.app_name returns 1900088 but getString(R.string.app_name) returns Method threw 'android.content.res.Resources$NotFoundException' exception. with cause android.content.res.Resources$NotFoundException: String resource ID #0x1cfe38.
The strings files have no errors. I really dont know how to proceed with this
EDIT:
using the same files in a new project worked perfectly
OK, the problem was in the gradle for the app module. There was a resConfig "zz" than can lead to this. Removing this line avoids all translation problems
I have tested the application on my device and few emulators. The app doesn't crash and I don't see anything on the LogCat but I can see around 400 crashes within 22 hours in ANRs & crashes.
The error doesn't say which resource is missing to check it and if it's missing why it is not crashing on my phone?
This is the line which causes the crash:
int themeLayout = sharedPreferences.getInt(THEME_KEY, R.layout.input_1);
mInputView = (LatinKeyboardView) getLayoutInflater().inflate(
themeLayout, null);
If shared preference returns null then I assigned a default value to use that one but still, it crash. I checked the layout and it exists, also check the content.
I created the emulator with the same specification but it doesn't crash.
android.content.res.Resources$NotFoundException: at
android.content.res.ResourcesImpl.getValue (ResourcesImpl.java:202)
at android.content.res.Resources.loadXmlResourceParser
(Resources.java:2968) at android.content.res.Resources.getLayout
(Resources.java:1984) at android.view.LayoutInflater.inflate
(LayoutInflater.java:425) at android.view.LayoutInflater.inflate
(LayoutInflater.java:378) at
com.sunzala.afghankeyboard.android.SoftKeyboard.onCreateInputView
(SoftKeyboard.java:163) at
com.sunzala.afghankeyboard.android.SoftKeyboard.onStartInput
(SoftKeyboard.java:242) at
android.inputmethodservice.InputMethodService.doStartInput
(InputMethodService.java:2641) at
android.inputmethodservice.InputMethodService$InputMethodImpl.startInput
(InputMethodService.java:590) at
android.inputmethodservice.IInputMethodWrapper.executeMessage
(IInputMethodWrapper.java:186) at
com.android.internal.os.HandlerCaller$MyHandler.handleMessage
(HandlerCaller.java:37)
Edit:
I found this error:
E/dalvikvm: Could not find class
'android.graphics.drawable.RippleDrawable', referenced from method
android.support.v7.widget.AppCompatImageHelper.hasOverlappingRendering
The R values that we refer to in Java code, such as R.layout.input_8, are public static final int values on a code-generated R class. You will find that class in the build/generated/source/r/ directory of your module. The file will be fairly large, but you will see stuff like:
public static final class layout {
public static final int activity_main=0x7f050000;
}
That number (0x7f050000) is generated by the build tools (aapt, specifically, IIRC). And that value can change from build to build. As a result, it is not safe to persist such a number. Otherwise, you wind up with scenarios like this:
User installs your app
User does something in your app that causes you to persist a value (e.g., editor.putInt(THEME_KEY, R.layout.input_8).apply();)
Time passes
You ship an update to your app, where, as it turns out, the number for R.layout.input_8 changes
The user installs the update to your app
Your code calls sharedPreferences.getInt(THEME_KEY, R.layout.input_1); and retrieves a number that used to be a resource ID... but now is just a number, or points to some different resource
Your code crashes
The user gets frustrated and throws their phone against a wall
Note: no actual phones or walls were harmed in the creation of this scenario
This is a problem with your code. I do not know if it is the problem that is triggering your crashes, but it could be.
The problem is that you are persisting a value (0x7f050000) that you do not control. You think that R.layout.input_8 will always be 0x7f050000, but that is not the case.
What you need to do is store something else in the preference, then use that to look up the proper ID. There are two main approaches for this.
One is to use a simple index. Your naming scheme suggests that you have a series of numbered layouts, at least through 8. So, you could save a number between 1 and 8 in the SharedPreferences, then use that as an index into an array:
static final int[] THE_LAYOUTS={R.layout.input_1, R.layout.input_2, R.layout.input_3, R.layout.input_4, R.layout.input_5, R.layout.input_6, R.layout.input_7, R.layout.input_8};
In this solution, editor.putInt(THEME_KEY, R.layout.input_8).apply(); turns into editor.putInt(THEME_KEY, 8).apply();, and sharedPreferences.getInt(THEME_KEY, R.layout.input_1); turns into THE_LAYOUTS[sharedPreferences.getInt(THEME_KEY, 1)];.
The other is to save the string "R.layout.input_8". Given that, and getIdentifier() on a Resources object, you can get back the int value associated with that string for your current build. Personally, I find this to be more awkward and slower, but it's an option.
I am using getIdentifier to get the id of a raw resource by name. It is not working though, and I am certain to be using it correctly. Is there something that I am missing?
I have verified that the raw resources exist under the string I am giving it. I have also cleaned the project to make sure that R.java is correct.
id = ctx.getResources().getIdentifier("file_name", null , ctx.getPackageName());
Looks like the methods needs the type/ (or defType) param. Should be something like drawable or layout depending on the resource directory.
You can include it in the first String parameter :
id = ctx.getResources().getIdentifier("drawable/file_name", null , ctx.getPackageName());
or pass it as the second parameter :
id = ctx.getResources().getIdentifier("file_name", "drawable", ctx.getPackageName());
Also, be sure to exclude the file extension from the file name you're passing. If the methods still returns 0, check if file_name corresponds to an id somewhere in your R.java file.
Way late, but I think this issue is related to an incorrect application id.
It is configured in you app's module build.gradle file:
android{
defaultConfig {
applicationId "your application id goes here"
From what I have observered, It seems the packageName for the generated R file is base on the value of the packageName in the Manifest.xml file. However the context.GetPackageName seems to be returning the value of the configured applicationId. If they are the same, then there's no issue. If they are different than a call to resources.getIdentifier(…,..., ctx.getPackageName()) will fail to find the identifier.
I'm not sure that the above paragraph is totally correct. What I actually observed was that If I changed the applicationId to match name of the PackageName in the Manifest.xml file then the issue I had on not getting a resource identifier using the getIdentifer method went away. I have to admit, I was somewhat surprised that corrected my problem.
I am facing these problems when integrating slide menu library in Android Studio(1.1.0) project. I am using sdk 24.1.2.
The error is at line 63 in the code given below:
super(act, R.id.menu_label, items);
However i have integrated this library in one of my eclipse project & no error has been evolved there.
Reports two types of problems:
Supplying the wrong type of resource identifier. For example, when calling Resources.getString(int id), you should be passing R.string.something, not R.drawable.something.
Passing the wrong constant to a method which expects one of a specific set of constants. For example, when calling View#setLayoutDirection, the parameter must be android.view.View.LAYOUT_DIRECTION_LTR or android.view.View.LAYOUT_DIRECTION_RTL.
I am trying to develop an application that requires the ability to capture screen content. I'm targeting lollipop to avoid the requirement for root. When trying to get an instance of the MediaProjectionManager via a call to getSystemService() I am getting the following error reported in Android Studio:
Must be one of: Context.POWER_SERVICE, Context.WINDOW_SERVICE, Context.LAYOUT_INFLATER_SERVICE, Context.ACCOUNT_SERVICE, Context.ACTIVITY_SERVICE, Context.ALARM_SERVICE, Context.NOTIFICATION_SERVICE, Context.ACCESSIBILITY_SERVICE, Context.CAPTIONING_SERVICE, Context.KEYGUARD_SERVICE, Context.LOCATION_SERVICE, Context.SEARCH_SERVICE, Context.SENSOR_SERVICE, Context.STORAGE_SERVICE, Context.WALLPAPER_SERVICE, Context.VIBRATOR_SERVICE, Context.CONNECTIVITY_SERVICE, Context.WIFI_SERVICE, Context.WIFI_P2P_SERVICE, Context.NSD_SERVICE, Context.AUDIO_SERVICE, Context.MEDIA_ROUTER_SERVICE, Context.TELEPHONY_SERVICE, Context.CLIPBOARD_SERVICE, Context.INPUT_METHOD_SERVICE, Context.TEXT_SERVICES_MANAGER_SERVICE, Context.DROPBOX_SERVICE, Context.DEVICE_POLICY_SERVICE, Context.UI_MODE_SERVICE, Context.DOWNLOAD_SERVICE, Context.NFC_SERVICE, Context.BLUETOOTH_SERVICE, Context.USB_SERVICE, Context.INPUT_SERVICE, Context.DISPLAY_SERVICE, Context.USER_SERVICE, Context.PRINT_SERVICE less... (Ctrl+F1)
Reports two types of problems:
* Supplying the wrong type of resource identifier. For example, when calling Resources.getString(int id), you should be passing R.string.something, not R.drawable.something.
* Passing the wrong constant to a method which expects one of a specific set of constants. For example, when calling View#setLayoutDirection, the parameter must be android.view.View.LAYOUT_DIRECTION_LTR or android.view.View.LAYOUT_DIRECTION_RTL.
I am currently at a loss as to why this constant is not considered valid, it's there as an autocomplete option, so it's present, and it's shown in all sample code I have seen for screen capture in lollipop. I have verified that the project setup specifies Android SDK 21 as min and target. Is there something else obvious/stupid I might be missing that would cause this error?
UPDATE: Took the exact same code to Eclipse and it works without issue. So this is related to something in Android Studio specifically it seems.
I get this error while getting Context.BLUETOOTH_SERVICEand the error doc (Must be one of..) contains Context.BLUETOOTH_SERVICE though.
This is not the way Android Studio "1.2" should work. :#
Anyway, its an Inspection bug, Constant and Resource Type mismatch (How in the hell Bluetooth is a resource in android context).
You can suppress this for Class/Method/Statement, for statement, add #SuppressWarnings("ResourceType") above or before the statement.
Another approach:
Goto Settings>>Editor>>Inspection>>Android>>Constant and Resource Type Mismatches and make the severity to anything but Error, probably Warning or Weak Warning.
(Though it fixes the error issue, but I want this mismatch to be an error when it really happens.)
Run into the same problem, it is so strange, there are no any other threads talking about this problem.
Well, actually you can just ignore this error and still run the program, even with
the red marks on it