Android & jar file compatibility - android

How does one find out if a jar is Android compatible, meaning it does not contain imports from class not contained in Android.jar?
I'm trying to build a app that uses the MySQL J connector thingy (and YES, I know about SQLite's existence, but i need the MySQL thingy to work - for remote querying) and when i add the external jar, i get:
Conversion to Dalvik format failed with error 1
I've done my Googling and found this article:
http://bimbim.in/post/2010/09/24/Reason-of-Conversion-to-dalvik-format-failed-with-error-1.aspx
which states, as most answers given on stackoverflow on similar problems that i should: remove all jars, clean project, fix-project-properties.
Did this, but problem persist so I'm assuming that somewhere in this jar there is a class that uses an import that android.jar's java doesn't contain... but i could be wrong, i usually am.
So... Anyone?

It is not possible to use the MySQL connector in Android. You need to create a layer on the server that is hosting your MySQL.
I read about the reason why Android and MySQL can't directly talk to each other, but of course I can't find the post, so you'll have to do with my answer :P
Check out this tutorial out on how to use a php script to process MySQL tables to JSon:
http://www.helloandroid.com/tutorials/connecting-mysql-database

The source code is included with the MySQL J connector download. Is it possible to use the source and build and compile java code for Android?

Try building the project from the command line.
(assuming you have ant, and the android tool that comes with the sdk is in your path)
android update project -p . -t android-10
ant debug
(use whatever android target level your project needs, for the -t option)
If this succeeds, then your problem has something to do with eclipse, not a problem with the jar you are using. And if it fails, it will likely give you a more helpful message than "Conversion to Dalvik format failed".

Related

gradlew appengineEndpointsInstallClientLibs does not install client libs (but does generate them)

I am working on an android project working in Android Studio (0.5.3).
I have created two endpoint api classes (called UserEndpoint and OfferEndpoint) in the backend part of the project. Then I wanted to create the client libraries to use in the app part of the project. I use the gradlew appengineEndpointsInstallClientLibs command for this. In the /build/client-libs part it did create the .zip files of the client libraries. But it did not install them in the app part of the project.
So now my question:
Is the command I am using (gradlew appengineEndpointsInstallClientLibs) supposed to also install them in the app part, and if yes what could be the reason it is not working for me (there seem to be no errors).
This tutorial mentions that I have to manually add the libraries. I added the .zip files to the /libs folder, but there is no 'add as library' option as the tutorial mentions. Is this the correct way of doing this? And if yes could someone give me a little more in detail explanation because I tried some things by adding the dependency in the build.gradle file but nothing seems to work.
Thanks in advance!
By default, if you don't use #ApiNamespace, the namespace that is used
is the reverse of your-project-id.appspot.com. That is, the package
path will be com.appspot.your-project-id.yourApi.
Source
The annotation was missing in the #Api annotations of the endpoints.

java servlet project and android library project in eclipse - NoClassDefFoundError

I have some projects in my workspace :
AndroidMonitoring # an android application
MonitoringModel # an android library project
DataServlet # servlet project
AndroidMonitoring (which depends on MonitoringModel,
)
compiles and runs just fine but I need the MonitoringModel classes to be available also in the DataServlet project. I added the Model as a dependency in the Java Build path of the DataServlet project but I get :
java.lang.NoClassDefFoundError: gr/uoa/di/monitoring/model/Battery
gr.uoa.di.monitoring.server.servlets.DataCollectionServlet.doGet(DataCollectionServlet.java:20)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
I need the Model to be an Android library project as it contains android classes - but also contains the methods to parse the files in the servlet - is it possible ? How should I set this up ?
EDIT : MonitoringModel is here
Solved !
remove the dependency from DataServlet's java build path
go to the MonitoringModel project and remove the library attribute, run it as an Android app remake it into a library (from here) Clean the MonitoringModel project
grab the monitoringmodel.jar from bin/ and drop it into the DataServlet/WEB-INF/lib
refresh and run on server
done !
Will try and improve on this hack (linking to an external jar did not seem to work btw) - any better ideas will be accepted as an answer - however closing this for now.
EDIT : apparently step 3. can be substituted by creating a hard link from DataServlet/WEB-INF/lib/monitoringmodel.jar to monitoringmodel.jar - still testing this as some action sequences break the link methinks. Symbolic links do not seem to work though - reported this as a bug
EDIT2 : the steps below seem to work too - but I leave the manual procedure as it definitely works
remove the dependency from DataServlet's java build path
Hard link the monitoringmodel.jar from bin/ and to the DataServlet/WEB-INF/lib. I used shell link extension but this :
mklink /H c:\path\to\WebContent\WEB-INF\lib\monitoringmodel.jar c:\path\to\bin\monitoringmodel.jar
should also work
Now everytime you make a change in monitoring model the jar is updated. You only have to refresh the servlet project (will be redeployed on server on its own by default)
Clarification : of course the servlet project is not meant to use android.* classes - this was not my issue - my issue was to have the model code in one place and this place had to be an android library
First of all - I believe Java Web Project will not work with any of Android specific classes due to many reasons.
If your MonitoringModel contains some Java code that you want to share between Android and Web application you can extract it to separate Java project and use a Link Source option in Properties->Build Path to link it to both projects.

