Android WebService Core + example App ZerlinaContacts

546 views
Skip to first unread message

Jan Thielemann

unread,
Jul 21, 2014, 5:45:30 AM7/21/14
to idem...@googlegroups.com
Hey guys,
as some of you might know, i am currently working on my bachelor thesis. I created a prototype Android App to display business partners and their locations/contacts.

If you are also interested in developing mobile apps for iDempiere, you should definately take a look at the WebService Library we created. Heres the code:

https://bitbucket.org/evenos-consulting/org.evenos.android.webservicecoretest (iDempiere Plug-in for the WebService Core JUnit Tests)
https://bitbucket.org/evenos-consulting/org.evenos.android.activeandroid-sqlcipher (ActiveAndroid implementation which uses SQLCipher)

To get the code running, you need to install the iDempiere Plug-in for ZerlinaContacts on your server. Then run the ZerlinaContacts App with your Android Phone. To get the App running, you need the Eclipse ADT (may be found here). Then you import the App, the WebService Core Library and the ActiveAndroid-SQLCipher Library into your workspace. You may need to fix the project settings by rightclicking the project and chosing "properties". Then go to the Android section and/or the build path to fix the settings. It shouldn't be so hard. You also may need to create a clean new library projects and add it to all the other projects because in my workspace i have a project calles "SupportLibrary" which only contains the "android-support-v4.jar" in it's libs folder so all other projects use the same jar.


Here's how you can query the WebService. First you create an instance of WebServiceClient. Then you create your login request and call on of the clients execute methods:
WebServiceClient client = new WebServiceClient();
client.setEndpointAddress("http://192.168.0.51:8080");
ADLoginRequest loginRequest = new ADLoginRequest("WebService", "WebService", "192", "11", "50004", "11", "103", "0");
client.setADLoginRequest(loginRequest);
ModelCRUD modelCRUD = new ModelCRUD("getBPartners");
client.executeQuery(modelCRUD, new SOAP11ListObserver<DataRow>() {
@Override
public void onException(Request<List<DataRow>, SOAP11Fault> arg0, SOAPException arg1) {
//Whenever a failure occurres, this method gets called
}
@Override
public void onCompletion(Request<List<DataRow>, SOAP11Fault> arg0) {
//When all DataRows are processed, this method gets called
}
@Override
public void onNewItem(Request<List<DataRow>, SOAP11Fault> arg0, DataRow arg1) {
//For each DataRow in the response, this method gets called
}
});

There are two kinds of observers you can use. A normal observer will give you one response in the onCompletion() method (e. g. in setDocAction). A list observer will call the onNewItem() method everytime a list-entry is processed (e. g. in queryData). Take a look at the WebService Core Android JUnit Test project for more examples.

In my App, i have some security. The first time it is started, the user has to protect the app with a password. This password is used to encrypt a generated key for the database. When the user changes the password, the key is reencrypted which is less time consuming than reencrypting the whole database. For databaseencryption, SQLCipher is used (which uses AES 265 if i remember right). Thats the reason why i had to modify ActiveAndroid a little bit so it can make use of SQLCipher. 

ActiveAndroid is an active record style object relational mapper. I used this because i didn't want to reinvent the wheel and bring the PO to android. Model tables can be easily created:
@Table(name = "AD_User")
public class MUser extends Model {

@Column(name = "AD_User_ID")
public String AD_User_ID;
@Column(name = "C_BPartner_ID")
public String C_BPartner_ID;
@Column(name = "Fax")
public String Fax;
@Column(name = "Phone")
public String Phone;
@Column(name = "Phone2")
public String Phone2;
@Column(name = "EMail")
public String EMail;
@Column(name = "Name")
public String Name;

public MUser() {
}
}

And manipulating the database is also very easy:
MUser m_user = new Select().from(MUser.class).where("AD_User_ID = ?", ad_user_id).executeSingle();
m_user.Name = "Test";
m_user.save();
new Delete().from(MBPartnerLocation.class).where("C_BPartner_Location_ID NOT IN (" + ids.toString() + ")").execute();


Please try the App out and tell me what you think. Every feedback is welcome and if you have problems or questions then just ask me here or on irc.

Jan Thielemann

unread,
Jul 21, 2014, 5:46:51 AM7/21/14
to idem...@googlegroups.com
Here's the Plug-in
Here's the apk

Jan Thielemann

unread,
Jul 21, 2014, 8:35:00 AM7/21/14
to idem...@googlegroups.com

I forgot to mention that after installing the iDempiere Plug-in, you need to run the process which comes with the plugin. I reccomend you to run it for Client 11 and Org 0 so you can use the WebService user from GardenWorld for testing the App. Also in a default installation, there are no contacts in your business partners so i suggest that you create new contacts to see the full power of the app. Here are also some screenshots of the App running on an Asus Memo Pad FHD 10:



Alex Yang

unread,
Sep 3, 2014, 3:04:40 AM9/3/14
to idem...@googlegroups.com
Hi Jan,

Your code can't compile. Here is the problem for class: BPartnerEntryAdapter.java

Could you kindly check?

