Android jar and source code mismatch? - android

I have been looking through the android source code for ICS and JB (API15 & API16) and am finding what appears (to me) to be a mismatch between the code and the jar files. More specifically, in SpeechRecognizer.java there is a reference to Settings.Secure.VOICE_RECOGNITION_SERVICE, which is defined in android/provider/Settings.java under the subclass Secure as
public static final String VOICE_RECOGNITION_SERVICE = "voice_recognition_service";
But when I try to reference VOICE_RECOGNITION_SERVICE from my own code, it cannot be resolved. In Eclipse, when I look through the jar file, I do not see VOICE_RECOGNITION_SERVICE defined. In fact, many of the fields in Settings.Secure which are defined as public in the java source code are not found in the jar file. I am wondering why, if the jar file was created using the source files, I cannot access VOICE_RECOGNITION_SERVICE. If a field is declared public in the source then shouldn't it be accessible from the .jar file?

I noticed the same. It seems that often, some of the methods/fields are not visible for application-specific code.
However, sometimes it is possible to invoke these methods/fields by using Java reflections.

Related

How to duplicate com.android.internal.R in my librairy?

Because of just one wrong written line of code in FloatingToolbar.java i was force to copy the entire source code in my library to patch it. This work but now the problem is that this unit call also com.android.internal.R. The problem with com.android.internal.R is that it's could be different between release, (because it's internal), so to be safe i must also duplicate the definition
in r class i have for example :
public static final class layout {
public static final int floating_popup_open_overflow_button=xxx
}
where to find the xml (i think it's an xml?) that define floating_popup_open_overflow_button ? actually in \android-sdk-windows\sources\ i can find only the java files
where to find the xml (i think it's an xml?) that define floating_popup_open_overflow_button ?
You can find a copy in $ANDROID_SDK/platforms/android-NNN/data/res/layout/, where $ANDROID_SDK is wherever you have installed the Android SDK and NNN corresponds with the version of the Java that you forked. There may be other variants of floating_popup_open_overflow_button.xml in peer directories (e.g., layout-xlarge); I have not checked them all.

How to store resource file with same name but different extensions in android

I am working on one static custom Android Media Player Application where i have many media files stored in raw folder.
Where as some files have same name but different extensions, here android is giving me
res\raw\then.mp4:0: error: Resource entry then is already defined.
res\raw\then.mp3:0: Originally defined here..
Can anybody please suggest me something on this?
Also there are few media files with java keywords like if, else, return, switch, case,class, else, final, long, new, this,true... where android is giving me error of invalid symbol.
Please suggest me solution for that also.
Thanks in advance...
As #blackbelt said, it's not possible, I'll just add that you can instead put your files in the assets directory instead of res.
You will not be able to use them like R.id.file, but you will get more flexibility.
simply you can't. Raw is build at compile-time inside R.java, and the name key must follow the java convention for naming. Since
if, else, return, switch, case,class, else, final, long, new,
this,true
are reserved keywords you can not use them.
Edit: R.java would look lie:
public static final class raw {
public static final int if=0x70000;

what R.java file actually does and how

I have been working on a simple android tutorial and while browsing through the project folders I found this R.java file in gen folder...
When I opened it seemed to me as a mess...
first R itself is a class.
it had multiple Inner classes defined within eg drawable,id,layout,etc.
and that inner classes had lots of variables declared as below which were assigned with hex values
public static final int addr=0x7f080003;
...
...
and much more
R is auto generated and acts as some pointer for other files
Questions for R.java
what it is basically for
how it works
why
values are in hex
what role did it performs while the actual application is running
"Acts as some pointer to other files" is actually absolutely correct, now the question is which files it points to how it is done.
What does it contain?
R file contains IDs for all the resources in the res folder of your project and also some additional IDs that you define on your own (in the layouts, for example). The IDs are needed for the Android resource management system to retrieve the files from the APK. Each ID is basically a number which corresponds to some resource in the resource management system.
The file itself is needed so you can access or reference the resource from code by giving the ID of the resource to the resource manager. Say, if you want to set the view in the activity, you call
setContentView(R.layout.main);
main in the R file contains the number which is understood by the Android resource management system as the layout file which is called main.
Why is it better than just plain file names?
It's harder to make a mistake with the generated fields. If you write the field name incorrectly, your program won't compile and you will know that there's an error immediately. If you write an incorrect string, however, the application won't fail until it is launched.
If you want to read more on this topic, you should check the Android documentation, especially the Accessing Resources part.
This holds your resource ids. So when you do something like
TextView tv = (TextView) findViewById(R.id.mytextview);
it looks up your id here for that View, layout, etc... This way the app has an easy way to look up your ids while you can use easy to remember names. Anytime you create a resource it automatically creates an id for it and stores it here. That's why you never want to try and edit this file yourself.
One way to think about how valuable R.java is, imagine a world without it. Its amazing how android brings the xml and java world together to help avoid coding the UI manually completely. With legacy java building UI using the java language was a pain. Invaluable.
With Android you can not only build your UI using only xml, but also see it while you build it. Invaluable.
Every element in the xml can be referenced in the java code WITHOUT writing a single line of code to parse the xml :). Just R.id.nameOfElement. Invaluable.
Rapid development is beautifully done in android. Imagine if iPhone would have 5000 screens to fit that one piece of code, they would crumble on their XCode. Google has done a wonderful job with just R.java. Invaluable.

Android: Is it possible to alias R from app and lib to distinguish between the two?

Can I somehow alias a generated R file from a library and a generated R file from an application?
IE: I have two projects, one being a library. I reference the library in the application.
The library creates one R file, the application creates two: com.example.mapplication.R and the R from the referenced library, com.example.mlibrary.R. However, since I want to use both frequently in the application, I want to alias both the R classes. For example, call the library R something like libR and the app R something like appR.
I tried a couple of things which are of such stupidity, I won't even fully mention them, but I did some things like private com.example.mapplication.R appR = com.example.mapplication.R (immediately realising this wasn't gonna work), and private Class<com.example.mapplication.R> appRclass = com.example.mapplication.R.class;, but that didn't give me the desired effect. I do, however, use the latter method and some reflection to make it possible to be able to get the field and inner classes like this:
Class<com.example.mapplication.R> appRclass = com.example.mapplication.R.class;
int activity_main_layoutid = Toolkit.getFromClass(appR).
getMeTheInnerClass("layout").getMeAField("activity_main");
I haven't fully implemented the Toolkit method, but as we all know refletion can do this kind of stuff, but at the end of the day it's just as much work as just typing com.example.mapplication.R or com.example.mlibrary.R everywhere.
So to wrap thing up: Is it possible to alias multiple R's so that I can use appR and libR to distinguish the two?
I wish we could, but according to what I know, it isn't possible, at least not yet.
I also wish we could put resources in sub folders, but even this is impossible.
What you can do is setting a unique prefix (rename each resource file) for each library, as it's done by some third party libraries (like actionBarSherlock, which uses "abs" as the prefix).
Alternatively, you can have a special trick and put the files in the src folder and reach them from there, but that's more of a workaround, since the R won't have a reference to any of the resources there.
For example, you can put an image called image.png into the src/com/company/app_name, and then create a bitmap from it using:
final InputStream fis = getClass().getResourceAsStream("/com/company/app_name/image.png");
final Bitmap bitmap = BitmapFactory.decodeStream(fis);
By the way, if you've thought of using the assets folder, you can't do it for library projects, since it requires you to have the files in the project that uses the library project. It will work, but it misses the encapsulation idea...

Accessing application resources from the library project

My application depends on a library project.
The menu.xml file is within the application project.
All the java code is within the library project, including the menu handler code onOptionsItemSelected().
Is there a way to access the application resources from library project ? I'd like to write something like this, which is currently impossible, since menu items are not visible from the library:
if ( item.getItemId()==R.id.settings ) {
...
}
Yes you can if you know the package name of your library. See: Resources#getIdentifier
You can do:
getResources().getIdentifier("res_name", "res_type", "com.library.package");
ex:
R.id.settings would be:
getResources().getIdentifier("settings", "id", "com.library.package");
You should really just include a version of the menu.xml resource in your library project. If you want to have a different menu.xml in your application, you can do that and it will override the copy from the library project.
From the Library Projects docs:
In cases where a resource ID is defined in both the application and the library, the tools ensure that the resource declared in the application gets priority and that the resource in the library project is not compiled into the application .apk. This gives your application the flexibility to either use or redefine any resource behaviors or values that are defined in any library.
I found #triad's solution with Resources.getIdentifier(String, String, String) to be somewhat error-prone:
the String-literal resource identifiers aren't checked by the IDE
multiple sequential String arguments to a single method are easy to use incorrectly.
I found this approach to work better for me:
String libString = context.getString(example.library.pkg.R.string.library_string)
Where the library's package is example.library.pkg.
The library's R class is resolved at compile-time, so your IDE will tell you if you referenced it correctly
Not importing the library's R class allows you to still use your own local R later,
and explicitly marking the external resource usages makes them easier to spot.

Categories

Resources