android aapt in eclipse

i saw some info regarding this question in several threads but non suited my condition.
I have an android application which i now need to customized some resources and code.
For the time being i have some problems using android library so i have an ant build that copies base resources and Assets plus specific ones to my android project and than changes the package name in the manifest as needed. All my activity have constant path and non relative to the package name so that's not an issue.
The problem is with the R object in the gen folder that is generated in the aapt. aapt does have a parameter to not use the android manifest package but another one, but it's available only if i use the ant build file, the parameters for the ADT are hard coded in the plugin.
has anyone found solution to this ? i mean i can always use ant task to change all R references (imports) but it looks to me error prone. Any way except wrapper script that wont do it on windows to customize aapt ?
again... no answer for my question, i'll start thinking you guys got something against me.
in short, i see there's no solution, the things i can do:
use ant task that regexps all the import com....R; to the new package - disadvantage: even the smallest issue with the regexp i may mess something up in the code that will show only in runtime.
use wrapper script around aapt.exe or aapt binary that adds --custom-package my.package.name that even if i change the manifest package will keep the original R files, for both ant and eclipse - disadvantage, some: 1. on windows this needs to be an exec file as eclipse looks for one it took me a while to build one properly in C, on linux\mac this could be a script of any kind so we need 2 versions of it\ 2. every update to the SDK we need to install the wrapper all over again.
edit the ant tasks jar code to allow --custom-package and edit the adt source code to enable in the menu custom parameters - this is great feature that should be included! but the disadvantage is until the code is accepted (if it is accepted) and added to the SDK itself , i'll needs to merge my changes every new SDK emerges, unlike #2 this is a lot harder.
I chose option #2, for now i have executable for windows, and i'll check options for Linux and mac (probably simple bash script) once i'm there, and i'll create a python installation script and save it all in the svn along with my build project.
Good luck to everyone....

How do I build the Android SDK with hidden and internal APIs available?

