Getting started:
- Download source and put it to your workspace.
- Download
ActionBarSherlock, unzip and create new project(ActionBarSherlock) from "library" folder.
- Import both projects(from library and sample folder) to Eclipse.
- Remove ActionBarSherlock library dependency and add it again but with pointing to project create in 2..
- Start ListSyncSample on device or emulator.
- Play with sample app,
HTML5 or/and Silverlight
Adding SyncFramework to own project:
- Create project (in this tutorial we will named it "Project" and pakage will be "com.example.Project"
- Add SyncFramework as referenced library:
- SyncFramework should be oppened as project in Eclipse.
- Click right click on your Project select "Properties" then "Android" then "Add.." button.
- Select SyncFramework Project and click Add button.
- Add:
<provider android:name=".YourProviderClass" android:authorities="com.example.Project.Authority" />
in your AndroidManifest.xml - Add YourProviderClass.class:
package com.example.Project;
import pl.selvin.android.syncframework.content.BaseContentProvider;
public class YourProviderClass extends BaseContentProvider {
}
- Add your database definition class - DatabaseClass.java:
package com.example.Project;
import pl.selvin.android.syncframework.ColumnType;
import pl.selvin.android.syncframework.anotation.Column;
import pl.selvin.android.syncframework.anotation.Table;
import pl.selvin.android.syncframework.anotation.TableName;
public class DatabaseClass {
static final String ScopeName = "DefaultScope";
@Table(primary_key = MyTable.ID, scope = ScopeName)
public static interface MyTable {
@TableName
public static final String TABLE_NAME = "MyTable";
@Column
public static final String ID = TABLE_NAME + "_ID";
/*
* global name in yoursyncdef.config file should be TABLE_NAME + "_ID"
* (MyTable_ID)
*/
@Column(type = ColumnType.varchar, extras = Column.COLLATE)
public static final String Name = TABLE_NAME + "_Name";
/*
* global name in yoursyncdef.config file should be TABLE_NAME + "_Name"
* (MyTable_Name)
*/
@Column(type = ColumnType.varchar, extras = Column.COLLATE)
public static final String Description = TABLE_NAME + "_Description";
/*
* global name in yoursyncdef.config file should be TABLE_NAME +
* "_Description" (MyTable_Description)
*/
/*
* sample computed Column ... it will be not created in db but you can
* use it in query
*/
@Column(type = ColumnType.varchar, computed = "LTRIM(RTRIM(" + Name
+ " || ' ' || " + Description + "))")
public static final String NameAndDescription = TABLE_NAME
+ "_NameAndDescription";
/* other columns goes here */
}
}
- Now you (have to) must add Setup.class ... but it should be in pl.selvin.android.syncframework pakage becouse SyncFramework will search for this class:
package pl.selvin.android.syncframework;
import org.apache.http.impl.client.DefaultHttpClient;
import com.example.Project.DatabaseClass;
import android.content.Context;
public class Setup implements SetupInterface {
public final static String DATABASE_NAME = "your_database_name";
public final static int DATABASE_VERSION = 3;
@Override
public String getServiceUrl() {
return "http://example.com/";
}
@Override
public String getAuthority() {
return "com.example.Project.Authority";
}
@Override
public Class<?> getDatabaseClass() {
return DatabaseClass.class;
}
@Override
public String getDatabaseName() {
return DATABASE_NAME;
}
@Override
public int getDatabaseVersion() {
return DATABASE_VERSION;
}
@Override
public HttpClientPolicy getHttpClientPolicy() {
return HttpClientPolicy.Default;
}
@Override
public DefaultHttpClient getHttpClient(Context context) {
return null;
/*
* it will be used if you wana add some pre/post processing of headers
* (fx for authentication)
*/
}
}
- Thats all folks!
Simple usage of SyncFramework library
- How to do sync - just call:
/*
* for example: service name is "Service.svc" and scope is
* "DefaultScope" scope has parameter named "template_param"
*/
Uri uri = YourProviderClass.getSyncUri("Service", "DefaultScope");
getContentResolver().update(uri, null, "?template_param=value", null);
- What Uris are generated ...
- "content://" + AUTHORITY + "/" + TABLE_NAME ---- all rows from TABLE_NAME with type:
ContentResolver.CURSOR_DIR_BASE_TYPE + "." + AUTHORITY + "." + TABLE_SCOPE + "." + TABLE_NAME
you can get this uri by calling
YourProviderClass.getDirUri(DatabaseClass.MyTable.TABLE_NAME)
- "content://" + AUTHORITY + "/" + TABLENAME + "/ROWID/" + ROWID ---- item with "ROWID" = ROWID
ContentResolver.CURSOR_ITEM_BASE_TYPE + "." + AUTHORITY + "." + TABLE_SCOPE + "." + TABLE_NAME
you can get this uri by calling
YourProviderClass.getItemUri(DatabaseClass.MyTable.TABLE_NAME, some_long_rowid)
- "content://" + AUTHORITY + "/" + TABLENAME + "/PK1_SEARCH_VALUE/" + "/PK2_SEARCH_VALUE/" + ... + "/PKN_SEARCH_VALUE/"---- item with "PK1" = PK1_SEARCH_VALUE and ...
ContentResolver.CURSOR_ITEM_BASE_TYPE + "." + AUTHORITY + "." + TABLE_SCOPE + "." + TABLE_NAME
you can get this uri by calling
YourProviderClass.getItemUri(DatabaseClass.MyTable.TABLE_NAME,PK1_SEARCH_VALUE,PK2_SEARCH_VALUE, ... PKN_SEARCH_VALUE)
if there is only 1 PK and its integer it acts in the same way was version with ROWID