I am developing an Android app for connecting to Tridion 2011 SP1 Core Service. So far I have created Android WS Stubs from the core service wsdl using wsclient.
Imported those stubs, which allow access to all the core service methods.
I can now authenticate to Tridion via the Android application but as soon as I try to perform even the most basic of web service calls, such as getApiVersion()
, I get the error:
ReflectionHelper*java.lang.NoSuchFieldException: GetApiVersionResult.
I was wondering has anyone else managed to create a java android app that communicates with the Core Service?
Interestingly enough, if I run the code as a java application, using wsimport stubs everything works a treat.
Any help appreciated. For reference here is a code snippet:
To connect to Tridion:
class TridionConnect extends AsyncTask<String, Integer, String> {
// Called to initiate the background activity
@Override
protected String doInBackground(String... statuses) {
try {
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("username", "password".toCharArray());
}
});
url = new URL("http://tridion-server/webservices/CoreService2011.svc?wsdl");
System.out.println(String.format("Get Service"));
service = new CoreService2011();
System.out.println(String.format("Get Client"));
client = service.getBasicHttp();
return "Authenticated To Tridion";
} catch (Exception e) {
Log.e("Authentication failure", e.toString());
e.printStackTrace();
return "Failed to authenticate";
}
}
// Called when there's a status to be updated
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
// Not used in this case
}
// Called once the background activity has completed
@Override
protected void onPostExecute(String result) { //
Toast.makeText(FullscreenActivity.this, result, Toast.LENGTH_LONG).show();
area.setText("Authenticated to Tridion OK");
}
}
To get the ApiVersion
client.getApiVersion();
UserData currentUser = client.getCurrentUser();
System.out.println(String.format("'%s' %s", currentUser.getTitle(), currentUser.getId()));
Frank,
It is not possible for a couple of reasons.
If you use wsimport to create the coreservice proxy it will use the javax library, which exists in the JRE. However Dalvik implements only a subset of the javax library which means this approach is impossible in the Android environment.
I then looked at Ksoap2 tools for creating the proxy. This seemed to work OK, in as much as it did create a proxy, however it did not match the coreservice so I was unable to authenticate. I didn't get any further with this approach beyond examining the JRE proxy v Ksoap2 proxy. They were quite different.
At this point I took a step back, had a cup of tea and re-engineered the approach.
I created a c# REST service to sit between the android app and the core service.
This approach seemed a bit complex, but it offers lots of advantages. Lots of the spade work can be done in the REST service, which will be much quicker than similar code on a tablet or phone.
Secondly the REST service sits on the same server as the CMS/CoreService so the comms is quicker and you can make the REST requests from the android app much lighter.
I have got the application to the point where you can authenticate to Tridion, select a publication, and components that is then rendered in a dynamic layout ready for update/save/publish.
The one big downside of this approach is that the REST service 'should' be stateless so superficially you have to authenticate to the coreservice for every request. Of course I don't do that, but you have to come up with some alternative approach Oauth, shared secret etc.
In initial tests this approach has seemed to be fairly slick on an android device.