Thanks,
Alex Yang

Carlos Antonio Ruiz Gomez

unread,
Sep 3, 2014, 8:46:13 AM9/3/14
to idem...@googlegroups.com
Hi, during my stay in Germany working with Thomas we were able to compile and run this contribution from Jan.

Thanks a lot Jan, we found it as a good framework to start any related app, the libraries you chose make the code very clean and easy to understand/maintain.

Alex, please note the prerequisites that Jan mentioned in the post, they are preinstalled but maybe you need to do some setup:
the project must be linked to
org.evenos.android.activeandroid-sqlcipher
org.evenos.android.webservicecore

In the project org.evenos.android.activeandroid-sqlcipher you need to include in the classpath android-support-v4.jar which is included in my case in the folder adt-bundle-linux/sdk/extras/android/support/v4

The problem we struggled a lot was about the included androidannotations-api-3.0.1.jar
The version of ADT that we downloaded (the latest at that moment 23.0.21259578) had a problem and was not able to process the annotations - this seems similar to the problem you're reporting.
The workaround at that time was to install the annotations processor directly from eclipse update, but I think probably is now solved if you install the latest ADT.

Regards,

Carlos Ruiz



On 03/09/14 a las 02:04, Alex Yang wrote:
Hi Jan,

Your code can't compile. Here is the problem for class: BPartnerEntryAdapter.java


Carlos Antonio Ruiz Gomez

unread,
Sep 3, 2014, 9:00:00 AM9/3/14
to idem...@googlegroups.com
Ah!  two more things, Jan's implementation is totally clean, it uses the iDempiere webservice layer without any modification, so, in principle is not needed to install the server plugin to make it work.

The server plugin creates a process that creates the configuration for webservices on the current tenant:
@Jan, we found a minor typo, here I'm attaching the patch.

But, also we tried instead of installing the plugin you can just configure the webservices importing a 2pack that I'm attaching here also.
After importing you need to set up the webservice access roles for testing.
[ NOTE: here we found the 2pack issue about importing Garden roles into a different tenant, this is being solved at https://idempiere.atlassian.net/browse/IDEMPIERE-2137 ]

Regards,

Carlos Ruiz
WebServiceTypes.zip
typoZerlinaProcess.patch

Alex Yang

unread,
Sep 3, 2014, 12:12:10 PM9/3/14
to idem...@googlegroups.com
Thanks Carlos for your detail reply.

I have tried again and reviewed the all the steps you and Jan wrote down. But still no luck.
I noticed the code from bitbucket and see it do have problems in code. Please see below screen shot for the tip:

Could you kindly check the code once more? :)

Thanks,
Alex Yang

On Monday, July 21, 2014 2:45:30 AM UTC-7, Jan Thielemann wrote:

Alex Yang

unread,
Sep 3, 2014, 9:58:23 PM9/3/14
to idem...@googlegroups.com
Hi Carlos,

The code problem is in these adapter classes: BPartnerEntryAdapter.java and BPartnerListAdapter.java.

There is no View.build() method. I just want to confirm there is missing any source files or just a typo?

Thanks,
Alex Yang

Alex Yang

unread,
Sep 4, 2014, 3:58:32 AM9/4/14
to idem...@googlegroups.com
Hi Carlos and Jan,

It's the problem of Google ADT buddle. I have installed the latest ADT version. The annotation works then the compile error gone!

Thanks,
Alex Yang

Jan Thielemann

unread,
Sep 4, 2014, 5:09:43 AM9/4/14
to idem...@googlegroups.com
Not my fault :D

@Carlos: The Process which is installed should take the target client and organization as parameters so it creats the webservices for this client/org. I chose this way because with 2Pack you only can pack in the webservices on a given client and if you have your own client it would not work.

Carlos Antonio Ruiz Gomez

unread,
Sep 4, 2014, 9:29:41 AM9/4/14
to idem...@googlegroups.com
Jan, with this ticket
https://idempiere.atlassian.net/browse/IDEMPIERE-1298
2Pack is able to move things between tenants.

Regards,

Carlos Ruiz
Message has been deleted

Flemming Birch

unread,
Sep 9, 2014, 5:36:12 PM9/9/14
to idem...@googlegroups.com

Hi

This does indeed look good! I’m just having difficulties to figure out what is the difference between this Android app and the SFAndroid app?

/Flemming

Jan Thielemann

unread,
Oct 2, 2014, 6:58:03 AM10/2/14
to idem...@googlegroups.com
The App is more a showcase than a real productive app. It shows how you can use the webservice library to get information from idempiere. SFAndroid, if i understand it right, is some kind of idempiere port for android which has an build in application dictionary.

midvide...@gmail.com

unread,
Apr 5, 2016, 5:19:26 AM4/5/16
to iDempiere
Hi Jan,

Really appreciable and easy to maintain app, many thanks to the explanation and code comments, i have just a small problem, every time i try to pull the database (Password.db or Zerlina.db) from the emulator to read it from DB Browser i get the message bellow, might i miss something ?


Reply all
Reply to author
Forward
0 new messages