I am writing my own SDK on android and as such creating my own jar.
Now I create documentation of my SDK using droiddoc tool.
In my framework files(.java), there are many APIs that I have marked with #hide
Now this is the current state:
a) all APIs marked with #hide are hidden in documentation.
b) These APIs marked hidden is INCLUDED in class files in generated jar file.(I use Java decompiler to check this).
Now when I include this jar in eclipse and use Ctrl+space on my class object to find its options, i can see that hidden APIs are actually visible and accessible here.
Am I missing anything here, and do I need to add any special flags in make file? Or is this a normal behaviour?
I found out that:
android.jar has all classes from com.android.internal removed, and all
classes, enums, fields and methods marked with #hide removed as well
So the classes with #hide are not included on jar -> that's why they are not accessible in eclipse.
Furthermore:
When you launch your application on device it loads framework.jar
(roughly this is equivalent of android.jar on the device) which is
uncut and has all the internal API classes and all hidden API
components.
Have a look over this post and this answer
Hope you find an alternative solution for hiding things
Related
Using AOSP we can build own Android with some features.
I have setup environment using google documentation and another web sites, and in tutorials says -
make adb fastboot. Update yours android OS with yours customization.
But i just need use #SystemApi classes for build one app, what i should to do?
I searched in web for one month, but still didn't find.
Methods marked as #hide or #SystemAPI are not part of the official SDK, and are not intended to be used generally.
Yet, until lately you could access all of them either by Reflection, or by using a custom android.jar that has those methods too. See this project for the list of android.jar: https://github.com/anggrayudi/android-hidden-api
If your Android version is below P, that's all you need to do. Otherwise keep reading:
In Android P, Google removed access to non-SDK interfaces, so you cannot use those methods as above. In this case you'd have to remove the #SystemApi and #hide annotations from the classes and methods you need, compile and flash the update to the device. Then you can use the above methods
I am writing an Android library. The vast majority of the interface in the lbirary supports Android API level 10 or above. Some functionality, though, requires a higher API level. For instance, part of the library requires API 18 for Bluetooth Low Energy.
For the sake of concreteness, let's say that the library produces three classes ClassA, ClassB and ClassC. ClassA uses functionality available in API 10, ClassB uses functionality available in API 14 and ClassC uses functionality available in API 18.
I want to be able to trigger a lint issue (warning/error) whenever someone uses a class from my library without having the required API level in their project (unless they suppress the warning with the appropriate annotation), similar to the already built-in NewApi issue used by lint.
After searching, I have found the following possible solutions:
1) This solution isn't along the lines of lint: Split the library into three .jar files, say lib_10.jar that includes all classes using functionality available in API 10 (ClassA in the example), lib_14.jar that includes all the classes using functionality available in API 14 (ClassB in the example) and lib_18.jar that includes all classes using functionality available in API 18 (ClassC in the example). This solution allows portability but would complicate the later maintainability of the codebase and would potentially require some code duplication as well.
2) Create my own annotation (say, #RequireAndroidApi(API_LEVEL) indicating the minimum API level required by the annotated class/method/etc...) and use the lint-api.jar (http://tools.android.com/tips/lint-custom-rules) to create a custom lint rules that check the usage of any annotated classes/methods/etc... with a lower API than required. Something that would later look like this:
#RequireAndroidApi(10)
Class ClassA {
}
#RequireAndroidApi(14)
Class ClassB {
}
#RequireAndroidApi(18)
Class ClassC {
}
The problem is that I couldn't find good documentation for the lint API and it seems that this is reinventing the wheel for a functionality that lint already supports (lint already checks for the "NewApi" issue).
3) Finally, I succeeded to edit <SDK>/platform-tools/api/api-versions.xml in order to indicate the API level required by each class as follows:
<api version="1">
...
<class name="package/path/ClassA" since="10">
<extends name="java/lang/Object" />
<method name="<init>()V" />
</class>
<class name="package/path/ClassB" since="14">
<extends name="java/lang/Object" />
<method name="<init>()V" />
</class>
<class name="package/path/ClassC" since="18">
<extends name="java/lang/Object" />
<method name="<init>()V" />
</class>
</api>
Which caused lint to trigger the NewApi issue in the same manner as it would with the Android APIs. I like this type of solution because it doesn't reinvent the wheel and further any errors thrown this way would utilize the suggested solutions programmed in Eclipse or Android Studio to deal with the problem (i.e. "quick fixes" in Eclipse). The problem with this solution is that it requires editing api-versions.xml that ships with the Android SDK, which makes this solution not very portable for releasing the library for several reasons including: a) the api-versions.xml file is not local to a project and changes the behavior of lint for all android projects, including the ones that do not use the library; and b) api-versions.xml will be overwritten every time the SDK is updated from the Android SDK manager which would overwrite any changes made.
I was wondering if there is a simpler solution to achieve this "minimum API errors/warnings" or if there is a way to write a separate file similar to api-versions.xml that can be placed in the project directory which can be read by lint whenever lint is ran on the project in question (something similar to lint.xml).
Thanks for bearing with me during this long description of the problem and I appreciate any help in advance.
There is no need to create your own annotation, the android support library's #RequiresApi annotation is what you are looking for. For example:
#RequiresApi(Build.VERSION_CODES.LOLLIPOP)
public void someMethod() {}
This annotation tells lint to warn if someMethod() is used in a context that may have a lower API level.
Note that #TargetApi is different: It's used to assure the linter that the annotated method will only be called with the targeted API, in a situation where it would otherwise warn you not to use that method. So #TargetApi can be used to silence the lint warning triggered by #RequiresApi.
I have recently done this on a custom view class, which needed special constructor for some api levels.
I have done it with the #TargetApi annotation.
If a method is available only since api level 16:
#TargetApi(16)
public void someMethod () {}
This should do the trick, including lint errors.
I am trying to use the class SntpClient that should be in the android.net package, but Android Studio is telling me it cannot find it. Indeed when I look through the source jars (of both API 19 and API 21), the class is not there. However according to grepcode it should be.
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4.4_r1/android/net/SntpClient.java
What am I doing wrong?
Google has chosen not to make all public classes available as part of the SDK. Visibility is controlled by the #hide comment tag as described here.
I'm not sure why they chose to hide SntpClient particularly, but provided you respect the terms of the Apache license you can copy the source into your application without much modification.
My application requires a method to be accessed from a class Trace.java, which is present in the package android.os.Trace. I have added the appropriate import statement in order to do this. But the build system shows an error mentioning that 'Trace class not found'.
But surprisingly the methods of some other classes in the same package, i.e. android.os are at all accessible. Would anyone address about this anomaly ?
Or is it due to limitations imposed on importing of this Trace.java class by android build system?
I am not using Android SDK but building the app directly along with along with JB source tree. The root directory of app has been put at the proper location in the android source tree.
Thanks in advance.
Check the sources of the class. If a method in the documentation has tag #hide then this method will be not included into SDK and, thus, will be not available for your application. However, I think you can call this method using reflection (if there is no security checks implemented for it).
Now I am doing an android project(Api level 8),I install JD-Eclipse(decompiler) to know the flow of program execution.The decompiled 'android.jar' contains full of abstract classes and interfaces, then where is the actual class containing the body to be executed? What is the name of that jar file?
You probably won't find what you are looking for. The android.jar is an API and as that not directly executable, there isn't even any guarantee that it contains such code.
If you want to start creating an application, just go to the developer page and start reading through the documentation on how to set up the development environment, how to program against the API, how to test your application and, finally, how to deploy it on an actual device.
The lifecycle of an activity for example can be found in the documentation.
Android.jar contains the Android API (Classes, interfaces, ..). If you want to see the rest, download the source from Android Git repository or via SDK Manager.