I want to rebuild the Android SDK (or rather only the android.jar) to include hidden and internal APIs.
I could not find any documentation or discussion doing on how to go about this. I have an Ubuntu CyanogenMod build environment already setup that is able to build cm7.
Now, I read that make SDK will build the SDK but I want to build an SDK that includes methods and fields that are marked as hidden using #hide. Is this possible?
What I want to do is make changes to an application that uses hidden API and in order to rebuild it I would like to use the modified SDK.
This is what I always do to use hidden api.
Build the repo or download jars from https://sites.google.com/site/hippunosource/home/android/androidnohide-apiwo-shi-yongsuru-rifurekushonha-wei-shi-yong
copy out out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar (better to rename it as something like framework_all.jar)
config your project build path-->libraries --> add this external jars. In Order and Export, move it up and before android.jar
I have done some investigating into this, and my conclusion is simply: This cannot be done without quite a bit of work. Read the rest of this answer for details on what I have found.
android.jar is actually comprised of the "public api" of framework.jar and core.jar which is found in system/frameworks/ on the device. android.jar is a kind of what I would call Java library header, all implementation in the actual byte code are just a throw new RuntimeException("stub");, this allows you to build against android.jar (e.g. in Eclipse), but execution has to be performed on a device or emulator.
The public API of the Android SDK is defined by classes/methods/fields that are not prefixed with the #{hide} javadoc annotation. I.e. everything that is not annotated is included in the SDK.
android.jar is built from the sources located in out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates which itself is generated by the tool DroidDoc located in build/tools/droiddoc.
DroidDoc is the tool (probably adapted from javadoc, or using javadoc) that generate the actual Android SDK documentation. As a side-effect, and probably because it is already parsing all the javadoc, it also spews out the android stubs which are then compiled into the android.jar which is distributed in the SDK.
So to include the stuff that is hidden you could, if you only want to include specific parts, just remove the #hide annotation and rebuild the SDK.
However if you want to include all the hidden parts things get a lot more complicated. You can modify DroidDoc (the relevant source is in build/tools/droiddoc/src/Stubs.java) such that nothing is detected as hidden. This is quite trivial and I have tried this, however the stubs that is then generated does not compile at all.
My conclusion by now is that this is simply not feasible. The stubs generated if you remove the part of DroidDoc that detect hidden annotations, is simply not compilable, and would require quite a bit of work to compile correctly.
So my answer to your questions is: No, this cannot be done, without doing a lot of work. Sorry.
A side note about the mkstubs tool. mkstubs are used when you build a SDK addon, i.e. the addons you can find in the Android SDK manager from vendors, e.g. Samsung providing you with an additional API for stuff specific to Samsung phones. mkstubs does much the same as the DroidDoc stubs generation process, however it does not use #hide annotations, it uses a .defs file describing which packages/classes/fields to include or exclude from your SDK addon.
However this is all irrelevant to the question, as the Android SDK build does not use the mkstubs tool. (Unfortunately.)
We could reconstruct the *.jar files from the Android platform.
First, connect ADB to your device. Then run:
adb pull /system/framework/core.jar .
adb pull /system/framework/framework.jar .
The core.jar contain the standard Java libraries (java.*) and the framework.jar contain the Android libraries (android.*). This is not usable yet, as the actual files are in DEX format, not JAR format.
We could convert these DEX-formatted *.jars into real JARs using tools such as dex2jar:
dex2jar core.jar
dex2jar framework.jar
Then pull in these jars using "Add External JARs..." (assuming you're using Eclipse ADT)
right click on Project → Properties → Java Build Path → Libraries → Add External JARs... → (Choose the core-dex2jar.jar and framework-dex2jar.jar from above).
This will enable you to use the internal and some Java 7 APIs. (The generated APK, as far as I can see, does not contain any actual code from the JARs.)
You can download the modified android.jar to be used as hidden APIs from this repository. Follow the instructions there.
For Lollipop the flow is little different:
Get /system/framework/arm/boot.oat from lollipop device
Use 'java -jar oat2dex.jar boot boot.oat'
You will get two folders: dex and odex. Go to dex and make 'java -jar dex2jar.jar framework.dex'
Rename resulting framework.jar to .zip, extract and find classes you need
Go to [sdk_path]/platforms/[target_platform] and extract android.jar (first rename it to zip).
Copy files from extracted framework to extracted android.jar. Then compress to zip and rename to .jar :)
ps: probably you need repeat steps 4-6 for 'framework_classes2.dex'
DroidCon 2011
Here Erik Hellman from Sony Ericson explains how to access the hidden Android API's:
http://vimeo.com/30180393
(Hmm link doesn't appear to work).
Goto the DroidCon webpage Day 2 scroll down to Using Hidden APIs 10:15 and you can watch it there.
Links are dieing!
I've found this one: http://skillsmatter.com/podcast/os-mobile-server/hidden-api I don't know, how long it'll be up.
The official APIs in the Android SDK is usually sufficient for most normal applications. However, there are sometimes situations where a developer needs access to the internal system services, APIs and resources that are not published in the official APIs. Fortunately, these APIs are still available through some clever tricks and can often be useful when developing new and innovative solution on top of Android. In this session you will learn how to access and use these hidden and protected APIs, the limitations of their usage and some tips'n'trick on how to use them in a safe and control manner across multiple vendors devices and Android versions. The audience will see several advanced demos that you normally cannot do with Android. Expect a fairly advanced session with lots of insights in the internals of the Android platform.
Try to look at this:
The ultimate target of these articles is to give developers the power of Internal and Hidden APIs without using reflection. If you complete all the steps described in next several parts you will be able to use Internal and Hidden APIs as if they were public open APIs. There will be no need for reflection.
But if you’re using these non-public APIs then you should be aware that your application is at great risk. Basically there are no guarantees that APIs will not be broken with next update to Android OS. There are even no guarantees about consistent behavior across devices from different vendors. You are completely on your own.
There are three scenarios you may want to follow:
Enable both internal and hidden APIs (scenario A)
Enable only hidden API (scenario B)
Enable only internal API (scenario C)
Scenario A is a sum of B and C. Scenario B is the easiest one (requires no eclipse ADT plugin modifications).
Scenario A: read parts 1, 2, 3, 4, 5
Scenario B: read parts 1, 2, 3, 5
Scenario C: read parts 1, 2, 3, 4, 5
I once wrote some Groovy scripts for extracting the java files from a repo checkout from http://source.android.com/ and then compiling them without the need for a full toolchain for compiling all the android sources, including the needed other steps (packaging, generating resources etc).
They can be found here:
https://github.com/thoutbeckers/CollectAndroid
But for sure this will need updating for anything after Gingerbread, mostly by setting the correct directories in "rootdirs" in the config file (CollectConfig.groovy).
At the time I regularly used this for development with all of the hidden API and sources (also problematic at the time) available.
As mentioned elsewhere com/android/internal/** will still be hidden in recent versions of ADT due to the access rule aded.
Long's answer worked for me, but I was still missing some classes I needed, in particular android.provider.Telephony. I was able to add it like this:
Extract the framework.jar file
mkdir /tmp/framework
cp framework.jar /tmp
cd /tmp/framework
jar xvf ../framework.jar
mv android classes
Build the Android repo, which will create the out/target/common/obj/JAVA_LIBRARIES directory
Find where the missing classes are
$ cd /path/to/out/target/common/obj/JAVA_LIBRARIES
$ find . | grep "/Telephony.class"
./telephony-common_intermediates/classes/android/provider/Telephony.class
./android_stubs_current_intermediates/classes/android/provider/Telephony.class
Add the new classes and rebuild the framework JAR file
cd /tmp/framework
cp -r /path/to/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes .
cp -r /path/to/out/target/common/obj/JAVA_LIBRARIES/telephony-common_intermediates/classes .
cd classes
jar cvf ../framework.jar .
Or you can just be lazy and include all of the classes into one giant jar file:
cd /tmp/framework
cp -r /path/to/out/target/common/obj/JAVA_LIBRARIES/*/classes .
cd classes
jar cvf ../framework.jar .
I can't comment but this is basically a comment to #KennyTM's (https://stackoverflow.com/a/13550030/2923406) excellent answer:
If you find yourself with the following error in Eclipse:
The type com.android.internal.util.Predicate cannot be resolved. It is indirectly referenced from required .class files
(that is, android.internal.* is not available)
Then one possible solution is to apply the same method for /system/framework/framework2.jar. Using the Android Emulator for SDK19 I have this extra jar. On my HTC One there is even a framework3.jar.

ANTLR and Android

is there any guide how to use ANTLR on Android? I have found some ANTLR portation for Android but it looks like being without any tutorial or manual. Do you know where to find some? (and yes, I have been googling...)
Thx
After reading the README from this ANTLR port:
AntlrJavaRuntime - Earlence Fernandes, The CRePE Project, VU Amsterdam
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The Runtime is available as an external library against which apps can link.
It provides the necessary mechanisms to execute Lexer/Parser code generated by the ANTLR tool.
The model is offline, in the sense that the parser/lexer is generated off the mobile phone on a desktop computer.
The resulting files are transferred to an Android project which then uses this library.
Building
~~~~~~~~
lunch the appropriate target
make AntlrJavaRuntime
verify that AntlrJavaRuntime.xml was placed in /system/etc/permissions and AntlrJavaRuntime.jar was placed in /system/framework
after this, you can run a normal make
It seems to me that the only difference is when you want to run your parser on an Android device (or -emulator) you must include the AntlrJavaRuntime in your Android project/app.
So, writing the grammar, generating a parser and lexer from said grammar would be the same as on a "normal" machine. Here's a previous Q&A that shows how to write a simple expression parser: ANTLR: Is there a simple example?
EDIT
Also see this Q&A: android ANTLR make not working properly
I'm not sure what "using ANTLR" means to you. Here's what it means to me:
I'm assuming that you will create a grammar, generate the parser/lexer Java classes, compile them, deploy them in your Android app, and then let them parse whatever your app sends into an AST.
If you want to know how to do that, there's no better place than the ANTLR documentation or the book you can buy from Amazon.
There is an Android Studio (actually IntelliJ) plug-in for this, called "ANTLR v4 grammar plugin".
This tutorial worked for me.
In short, simply copy grammar (a .g4 file) into your project, right-click on it > Configure ANTLR...
From there you can select to generate Java or Kotlin files, which will compile and run once you added the runtime in your dependencies:
implementation 'org.antlr:antlr4-runtime:4.7'

Categories

Resources