mirror of
https://github.com/nextcloud/notes-android.git
synced 2024-11-25 06:16:15 +03:00
speed-up synchronization (ETag and Last-Modified)
This commit is contained in:
parent
d6ac2cc6e6
commit
2e7ab5a857
5 changed files with 226 additions and 92 deletions
|
@ -39,6 +39,8 @@ public class SettingsActivity extends AppCompatActivity {
|
|||
public static final String SETTINGS_URL = "settingsUrl";
|
||||
public static final String SETTINGS_USERNAME = "settingsUsername";
|
||||
public static final String SETTINGS_PASSWORD = "settingsPassword";
|
||||
public static final String SETTINGS_KEY_ETAG = "notes_last_etag";
|
||||
public static final String SETTINGS_KEY_LAST_MODIFIED = "notes_last_modified";
|
||||
public static final String DEFAULT_SETTINGS = "";
|
||||
public static final int CREDENTIALS_CHANGED = 3;
|
||||
|
||||
|
@ -258,6 +260,8 @@ public class SettingsActivity extends AppCompatActivity {
|
|||
editor.putString(SETTINGS_URL, url);
|
||||
editor.putString(SETTINGS_USERNAME, username);
|
||||
editor.putString(SETTINGS_PASSWORD, password);
|
||||
editor.remove(SETTINGS_KEY_ETAG);
|
||||
editor.remove(SETTINGS_KEY_LAST_MODIFIED);
|
||||
editor.apply();
|
||||
|
||||
final Intent data = new Intent();
|
||||
|
|
|
@ -256,9 +256,9 @@ public class NoteSQLiteOpenHelper extends SQLiteOpenHelper {
|
|||
|
||||
public void debugPrintFullDB() {
|
||||
List<DBNote> notes = getNotesCustom("", new String[]{}, default_order);
|
||||
Log.d(getClass().getSimpleName(), "Full Database ("+notes.size()+" notes):");
|
||||
Log.v(getClass().getSimpleName(), "Full Database ("+notes.size()+" notes):");
|
||||
for (DBNote note : notes) {
|
||||
Log.d(getClass().getSimpleName(), " "+note);
|
||||
Log.v(getClass().getSimpleName(), " "+note);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ import it.niedermann.owncloud.notes.model.DBStatus;
|
|||
import it.niedermann.owncloud.notes.util.ICallback;
|
||||
import it.niedermann.owncloud.notes.util.NotesClient;
|
||||
import it.niedermann.owncloud.notes.util.NotesClientUtil.LoginStatus;
|
||||
import it.niedermann.owncloud.notes.util.ServerResponse;
|
||||
import it.niedermann.owncloud.notes.util.SupportUtil;
|
||||
|
||||
/**
|
||||
|
@ -218,7 +219,7 @@ public class NoteServerSyncHelper {
|
|||
@Override
|
||||
protected LoginStatus doInBackground(Void... voids) {
|
||||
client = createNotesClient(); // recreate NoteClients on every sync in case the connection settings was changed
|
||||
Log.d(getClass().getSimpleName(), "STARTING SYNCHRONIZATION");
|
||||
Log.i(getClass().getSimpleName(), "STARTING SYNCHRONIZATION");
|
||||
//dbHelper.debugPrintFullDB();
|
||||
LoginStatus status = LoginStatus.OK;
|
||||
pushLocalChanges();
|
||||
|
@ -226,7 +227,7 @@ public class NoteServerSyncHelper {
|
|||
status = pullRemoteChanges();
|
||||
}
|
||||
//dbHelper.debugPrintFullDB();
|
||||
Log.d(getClass().getSimpleName(), "SYNCHRONIZATION FINISHED");
|
||||
Log.i(getClass().getSimpleName(), "SYNCHRONIZATION FINISHED");
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -242,12 +243,12 @@ public class NoteServerSyncHelper {
|
|||
CloudNote remoteNote=null;
|
||||
switch(note.getStatus()) {
|
||||
case LOCAL_EDITED:
|
||||
Log.d(getClass().getSimpleName(), " ...create/edit");
|
||||
Log.v(getClass().getSimpleName(), " ...create/edit");
|
||||
// if note is not new, try to edit it.
|
||||
if (note.getRemoteId()>0) {
|
||||
Log.d(getClass().getSimpleName(), " ...try to edit");
|
||||
Log.v(getClass().getSimpleName(), " ...try to edit");
|
||||
try {
|
||||
remoteNote = client.editNote(customCertManager, note);
|
||||
remoteNote = client.editNote(customCertManager, note).getNote();
|
||||
} catch(FileNotFoundException e) {
|
||||
// Note does not exists anymore
|
||||
}
|
||||
|
@ -255,21 +256,21 @@ public class NoteServerSyncHelper {
|
|||
// However, the note may be deleted on the server meanwhile; or was never synchronized -> (re)create
|
||||
// Please note, thas dbHelper.updateNote() realizes an optimistic conflict resolution, which is required for parallel changes of this Note from the UI.
|
||||
if (remoteNote == null) {
|
||||
Log.d(getClass().getSimpleName(), " ...Note does not exist on server -> (re)create");
|
||||
remoteNote = client.createNote(customCertManager, note);
|
||||
Log.v(getClass().getSimpleName(), " ...Note does not exist on server -> (re)create");
|
||||
remoteNote = client.createNote(customCertManager, note).getNote();
|
||||
}
|
||||
dbHelper.updateNote(note.getId(), remoteNote, note);
|
||||
break;
|
||||
case LOCAL_DELETED:
|
||||
if(note.getRemoteId()>0) {
|
||||
Log.d(getClass().getSimpleName(), " ...delete (from server and local)");
|
||||
Log.v(getClass().getSimpleName(), " ...delete (from server and local)");
|
||||
try {
|
||||
client.deleteNote(customCertManager, note.getRemoteId());
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.d(getClass().getSimpleName(), " ...Note does not exist on server (anymore?) -> delete locally");
|
||||
Log.v(getClass().getSimpleName(), " ...Note does not exist on server (anymore?) -> delete locally");
|
||||
}
|
||||
} else {
|
||||
Log.d(getClass().getSimpleName(), " ...delete (only local, since it was not synchronized)");
|
||||
Log.v(getClass().getSimpleName(), " ...delete (only local, since it was not synchronized)");
|
||||
}
|
||||
// Please note, thas dbHelper.deleteNote() realizes an optimistic conflict resolution, which is required for parallel changes of this Note from the UI.
|
||||
dbHelper.deleteNote(note.getId(), DBStatus.LOCAL_DELETED);
|
||||
|
@ -289,20 +290,26 @@ public class NoteServerSyncHelper {
|
|||
*/
|
||||
private LoginStatus pullRemoteChanges() {
|
||||
Log.d(getClass().getSimpleName(), "pullRemoteChanges()");
|
||||
LoginStatus status = null;
|
||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(appContext);
|
||||
String lastETag = preferences.getString(SettingsActivity.SETTINGS_KEY_ETAG, null);
|
||||
long lastModified = preferences.getLong(SettingsActivity.SETTINGS_KEY_LAST_MODIFIED, 0);
|
||||
LoginStatus status;
|
||||
try {
|
||||
Map<Long, Long> idMap = dbHelper.getIdMap();
|
||||
List<CloudNote> remoteNotes = client.getNotes(customCertManager);
|
||||
ServerResponse.NotesResponse response = client.getNotes(customCertManager, lastModified, lastETag);
|
||||
List<CloudNote> remoteNotes = response.getNotes();
|
||||
Set<Long> remoteIDs = new HashSet<>();
|
||||
// pull remote changes: update or create each remote note
|
||||
for (CloudNote remoteNote : remoteNotes) {
|
||||
Log.d(getClass().getSimpleName(), " Process Remote Note: "+remoteNote);
|
||||
Log.v(getClass().getSimpleName(), " Process Remote Note: "+remoteNote);
|
||||
remoteIDs.add(remoteNote.getRemoteId());
|
||||
if(idMap.containsKey(remoteNote.getRemoteId())) {
|
||||
Log.d(getClass().getSimpleName(), " ... found -> Update");
|
||||
if(remoteNote.getModified()==null) {
|
||||
Log.v(getClass().getSimpleName(), " ... unchanged");
|
||||
} else if(idMap.containsKey(remoteNote.getRemoteId())) {
|
||||
Log.v(getClass().getSimpleName(), " ... found -> Update");
|
||||
dbHelper.updateNote(idMap.get(remoteNote.getRemoteId()), remoteNote, null);
|
||||
} else {
|
||||
Log.d(getClass().getSimpleName(), " ... create");
|
||||
Log.v(getClass().getSimpleName(), " ... create");
|
||||
dbHelper.addNote(remoteNote);
|
||||
}
|
||||
}
|
||||
|
@ -310,11 +317,30 @@ public class NoteServerSyncHelper {
|
|||
// remove remotely deleted notes (only those without local changes)
|
||||
for (Map.Entry<Long, Long> entry : idMap.entrySet()) {
|
||||
if(!remoteIDs.contains(entry.getKey())) {
|
||||
Log.d(getClass().getSimpleName(), " ... remove "+entry.getValue());
|
||||
Log.v(getClass().getSimpleName(), " ... remove "+entry.getValue());
|
||||
dbHelper.deleteNote(entry.getValue(), DBStatus.VOID);
|
||||
}
|
||||
}
|
||||
status = LoginStatus.OK;
|
||||
|
||||
// update ETag and Last-Modified in order to reduce size of next response
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
String etag = response.getETag();
|
||||
if(etag!=null && !etag.isEmpty()) {
|
||||
editor.putString(SettingsActivity.SETTINGS_KEY_ETAG, etag);
|
||||
} else {
|
||||
editor.remove(SettingsActivity.SETTINGS_KEY_ETAG);
|
||||
}
|
||||
long modified = response.getLastModified();
|
||||
if(modified!=0) {
|
||||
editor.putLong(SettingsActivity.SETTINGS_KEY_LAST_MODIFIED, modified);
|
||||
} else {
|
||||
editor.remove(SettingsActivity.SETTINGS_KEY_LAST_MODIFIED);
|
||||
}
|
||||
editor.apply();
|
||||
} catch (ServerResponse.NotModifiedException e) {
|
||||
Log.d(getClass().getSimpleName(), "No changes, nothing to do.");
|
||||
status = LoginStatus.OK;
|
||||
} catch (IOException e) {
|
||||
Log.e(getClass().getSimpleName(), "Exception", e);
|
||||
exceptions.add(e);
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
package it.niedermann.owncloud.notes.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
|
@ -14,27 +12,52 @@ import java.io.InputStreamReader;
|
|||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
|
||||
import at.bitfire.cert4android.CustomCertManager;
|
||||
import it.niedermann.owncloud.notes.model.CloudNote;
|
||||
import it.niedermann.owncloud.notes.util.ServerResponse.NoteResponse;
|
||||
import it.niedermann.owncloud.notes.util.ServerResponse.NotesResponse;
|
||||
|
||||
public class NotesClient {
|
||||
|
||||
/**
|
||||
* This entity class is used to return relevant data of the HTTP reponse.
|
||||
*/
|
||||
public static class ResponseData {
|
||||
private final String content;
|
||||
private final String etag;
|
||||
private final long lastModified;
|
||||
|
||||
public ResponseData(String content, String etag, long lastModified) {
|
||||
this.content = content;
|
||||
this.etag = etag;
|
||||
this.lastModified = lastModified;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public String getETag() {
|
||||
return etag;
|
||||
}
|
||||
|
||||
public long getLastModified() {
|
||||
return lastModified;
|
||||
}
|
||||
}
|
||||
|
||||
public static final String METHOD_GET = "GET";
|
||||
public static final String METHOD_PUT = "PUT";
|
||||
public static final String METHOD_POST = "POST";
|
||||
public static final String METHOD_DELETE = "DELETE";
|
||||
private static final String key_id = "id";
|
||||
private static final String key_title = "title";
|
||||
private static final String key_content = "content";
|
||||
private static final String key_favorite = "favorite";
|
||||
private static final String key_category = "category";
|
||||
private static final String key_etag = "etag";
|
||||
private static final String key_modified = "modified";
|
||||
public static final String JSON_ID = "id";
|
||||
public static final String JSON_TITLE = "title";
|
||||
public static final String JSON_CONTENT = "content";
|
||||
public static final String JSON_FAVORITE = "favorite";
|
||||
public static final String JSON_CATEGORY = "category";
|
||||
public static final String JSON_ETAG = "etag";
|
||||
public static final String JSON_MODIFIED = "modified";
|
||||
private static final String application_json = "application/json";
|
||||
private String url = "";
|
||||
private String username = "";
|
||||
|
@ -46,47 +69,12 @@ public class NotesClient {
|
|||
this.password = password;
|
||||
}
|
||||
|
||||
private CloudNote getNoteFromJSON(JSONObject json) throws JSONException {
|
||||
long id = 0;
|
||||
String title = "";
|
||||
String content = "";
|
||||
Calendar modified = null;
|
||||
boolean favorite = false;
|
||||
String category = null;
|
||||
String etag = null;
|
||||
if (!json.isNull(key_id)) {
|
||||
id = json.getLong(key_id);
|
||||
public NotesResponse getNotes(CustomCertManager ccm, long lastModified, String lastETag) throws JSONException, IOException {
|
||||
String url = "notes";
|
||||
if(lastModified>0) {
|
||||
url += "?pruneBefore="+lastModified;
|
||||
}
|
||||
if (!json.isNull(key_title)) {
|
||||
title = json.getString(key_title);
|
||||
}
|
||||
if (!json.isNull(key_content)) {
|
||||
content = json.getString(key_content);
|
||||
}
|
||||
if (!json.isNull(key_modified)) {
|
||||
modified = GregorianCalendar.getInstance();
|
||||
modified.setTimeInMillis(json.getLong(key_modified) * 1000);
|
||||
}
|
||||
if (!json.isNull(key_favorite)) {
|
||||
favorite = json.getBoolean(key_favorite);
|
||||
}
|
||||
if (!json.isNull(key_category)) {
|
||||
category = json.getString(key_category);
|
||||
}
|
||||
if (!json.isNull(key_etag)) {
|
||||
etag = json.getString(key_etag);
|
||||
}
|
||||
return new CloudNote(id, modified, title, content, favorite, category, etag);
|
||||
}
|
||||
|
||||
public List<CloudNote> getNotes(CustomCertManager ccm) throws JSONException, IOException {
|
||||
List<CloudNote> notesList = new ArrayList<>();
|
||||
JSONArray notes = new JSONArray(requestServer(ccm, "notes", METHOD_GET, null));
|
||||
for (int i = 0; i < notes.length(); i++) {
|
||||
JSONObject json = notes.getJSONObject(i);
|
||||
notesList.add(getNoteFromJSON(json));
|
||||
}
|
||||
return notesList;
|
||||
return new NotesResponse(requestServer(ccm, url, METHOD_GET, null, lastETag));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -98,18 +86,16 @@ public class NotesClient {
|
|||
* @throws IOException
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public CloudNote getNoteById(CustomCertManager ccm, long id) throws JSONException, IOException {
|
||||
JSONObject json = new JSONObject(requestServer(ccm, "notes/" + id, METHOD_GET, null));
|
||||
return getNoteFromJSON(json);
|
||||
public NoteResponse getNoteById(CustomCertManager ccm, long id) throws JSONException, IOException {
|
||||
return new NoteResponse(requestServer(ccm, "notes/" + id, METHOD_GET, null, null));
|
||||
}
|
||||
|
||||
private CloudNote putNote(CustomCertManager ccm, CloudNote note, String path, String method) throws JSONException, IOException {
|
||||
private NoteResponse putNote(CustomCertManager ccm, CloudNote note, String path, String method) throws JSONException, IOException {
|
||||
JSONObject paramObject = new JSONObject();
|
||||
paramObject.accumulate(key_content, note.getContent());
|
||||
paramObject.accumulate(key_modified, note.getModified().getTimeInMillis()/1000);
|
||||
paramObject.accumulate(key_favorite, note.isFavorite());
|
||||
JSONObject json = new JSONObject(requestServer(ccm, path, method, paramObject));
|
||||
return getNoteFromJSON(json);
|
||||
paramObject.accumulate(JSON_CONTENT, note.getContent());
|
||||
paramObject.accumulate(JSON_MODIFIED, note.getModified().getTimeInMillis()/1000);
|
||||
paramObject.accumulate(JSON_FAVORITE, note.isFavorite());
|
||||
return new NoteResponse(requestServer(ccm, path, method, paramObject, null));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -120,17 +106,16 @@ public class NotesClient {
|
|||
* @throws JSONException
|
||||
* @throws IOException
|
||||
*/
|
||||
public CloudNote createNote(CustomCertManager ccm, CloudNote note) throws JSONException, IOException {
|
||||
public NoteResponse createNote(CustomCertManager ccm, CloudNote note) throws JSONException, IOException {
|
||||
return putNote(ccm, note, "notes", METHOD_POST);
|
||||
}
|
||||
|
||||
public CloudNote editNote(CustomCertManager ccm, CloudNote note) throws JSONException, IOException {
|
||||
public NoteResponse editNote(CustomCertManager ccm, CloudNote note) throws JSONException, IOException {
|
||||
return putNote(ccm, note, "notes/" + note.getRemoteId(), METHOD_PUT);
|
||||
}
|
||||
|
||||
public void deleteNote(CustomCertManager ccm, long noteId) throws
|
||||
IOException {
|
||||
this.requestServer(ccm, "notes/" + noteId, METHOD_DELETE, null);
|
||||
public void deleteNote(CustomCertManager ccm, long noteId) throws IOException {
|
||||
this.requestServer(ccm, "notes/" + noteId, METHOD_DELETE, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -143,19 +128,25 @@ public class NotesClient {
|
|||
* @throws MalformedURLException
|
||||
* @throws IOException
|
||||
*/
|
||||
private String requestServer(CustomCertManager ccm, String target, String method, JSONObject params)
|
||||
private ResponseData requestServer(CustomCertManager ccm, String target, String method, JSONObject params, String lastETag)
|
||||
throws IOException {
|
||||
StringBuffer result = new StringBuffer();
|
||||
// setup connection
|
||||
String targetURL = url + "index.php/apps/notes/api/v0.2/" + target;
|
||||
HttpURLConnection con = SupportUtil.getHttpURLConnection(ccm, targetURL);
|
||||
con.setRequestMethod(method);
|
||||
con.setRequestProperty(
|
||||
"Authorization",
|
||||
"Basic " + Base64.encodeToString((username + ":" + password).getBytes(), Base64.NO_WRAP));
|
||||
if(lastETag!=null && METHOD_GET.equals(method)) {
|
||||
con.setRequestProperty("If-None-Match", lastETag);
|
||||
}
|
||||
con.setConnectTimeout(10 * 1000); // 10 seconds
|
||||
Log.d(getClass().getSimpleName(), method + " " + targetURL);
|
||||
// send request data (optional)
|
||||
byte[] paramData=null;
|
||||
if (params != null) {
|
||||
byte[] paramData = params.toString().getBytes();
|
||||
paramData = params.toString().getBytes();
|
||||
Log.d(getClass().getSimpleName(), "Params: " + params);
|
||||
con.setFixedLengthStreamingMode(paramData.length);
|
||||
con.setRequestProperty("Content-Type", application_json);
|
||||
|
@ -165,12 +156,25 @@ public class NotesClient {
|
|||
os.flush();
|
||||
os.close();
|
||||
}
|
||||
BufferedReader rd = new BufferedReader(new InputStreamReader(con.getInputStream()));
|
||||
// read response data
|
||||
int responseCode = con.getResponseCode();
|
||||
Log.d(getClass().getSimpleName(), "HTTP response code: "+responseCode);
|
||||
|
||||
if(responseCode==HttpURLConnection.HTTP_NOT_MODIFIED) {
|
||||
throw new ServerResponse.NotModifiedException();
|
||||
}
|
||||
|
||||
BufferedReader rd = new BufferedReader(new InputStreamReader(con.getInputStream()));
|
||||
String line;
|
||||
while ((line = rd.readLine()) != null) {
|
||||
result.append(line);
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
// create response object
|
||||
String etag = con.getHeaderField("ETag");
|
||||
long lastModified = con.getHeaderFieldDate("Last-Modified", 0) / 1000;
|
||||
Log.i(getClass().getSimpleName(), "Result length: " + result.length() + (paramData == null ? "" : "; Request length: " + paramData.length));
|
||||
Log.d(getClass().getSimpleName(), "ETag: " + etag + "; Last-Modified: " + lastModified + " (" + con.getHeaderField("Last-Modified") + ")");
|
||||
// return these header fields since they should only be saved after successful processing the result!
|
||||
return new ResponseData(result.toString(), etag, lastModified);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
package it.niedermann.owncloud.notes.util;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
|
||||
import it.niedermann.owncloud.notes.model.CloudNote;
|
||||
|
||||
/**
|
||||
* Provides entity classes for handling server responses with a single note ({@link NoteResponse}) or a list of notes ({@link NotesResponse}).
|
||||
*/
|
||||
public class ServerResponse {
|
||||
|
||||
public static class NotModifiedException extends IOException {
|
||||
}
|
||||
|
||||
public static class NoteResponse extends ServerResponse {
|
||||
public NoteResponse(NotesClient.ResponseData response) {
|
||||
super(response);
|
||||
}
|
||||
|
||||
public CloudNote getNote() throws JSONException {
|
||||
return getNoteFromJSON(new JSONObject(getContent()));
|
||||
}
|
||||
}
|
||||
|
||||
public static class NotesResponse extends ServerResponse {
|
||||
public NotesResponse(NotesClient.ResponseData response) {
|
||||
super(response);
|
||||
}
|
||||
|
||||
public List<CloudNote> getNotes() throws JSONException {
|
||||
List<CloudNote> notesList = new ArrayList<>();
|
||||
JSONArray notes = new JSONArray(getContent());
|
||||
for (int i = 0; i < notes.length(); i++) {
|
||||
JSONObject json = notes.getJSONObject(i);
|
||||
notesList.add(getNoteFromJSON(json));
|
||||
}
|
||||
return notesList;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private final NotesClient.ResponseData response;
|
||||
|
||||
public ServerResponse(NotesClient.ResponseData response) {
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
protected String getContent() {
|
||||
return response.getContent();
|
||||
}
|
||||
|
||||
public String getETag() {
|
||||
return response.getETag();
|
||||
}
|
||||
|
||||
public long getLastModified() {
|
||||
return response.getLastModified();
|
||||
}
|
||||
|
||||
protected CloudNote getNoteFromJSON(JSONObject json) throws JSONException {
|
||||
long id = 0;
|
||||
String title = "";
|
||||
String content = "";
|
||||
Calendar modified = null;
|
||||
boolean favorite = false;
|
||||
String category = null;
|
||||
String etag = null;
|
||||
if (!json.isNull(NotesClient.JSON_ID)) {
|
||||
id = json.getLong(NotesClient.JSON_ID);
|
||||
}
|
||||
if (!json.isNull(NotesClient.JSON_TITLE)) {
|
||||
title = json.getString(NotesClient.JSON_TITLE);
|
||||
}
|
||||
if (!json.isNull(NotesClient.JSON_CONTENT)) {
|
||||
content = json.getString(NotesClient.JSON_CONTENT);
|
||||
}
|
||||
if (!json.isNull(NotesClient.JSON_MODIFIED)) {
|
||||
modified = GregorianCalendar.getInstance();
|
||||
modified.setTimeInMillis(json.getLong(NotesClient.JSON_MODIFIED) * 1000);
|
||||
}
|
||||
if (!json.isNull(NotesClient.JSON_FAVORITE)) {
|
||||
favorite = json.getBoolean(NotesClient.JSON_FAVORITE);
|
||||
}
|
||||
if (!json.isNull(NotesClient.JSON_CATEGORY)) {
|
||||
category = json.getString(NotesClient.JSON_CATEGORY);
|
||||
}
|
||||
if (!json.isNull(NotesClient.JSON_ETAG)) {
|
||||
etag = json.getString(NotesClient.JSON_ETAG);
|
||||
}
|
||||
return new CloudNote(id, modified, title, content, favorite, category, etag);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue