Fix backup error handling
This commit is contained in:
parent
3ce4082997
commit
9d39e2f805
9 changed files with 322 additions and 147 deletions
|
@ -48,13 +48,14 @@ public class AndroidNetworkUtils {
|
||||||
private static final Log LOG = PlatformUtil.getLog(AndroidNetworkUtils.class);
|
private static final Log LOG = PlatformUtil.getLog(AndroidNetworkUtils.class);
|
||||||
|
|
||||||
public interface OnRequestResultListener {
|
public interface OnRequestResultListener {
|
||||||
void onResult(String result);
|
void onResult(@Nullable String result, @Nullable String error);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface OnFilesUploadCallback {
|
public interface OnFilesUploadCallback {
|
||||||
@Nullable
|
@Nullable
|
||||||
Map<String, String> getAdditionalParams(@NonNull File file);
|
Map<String, String> getAdditionalParams(@NonNull File file);
|
||||||
void onFileUploadProgress(@NonNull File file, int percent);
|
void onFileUploadProgress(@NonNull File file, int percent);
|
||||||
|
void onFileUploadDone(@NonNull File file);
|
||||||
void onFilesUploadDone(@NonNull Map<File, String> errors);
|
void onFilesUploadDone(@NonNull Map<File, String> errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,16 +65,26 @@ public class AndroidNetworkUtils {
|
||||||
void onFileDownloadProgress(@NonNull File file, int percent);
|
void onFileDownloadProgress(@NonNull File file, int percent);
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
void onFileDownloadedAsync(@NonNull File file);
|
void onFileDownloadedAsync(@NonNull File file);
|
||||||
|
|
||||||
|
void onFileDownloadDone(@NonNull File file);
|
||||||
void onFilesDownloadDone(@NonNull Map<File, String> errors);
|
void onFilesDownloadDone(@NonNull Map<File, String> errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RequestResponse {
|
public static class RequestResponse {
|
||||||
private Request request;
|
private final Request request;
|
||||||
private String response;
|
private final String response;
|
||||||
|
private final String error;
|
||||||
|
|
||||||
RequestResponse(@NonNull Request request, @Nullable String response) {
|
RequestResponse(@NonNull Request request, @Nullable String response) {
|
||||||
this.request = request;
|
this.request = request;
|
||||||
this.response = response;
|
this.response = response;
|
||||||
|
this.error = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
RequestResponse(@NonNull Request request, @Nullable String response, @Nullable String error) {
|
||||||
|
this.request = request;
|
||||||
|
this.response = response;
|
||||||
|
this.error = error;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Request getRequest() {
|
public Request getRequest() {
|
||||||
|
@ -83,6 +94,10 @@ public class AndroidNetworkUtils {
|
||||||
public String getResponse() {
|
public String getResponse() {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getError() {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface OnSendRequestsListener {
|
public interface OnSendRequestsListener {
|
||||||
|
@ -109,11 +124,18 @@ public class AndroidNetworkUtils {
|
||||||
for (Request request : requests) {
|
for (Request request : requests) {
|
||||||
RequestResponse requestResponse;
|
RequestResponse requestResponse;
|
||||||
try {
|
try {
|
||||||
String response = sendRequest(ctx, request.getUrl(), request.getParameters(),
|
final String[] response = {null, null};
|
||||||
request.getUserOperation(), request.isToastAllowed(), request.isPost());
|
sendRequest(ctx, request.getUrl(), request.getParameters(),
|
||||||
requestResponse = new RequestResponse(request, response);
|
request.getUserOperation(), request.isToastAllowed(), request.isPost(), new OnRequestResultListener() {
|
||||||
|
@Override
|
||||||
|
public void onResult(@Nullable String result, @Nullable String error) {
|
||||||
|
response[0] = result;
|
||||||
|
response[1] = error;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
requestResponse = new RequestResponse(request, response[0], response[1]);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
requestResponse = new RequestResponse(request, null);
|
requestResponse = new RequestResponse(request, null, "Unexpected error");
|
||||||
}
|
}
|
||||||
responses.add(requestResponse);
|
responses.add(requestResponse);
|
||||||
publishProgress(requestResponse);
|
publishProgress(requestResponse);
|
||||||
|
@ -157,21 +179,29 @@ public class AndroidNetworkUtils {
|
||||||
final boolean post,
|
final boolean post,
|
||||||
final OnRequestResultListener listener,
|
final OnRequestResultListener listener,
|
||||||
final Executor executor) {
|
final Executor executor) {
|
||||||
new AsyncTask<Void, Void, String>() {
|
new AsyncTask<Void, Void, String[]>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String doInBackground(Void... params) {
|
protected String[] doInBackground(Void... params) {
|
||||||
|
final String[] res = {null, null};
|
||||||
try {
|
try {
|
||||||
return sendRequest(ctx, url, parameters, userOperation, toastAllowed, post);
|
sendRequest(ctx, url, parameters, userOperation, toastAllowed, post, new OnRequestResultListener() {
|
||||||
|
@Override
|
||||||
|
public void onResult(@Nullable String result, @Nullable String error) {
|
||||||
|
res[0] = result;
|
||||||
|
res[1] = error;
|
||||||
|
}
|
||||||
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return null;
|
// ignore
|
||||||
}
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(String response) {
|
protected void onPostExecute(String[] response) {
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
listener.onResult(response);
|
listener.onResult(response[0], response[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,7 +285,7 @@ public class AndroidNetworkUtils {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
errors.put(file, e.getMessage());
|
errors.put(file, e.getMessage());
|
||||||
}
|
}
|
||||||
publishProgress(file, Integer.MAX_VALUE);
|
publishProgress(file, -1);
|
||||||
}
|
}
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
@ -263,7 +293,13 @@ public class AndroidNetworkUtils {
|
||||||
@Override
|
@Override
|
||||||
protected void onProgressUpdate(Object... objects) {
|
protected void onProgressUpdate(Object... objects) {
|
||||||
if (callback != null) {
|
if (callback != null) {
|
||||||
callback.onFileDownloadProgress((File) objects[0], (Integer) objects[1]);
|
File file = (File) objects[0];
|
||||||
|
Integer progress = (Integer) objects[1];
|
||||||
|
if (progress >= 0) {
|
||||||
|
callback.onFileDownloadProgress(file, progress);
|
||||||
|
} else {
|
||||||
|
callback.onFileDownloadDone(file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,9 +316,17 @@ public class AndroidNetworkUtils {
|
||||||
public static String sendRequest(@Nullable OsmandApplication ctx, @NonNull String url,
|
public static String sendRequest(@Nullable OsmandApplication ctx, @NonNull String url,
|
||||||
@Nullable Map<String, String> parameters,
|
@Nullable Map<String, String> parameters,
|
||||||
@Nullable String userOperation, boolean toastAllowed, boolean post) {
|
@Nullable String userOperation, boolean toastAllowed, boolean post) {
|
||||||
|
return sendRequest(ctx, url, parameters, userOperation, toastAllowed, post, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String sendRequest(@Nullable OsmandApplication ctx, @NonNull String url,
|
||||||
|
@Nullable Map<String, String> parameters,
|
||||||
|
@Nullable String userOperation, boolean toastAllowed, boolean post,
|
||||||
|
@Nullable OnRequestResultListener listener) {
|
||||||
|
String result = null;
|
||||||
|
String error = null;
|
||||||
HttpURLConnection connection = null;
|
HttpURLConnection connection = null;
|
||||||
try {
|
try {
|
||||||
|
|
||||||
String params = null;
|
String params = null;
|
||||||
if (parameters != null && parameters.size() > 0) {
|
if (parameters != null && parameters.size() > 0) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
@ -312,68 +356,66 @@ public class AndroidNetworkUtils {
|
||||||
output.write(params.getBytes("UTF-8"));
|
output.write(params.getBytes("UTF-8"));
|
||||||
output.flush();
|
output.flush();
|
||||||
output.close();
|
output.close();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
connection.setRequestMethod("GET");
|
connection.setRequestMethod("GET");
|
||||||
connection.connect();
|
connection.connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
|
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
|
||||||
|
if (ctx != null) {
|
||||||
|
error = (!Algorithms.isEmpty(userOperation) ? userOperation + " " : "")
|
||||||
|
+ ctx.getString(R.string.failed_op) + ": " + connection.getResponseMessage();
|
||||||
|
} else {
|
||||||
|
error = (!Algorithms.isEmpty(userOperation) ? userOperation + " " : "")
|
||||||
|
+ "failed: " + connection.getResponseMessage();
|
||||||
|
}
|
||||||
if (toastAllowed && ctx != null) {
|
if (toastAllowed && ctx != null) {
|
||||||
String msg = (!Algorithms.isEmpty(userOperation) ? userOperation + " " : "")
|
showToast(ctx, error);
|
||||||
+ ctx.getString(R.string.failed_op) + ": "
|
}
|
||||||
+ connection.getResponseMessage();
|
InputStream errorStream = connection.getErrorStream();
|
||||||
showToast(ctx, msg);
|
if (errorStream != null) {
|
||||||
|
error = streamToString(errorStream);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
StringBuilder responseBody = new StringBuilder();
|
result = streamToString(connection.getInputStream());
|
||||||
responseBody.setLength(0);
|
|
||||||
InputStream i = connection.getInputStream();
|
|
||||||
if (i != null) {
|
|
||||||
BufferedReader in = new BufferedReader(new InputStreamReader(i, "UTF-8"), 256);
|
|
||||||
String s;
|
|
||||||
boolean f = true;
|
|
||||||
while ((s = in.readLine()) != null) {
|
|
||||||
if (!f) {
|
|
||||||
responseBody.append("\n");
|
|
||||||
} else {
|
|
||||||
f = false;
|
|
||||||
}
|
|
||||||
responseBody.append(s);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
in.close();
|
|
||||||
i.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
// ignore exception
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return responseBody.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
// that's tricky case why NPE is thrown to fix that problem httpClient could be used
|
// that's tricky case why NPE is thrown to fix that problem httpClient could be used
|
||||||
|
if (ctx != null) {
|
||||||
|
error = ctx.getString(R.string.auth_failed);
|
||||||
|
} else {
|
||||||
|
error = "Authorization failed";
|
||||||
|
}
|
||||||
if (toastAllowed && ctx != null) {
|
if (toastAllowed && ctx != null) {
|
||||||
String msg = ctx.getString(R.string.auth_failed);
|
showToast(ctx, error);
|
||||||
showToast(ctx, msg);
|
|
||||||
}
|
}
|
||||||
} catch (MalformedURLException e) {
|
} catch (MalformedURLException e) {
|
||||||
|
if (ctx != null) {
|
||||||
|
error = MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template)
|
||||||
|
+ ": " + ctx.getResources().getString(R.string.shared_string_unexpected_error), userOperation);
|
||||||
|
} else {
|
||||||
|
error = "Action " + userOperation + ": Unexpected error";
|
||||||
|
}
|
||||||
if (toastAllowed && ctx != null) {
|
if (toastAllowed && ctx != null) {
|
||||||
showToast(ctx, MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template)
|
showToast(ctx, error);
|
||||||
+ ": " + ctx.getResources().getString(R.string.shared_string_unexpected_error), userOperation));
|
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
if (ctx != null) {
|
||||||
|
error = MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template)
|
||||||
|
+ ": " + ctx.getResources().getString(R.string.shared_string_io_error), userOperation);
|
||||||
|
} else {
|
||||||
|
error = "Action " + userOperation + ": I/O error";
|
||||||
|
}
|
||||||
if (toastAllowed && ctx != null) {
|
if (toastAllowed && ctx != null) {
|
||||||
showToast(ctx, MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template)
|
showToast(ctx, error);
|
||||||
+ ": " + ctx.getResources().getString(R.string.shared_string_io_error), userOperation));
|
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
if (connection != null) {
|
if (connection != null) {
|
||||||
connection.disconnect();
|
connection.disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onResult(result, error);
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,35 +443,64 @@ public class AndroidNetworkUtils {
|
||||||
public static String downloadFile(@NonNull String url, @NonNull File fileToSave, boolean gzip, @Nullable IProgress progress) {
|
public static String downloadFile(@NonNull String url, @NonNull File fileToSave, boolean gzip, @Nullable IProgress progress) {
|
||||||
String error = null;
|
String error = null;
|
||||||
try {
|
try {
|
||||||
URLConnection connection = NetworkUtils.getHttpURLConnection(url);
|
HttpURLConnection connection = NetworkUtils.getHttpURLConnection(url);
|
||||||
connection.setConnectTimeout(CONNECTION_TIMEOUT);
|
connection.setConnectTimeout(CONNECTION_TIMEOUT);
|
||||||
connection.setReadTimeout(CONNECTION_TIMEOUT);
|
connection.setReadTimeout(CONNECTION_TIMEOUT);
|
||||||
if (gzip) {
|
if (gzip) {
|
||||||
connection.setRequestProperty("Accept-Encoding", "deflate, gzip");
|
connection.setRequestProperty("Accept-Encoding", "deflate, gzip");
|
||||||
}
|
}
|
||||||
InputStream inputStream = gzip
|
connection.connect();
|
||||||
? new GZIPInputStream(connection.getInputStream())
|
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
|
||||||
: new BufferedInputStream(connection.getInputStream(), 8 * 1024);
|
return streamToString(connection.getErrorStream());
|
||||||
fileToSave.getParentFile().mkdirs();
|
} else {
|
||||||
OutputStream stream = null;
|
InputStream inputStream = gzip
|
||||||
try {
|
? new GZIPInputStream(connection.getInputStream())
|
||||||
stream = new FileOutputStream(fileToSave);
|
: new BufferedInputStream(connection.getInputStream(), 8 * 1024);
|
||||||
Algorithms.streamCopy(inputStream, stream, progress, 1024);
|
fileToSave.getParentFile().mkdirs();
|
||||||
stream.flush();
|
OutputStream stream = null;
|
||||||
} finally {
|
try {
|
||||||
Algorithms.closeStream(inputStream);
|
stream = new FileOutputStream(fileToSave);
|
||||||
Algorithms.closeStream(stream);
|
Algorithms.streamCopy(inputStream, stream, progress, 1024);
|
||||||
|
stream.flush();
|
||||||
|
} finally {
|
||||||
|
Algorithms.closeStream(inputStream);
|
||||||
|
Algorithms.closeStream(stream);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (UnknownHostException e) {
|
} catch (UnknownHostException e) {
|
||||||
error = e.getMessage();
|
error = e.getMessage();
|
||||||
LOG.error("UnknownHostException, cannot download file " + url + " " + error);
|
LOG.error("UnknownHostException, cannot download file " + url + " " + error);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
error = e.getMessage();
|
error = e.getMessage();
|
||||||
LOG.warn("Cannot download file : " + url, e);
|
LOG.warn("Cannot download file: " + url, e);
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String streamToString(InputStream inputStream) throws IOException {
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
if (inputStream != null) {
|
||||||
|
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 256);
|
||||||
|
String buffer;
|
||||||
|
boolean f = true;
|
||||||
|
while ((buffer = in.readLine()) != null) {
|
||||||
|
if (!f) {
|
||||||
|
result.append("\n");
|
||||||
|
} else {
|
||||||
|
f = false;
|
||||||
|
}
|
||||||
|
result.append(buffer);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
in.close();
|
||||||
|
inputStream.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// ignore exception
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
private static final String BOUNDARY = "CowMooCowMooCowCowCow";
|
private static final String BOUNDARY = "CowMooCowMooCowCowCow";
|
||||||
|
|
||||||
public static String uploadFile(@NonNull String urlText, @NonNull File file, boolean gzip,
|
public static String uploadFile(@NonNull String urlText, @NonNull File file, boolean gzip,
|
||||||
|
@ -444,7 +515,6 @@ public class AndroidNetworkUtils {
|
||||||
@NonNull Map<String, String> additionalParams,
|
@NonNull Map<String, String> additionalParams,
|
||||||
@Nullable Map<String, String> headers,
|
@Nullable Map<String, String> headers,
|
||||||
@Nullable IProgress progress) {
|
@Nullable IProgress progress) {
|
||||||
URL url;
|
|
||||||
try {
|
try {
|
||||||
boolean firstPrm = !urlText.contains("?");
|
boolean firstPrm = !urlText.contains("?");
|
||||||
StringBuilder sb = new StringBuilder(urlText);
|
StringBuilder sb = new StringBuilder(urlText);
|
||||||
|
@ -455,7 +525,7 @@ public class AndroidNetworkUtils {
|
||||||
urlText = sb.toString();
|
urlText = sb.toString();
|
||||||
|
|
||||||
LOG.info("Start uploading file to " + urlText + " " + fileName);
|
LOG.info("Start uploading file to " + urlText + " " + fileName);
|
||||||
url = new URL(urlText);
|
URL url = new URL(urlText);
|
||||||
|
|
||||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||||
conn.setDoInput(true);
|
conn.setDoInput(true);
|
||||||
|
@ -496,6 +566,10 @@ public class AndroidNetworkUtils {
|
||||||
LOG.info("Finish uploading file " + fileName);
|
LOG.info("Finish uploading file " + fileName);
|
||||||
LOG.info("Response code and message : " + conn.getResponseCode() + " " + conn.getResponseMessage());
|
LOG.info("Response code and message : " + conn.getResponseCode() + " " + conn.getResponseMessage());
|
||||||
if (conn.getResponseCode() != 200) {
|
if (conn.getResponseCode() != 200) {
|
||||||
|
InputStream errorStream = conn.getErrorStream();
|
||||||
|
if (errorStream != null) {
|
||||||
|
return streamToString(errorStream);
|
||||||
|
}
|
||||||
return conn.getResponseMessage();
|
return conn.getResponseMessage();
|
||||||
}
|
}
|
||||||
InputStream is = conn.getInputStream();
|
InputStream is = conn.getInputStream();
|
||||||
|
@ -575,7 +649,7 @@ public class AndroidNetworkUtils {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
errors.put(file, e.getMessage());
|
errors.put(file, e.getMessage());
|
||||||
}
|
}
|
||||||
publishProgress(file, Integer.MAX_VALUE);
|
publishProgress(file, -1);
|
||||||
}
|
}
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
@ -583,7 +657,13 @@ public class AndroidNetworkUtils {
|
||||||
@Override
|
@Override
|
||||||
protected void onProgressUpdate(Object... objects) {
|
protected void onProgressUpdate(Object... objects) {
|
||||||
if (callback != null) {
|
if (callback != null) {
|
||||||
callback.onFileUploadProgress((File) objects[0], (Integer) objects[1]);
|
File file = (File) objects[0];
|
||||||
|
Integer progress = (Integer) objects[1];
|
||||||
|
if (progress >= 0) {
|
||||||
|
callback.onFileUploadProgress(file, progress);
|
||||||
|
} else {
|
||||||
|
callback.onFileUploadDone(file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -602,11 +682,11 @@ public class AndroidNetworkUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Request {
|
public static class Request {
|
||||||
private String url;
|
private final String url;
|
||||||
private Map<String, String> parameters;
|
private final Map<String, String> parameters;
|
||||||
private String userOperation;
|
private final String userOperation;
|
||||||
private boolean toastAllowed;
|
private final boolean toastAllowed;
|
||||||
private boolean post;
|
private final boolean post;
|
||||||
|
|
||||||
public Request(String url, Map<String, String> parameters, String userOperation, boolean toastAllowed, boolean post) {
|
public Request(String url, Map<String, String> parameters, String userOperation, boolean toastAllowed, boolean post) {
|
||||||
this.url = url;
|
this.url = url;
|
||||||
|
|
|
@ -225,7 +225,7 @@ public class CustomRegion extends WorldRegion {
|
||||||
&& app.getSettings().isInternetConnectionAvailable()) {
|
&& app.getSettings().isInternetConnectionAvailable()) {
|
||||||
OnRequestResultListener resultListener = new OnRequestResultListener() {
|
OnRequestResultListener resultListener = new OnRequestResultListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onResult(String result) {
|
public void onResult(@Nullable String result, @Nullable String error) {
|
||||||
if (!Algorithms.isEmpty(result)) {
|
if (!Algorithms.isEmpty(result)) {
|
||||||
if ("json".equalsIgnoreCase(dynamicDownloadItems.format)) {
|
if ("json".equalsIgnoreCase(dynamicDownloadItems.format)) {
|
||||||
dynamicItemsJson = mapJsonItems(result);
|
dynamicItemsJson = mapJsonItems(result);
|
||||||
|
|
|
@ -37,6 +37,7 @@ import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
@ -65,10 +66,6 @@ public class BackupHelper {
|
||||||
public final static int STATUS_EMPTY_RESPONSE_ERROR = 2;
|
public final static int STATUS_EMPTY_RESPONSE_ERROR = 2;
|
||||||
public final static int STATUS_SERVER_ERROR = 3;
|
public final static int STATUS_SERVER_ERROR = 3;
|
||||||
|
|
||||||
public interface OnResultListener {
|
|
||||||
void onResult(int status, @Nullable String message, @Nullable JSONObject json);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface OnRegisterUserListener {
|
public interface OnRegisterUserListener {
|
||||||
void onRegisterUser(int status, @Nullable String message);
|
void onRegisterUser(int status, @Nullable String message);
|
||||||
}
|
}
|
||||||
|
@ -83,7 +80,6 @@ public class BackupHelper {
|
||||||
|
|
||||||
public interface OnCollectLocalFilesListener {
|
public interface OnCollectLocalFilesListener {
|
||||||
void onFileCollected(@NonNull GpxFileInfo fileInfo);
|
void onFileCollected(@NonNull GpxFileInfo fileInfo);
|
||||||
|
|
||||||
void onFilesCollected(@NonNull List<GpxFileInfo> fileInfos);
|
void onFilesCollected(@NonNull List<GpxFileInfo> fileInfos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,20 +89,21 @@ public class BackupHelper {
|
||||||
|
|
||||||
public interface OnUploadFilesListener {
|
public interface OnUploadFilesListener {
|
||||||
void onFileUploadProgress(@NonNull File file, int progress);
|
void onFileUploadProgress(@NonNull File file, int progress);
|
||||||
|
void onFileUploadDone(@NonNull File file);
|
||||||
void onFilesUploadDone(@NonNull Map<File, String> errors);
|
void onFilesUploadDone(@NonNull Map<File, String> errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface OnDeleteFilesListener {
|
public interface OnDeleteFilesListener {
|
||||||
void onFileDeleteProgress(@NonNull UserFile file);
|
void onFileDeleteProgress(@NonNull UserFile file);
|
||||||
|
|
||||||
void onFilesDeleteDone(@NonNull Map<UserFile, String> errors);
|
void onFilesDeleteDone(@NonNull Map<UserFile, String> errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface OnDownloadFileListener {
|
public interface OnDownloadFileListener {
|
||||||
void onFileDownloadProgress(@NonNull UserFile userFile, int progress);
|
void onFileDownloadProgress(@NonNull UserFile userFile, int progress);
|
||||||
|
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
void onFileDownloadedAsync(@NonNull File file);
|
void onFileDownloadedAsync(@NonNull File file);
|
||||||
|
void onFileDownloaded(@NonNull File file);
|
||||||
void onFilesDownloadDone(@NonNull Map<File, String> errors);
|
void onFilesDownloadDone(@NonNull Map<File, String> errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,20 +171,22 @@ public class BackupHelper {
|
||||||
params.put("orderid", orderId);
|
params.put("orderid", orderId);
|
||||||
}
|
}
|
||||||
params.put("deviceid", app.getUserAndroidId());
|
params.put("deviceid", app.getUserAndroidId());
|
||||||
AndroidNetworkUtils.sendRequestAsync(app, USER_REGISTER_URL, params, "Register user", true, true, new OnRequestResultListener() {
|
AndroidNetworkUtils.sendRequestAsync(app, USER_REGISTER_URL, params, "Register user", false, true, new OnRequestResultListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onResult(String resultJson) {
|
public void onResult(@Nullable String resultJson, @Nullable String error) {
|
||||||
int status;
|
int status;
|
||||||
String message;
|
String message;
|
||||||
if (!Algorithms.isEmpty(resultJson)) {
|
if (!Algorithms.isEmpty(error)) {
|
||||||
|
message = "User registration error: " + parseServerError(error);
|
||||||
|
status = STATUS_SERVER_ERROR;
|
||||||
|
} else if (!Algorithms.isEmpty(resultJson)) {
|
||||||
try {
|
try {
|
||||||
JSONObject result = new JSONObject(resultJson);
|
JSONObject result = new JSONObject(resultJson);
|
||||||
String statusStr = result.getString("status");
|
if (result.has("status") && "ok".equals(result.getString("status"))) {
|
||||||
if (statusStr.equals("ok")) {
|
|
||||||
message = "You have been registered successfully. Please check for email with activation code.";
|
message = "You have been registered successfully. Please check for email with activation code.";
|
||||||
status = STATUS_SUCCESS;
|
status = STATUS_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
message = "User registration error: " + statusStr;
|
message = "User registration error: unknown";
|
||||||
status = STATUS_SERVER_ERROR;
|
status = STATUS_SERVER_ERROR;
|
||||||
}
|
}
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
|
@ -217,12 +216,15 @@ public class BackupHelper {
|
||||||
params.put("deviceid", androidId);
|
params.put("deviceid", androidId);
|
||||||
}
|
}
|
||||||
params.put("token", token);
|
params.put("token", token);
|
||||||
AndroidNetworkUtils.sendRequestAsync(app, DEVICE_REGISTER_URL, params, "Register device", true, true, new OnRequestResultListener() {
|
AndroidNetworkUtils.sendRequestAsync(app, DEVICE_REGISTER_URL, params, "Register device", false, true, new OnRequestResultListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onResult(String resultJson) {
|
public void onResult(@Nullable String resultJson, @Nullable String error) {
|
||||||
int status;
|
int status;
|
||||||
String message;
|
String message;
|
||||||
if (!Algorithms.isEmpty(resultJson)) {
|
if (!Algorithms.isEmpty(error)) {
|
||||||
|
message = "Device registration error: " + parseServerError(error);
|
||||||
|
status = STATUS_SERVER_ERROR;
|
||||||
|
} else if (!Algorithms.isEmpty(resultJson)) {
|
||||||
try {
|
try {
|
||||||
JSONObject result = new JSONObject(resultJson);
|
JSONObject result = new JSONObject(resultJson);
|
||||||
settings.BACKUP_DEVICE_ID.set(result.getString("id"));
|
settings.BACKUP_DEVICE_ID.set(result.getString("id"));
|
||||||
|
@ -230,8 +232,9 @@ public class BackupHelper {
|
||||||
settings.BACKUP_NATIVE_DEVICE_ID.set(result.getString("deviceid"));
|
settings.BACKUP_NATIVE_DEVICE_ID.set(result.getString("deviceid"));
|
||||||
settings.BACKUP_ACCESS_TOKEN.set(result.getString("accesstoken"));
|
settings.BACKUP_ACCESS_TOKEN.set(result.getString("accesstoken"));
|
||||||
settings.BACKUP_ACCESS_TOKEN_UPDATE_TIME.set(result.getString("udpatetime"));
|
settings.BACKUP_ACCESS_TOKEN_UPDATE_TIME.set(result.getString("udpatetime"));
|
||||||
status = STATUS_SUCCESS;
|
|
||||||
message = "Device have been registered successfully";
|
message = "Device have been registered successfully";
|
||||||
|
status = STATUS_SUCCESS;
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
message = "Device registration error: json parsing";
|
message = "Device registration error: json parsing";
|
||||||
status = STATUS_PARSE_JSON_ERROR;
|
status = STATUS_PARSE_JSON_ERROR;
|
||||||
|
@ -271,14 +274,6 @@ public class BackupHelper {
|
||||||
additionaParams.put("name", gpxFileInfo.getFileName(true));
|
additionaParams.put("name", gpxFileInfo.getFileName(true));
|
||||||
additionaParams.put("type", Algorithms.getFileExtension(file));
|
additionaParams.put("type", Algorithms.getFileExtension(file));
|
||||||
gpxFileInfo.uploadTime = System.currentTimeMillis();
|
gpxFileInfo.uploadTime = System.currentTimeMillis();
|
||||||
if (file.equals(favoritesFile)) {
|
|
||||||
favouritesHelper.setLastUploadedTime(gpxFileInfo.uploadTime);
|
|
||||||
} else {
|
|
||||||
GpxDataItem gpxItem = gpxHelper.getItem(file);
|
|
||||||
if (gpxItem != null) {
|
|
||||||
gpxHelper.updateLastUploadedTime(gpxItem, gpxFileInfo.uploadTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
additionaParams.put("clienttime", String.valueOf(gpxFileInfo.uploadTime));
|
additionaParams.put("clienttime", String.valueOf(gpxFileInfo.uploadTime));
|
||||||
}
|
}
|
||||||
return additionaParams;
|
return additionaParams;
|
||||||
|
@ -291,13 +286,31 @@ public class BackupHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFileUploadDone(@NonNull File file) {
|
||||||
|
if (listener != null) {
|
||||||
|
GpxFileInfo gpxFileInfo = gpxInfos.get(file);
|
||||||
|
if (gpxFileInfo != null) {
|
||||||
|
if (file.equals(favoritesFile)) {
|
||||||
|
favouritesHelper.setLastUploadedTime(gpxFileInfo.uploadTime);
|
||||||
|
} else {
|
||||||
|
GpxDataItem gpxItem = gpxHelper.getItem(file);
|
||||||
|
if (gpxItem != null) {
|
||||||
|
gpxHelper.updateLastUploadedTime(gpxItem, gpxFileInfo.uploadTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
listener.onFileUploadDone(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFilesUploadDone(@NonNull Map<File, String> errors) {
|
public void onFilesUploadDone(@NonNull Map<File, String> errors) {
|
||||||
if (errors.isEmpty()) {
|
if (errors.isEmpty()) {
|
||||||
settings.BACKUP_LAST_UPLOADED_TIME.set(System.currentTimeMillis() + 1);
|
settings.BACKUP_LAST_UPLOADED_TIME.set(System.currentTimeMillis() + 1);
|
||||||
}
|
}
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
listener.onFilesUploadDone(errors);
|
listener.onFilesUploadDone(resolveServerErrors(errors));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, EXECUTOR);
|
}, EXECUTOR);
|
||||||
|
@ -338,17 +351,29 @@ public class BackupHelper {
|
||||||
for (RequestResponse response : results) {
|
for (RequestResponse response : results) {
|
||||||
UserFile userFile = filesMap.get(response.getRequest());
|
UserFile userFile = filesMap.get(response.getRequest());
|
||||||
if (userFile != null) {
|
if (userFile != null) {
|
||||||
String responseStr = response.getResponse();
|
|
||||||
boolean success;
|
boolean success;
|
||||||
try {
|
String message = null;
|
||||||
JSONObject json = new JSONObject(responseStr);
|
String errorStr = response.getError();
|
||||||
String status = json.getString("status");
|
if (!Algorithms.isEmpty(errorStr)) {
|
||||||
success = status.equalsIgnoreCase("ok");
|
message = parseServerError(errorStr);
|
||||||
} catch (JSONException e) {
|
|
||||||
success = false;
|
success = false;
|
||||||
|
} else {
|
||||||
|
String responseStr = response.getResponse();
|
||||||
|
try {
|
||||||
|
JSONObject result = new JSONObject(responseStr);
|
||||||
|
if (result.has("status") && "ok".equals(result.getString("status"))) {
|
||||||
|
success = true;
|
||||||
|
} else {
|
||||||
|
message = "Unknown error";
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
message = "Json parsing error";
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!success) {
|
if (!success) {
|
||||||
errors.put(userFile, responseStr);
|
errors.put(userFile, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -364,13 +389,16 @@ public class BackupHelper {
|
||||||
Map<String, String> params = new HashMap<>();
|
Map<String, String> params = new HashMap<>();
|
||||||
params.put("deviceid", getDeviceId());
|
params.put("deviceid", getDeviceId());
|
||||||
params.put("accessToken", getAccessToken());
|
params.put("accessToken", getAccessToken());
|
||||||
AndroidNetworkUtils.sendRequestAsync(app, LIST_FILES_URL, params, "Download file list", true, false, new OnRequestResultListener() {
|
AndroidNetworkUtils.sendRequestAsync(app, LIST_FILES_URL, params, "Download file list", false, false, new OnRequestResultListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onResult(String resultJson) {
|
public void onResult(@Nullable String resultJson, @Nullable String error) {
|
||||||
int status;
|
int status;
|
||||||
String message;
|
String message;
|
||||||
List<UserFile> userFiles = new ArrayList<>();
|
List<UserFile> userFiles = new ArrayList<>();
|
||||||
if (!Algorithms.isEmpty(resultJson)) {
|
if (!Algorithms.isEmpty(error)) {
|
||||||
|
status = STATUS_SERVER_ERROR;
|
||||||
|
message = "Download file list error: " + parseServerError(error);
|
||||||
|
} else if (!Algorithms.isEmpty(resultJson)) {
|
||||||
try {
|
try {
|
||||||
JSONObject result = new JSONObject(resultJson);
|
JSONObject result = new JSONObject(resultJson);
|
||||||
String totalZipSize = result.getString("totalZipSize");
|
String totalZipSize = result.getString("totalZipSize");
|
||||||
|
@ -425,6 +453,13 @@ public class BackupHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFileDownloadDone(@NonNull File file) {
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onFileDownloaded(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFileDownloadedAsync(@NonNull File file) {
|
public void onFileDownloadedAsync(@NonNull File file) {
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
|
@ -435,7 +470,7 @@ public class BackupHelper {
|
||||||
@Override
|
@Override
|
||||||
public void onFilesDownloadDone(@NonNull Map<File, String> errors) {
|
public void onFilesDownloadDone(@NonNull Map<File, String> errors) {
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
listener.onFilesDownloadDone(errors);
|
listener.onFilesDownloadDone(resolveServerErrors(errors));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, EXECUTOR);
|
}, EXECUTOR);
|
||||||
|
@ -523,6 +558,36 @@ public class BackupHelper {
|
||||||
task.executeOnExecutor(EXECUTOR);
|
task.executeOnExecutor(EXECUTOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Map<File, String> resolveServerErrors(@NonNull Map<File, String> errors) {
|
||||||
|
Map<File, String> resolvedErrors = new HashMap<>();
|
||||||
|
for (Entry<File, String> fileError : errors.entrySet()) {
|
||||||
|
File file = fileError.getKey();
|
||||||
|
String errorStr = fileError.getValue();
|
||||||
|
try {
|
||||||
|
JSONObject errorJson = new JSONObject(errorStr);
|
||||||
|
JSONObject error = errorJson.getJSONObject("error");
|
||||||
|
errorStr = "Error " + error.getInt("errorCode") + " (" + error.getString("message") + ")";
|
||||||
|
} catch (JSONException e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
resolvedErrors.put(file, errorStr);
|
||||||
|
}
|
||||||
|
return resolvedErrors;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String parseServerError(@NonNull String error) {
|
||||||
|
try {
|
||||||
|
JSONObject resultError = new JSONObject(error);
|
||||||
|
if (resultError.has("error")) {
|
||||||
|
JSONObject errorObj = resultError.getJSONObject("error");
|
||||||
|
return errorObj.getInt("errorCode") + " (" + errorObj.getString("message") + ")";
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressLint("StaticFieldLeak")
|
@SuppressLint("StaticFieldLeak")
|
||||||
public void generateBackupInfo(@NonNull final List<GpxFileInfo> localFiles, @NonNull final List<UserFile> remoteFiles,
|
public void generateBackupInfo(@NonNull final List<GpxFileInfo> localFiles, @NonNull final List<UserFile> remoteFiles,
|
||||||
@Nullable final OnGenerateBackupInfoListener listener) {
|
@Nullable final OnGenerateBackupInfoListener listener) {
|
||||||
|
|
|
@ -179,6 +179,11 @@ public class BackupTask {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFileUploadDone(@NonNull File file) {
|
||||||
|
onTaskProgressDone();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFilesUploadDone(@NonNull Map<File, String> errors) {
|
public void onFilesUploadDone(@NonNull Map<File, String> errors) {
|
||||||
uploadErrors = errors;
|
uploadErrors = errors;
|
||||||
|
@ -223,6 +228,11 @@ public class BackupTask {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFileDownloaded(@NonNull File file) {
|
||||||
|
onTaskProgressDone();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFileDownloadedAsync(@NonNull File file) {
|
public void onFileDownloadedAsync(@NonNull File file) {
|
||||||
UserFile userFile = filesMap.get(file);
|
UserFile userFile = filesMap.get(file);
|
||||||
|
@ -299,7 +309,7 @@ public class BackupTask {
|
||||||
progress.startTask((String) objects[0], -1);
|
progress.startTask((String) objects[0], -1);
|
||||||
} else if (objects[0] instanceof Integer) {
|
} else if (objects[0] instanceof Integer) {
|
||||||
int progressValue = (Integer) objects[0];
|
int progressValue = (Integer) objects[0];
|
||||||
if (progressValue < Integer.MAX_VALUE) {
|
if (progressValue >= 0) {
|
||||||
progress.progress(progressValue);
|
progress.progress(progressValue);
|
||||||
} else {
|
} else {
|
||||||
progress.finishTask();
|
progress.finishTask();
|
||||||
|
@ -312,6 +322,13 @@ public class BackupTask {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onTaskProgressDone() {
|
||||||
|
Context ctx = contextRef.get();
|
||||||
|
if (ctx instanceof Activity && AndroidUtils.isActivityNotDestroyed((Activity) ctx) && progress != null) {
|
||||||
|
progress.finishTask();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void onError(@NonNull String message) {
|
private void onError(@NonNull String message) {
|
||||||
this.error = message;
|
this.error = message;
|
||||||
runningTasks.clear();
|
runningTasks.clear();
|
||||||
|
|
|
@ -137,6 +137,7 @@ public class TestBackupActivity extends OsmandActionBarActivity {
|
||||||
a.buttonVerify.setVisibility(View.VISIBLE);
|
a.buttonVerify.setVisibility(View.VISIBLE);
|
||||||
a.buttonVerify.setEnabled(status == BackupHelper.STATUS_SUCCESS);
|
a.buttonVerify.setEnabled(status == BackupHelper.STATUS_SUCCESS);
|
||||||
a.tokenEditText.requestFocus();
|
a.tokenEditText.requestFocus();
|
||||||
|
a.infoView.setText(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -162,10 +163,11 @@ public class TestBackupActivity extends OsmandActionBarActivity {
|
||||||
a.progressBar.setVisibility(View.GONE);
|
a.progressBar.setVisibility(View.GONE);
|
||||||
a.buttonVerify.setEnabled(status != BackupHelper.STATUS_SUCCESS);
|
a.buttonVerify.setEnabled(status != BackupHelper.STATUS_SUCCESS);
|
||||||
if (status == BackupHelper.STATUS_SUCCESS) {
|
if (status == BackupHelper.STATUS_SUCCESS) {
|
||||||
tokenEdit.setVisibility(View.GONE);
|
a.tokenEdit.setVisibility(View.GONE);
|
||||||
buttonVerify.setVisibility(View.GONE);
|
a.buttonVerify.setVisibility(View.GONE);
|
||||||
|
a.prepareBackup();
|
||||||
}
|
}
|
||||||
a.prepareBackup();
|
a.infoView.setText(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -196,15 +198,19 @@ public class TestBackupActivity extends OsmandActionBarActivity {
|
||||||
String description;
|
String description;
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
description = error;
|
description = error;
|
||||||
} else if (uploadErrors == null && downloadErrors == null) {
|
} else if (uploadErrors == null && deleteErrors == null) {
|
||||||
description = "No data";
|
description = "No data";
|
||||||
} else {
|
} else {
|
||||||
description = getBackupErrorsDescription(uploadErrors, downloadErrors, deleteErrors, error);
|
description = getBackupErrorsDescription(uploadErrors, downloadErrors, deleteErrors, error);
|
||||||
}
|
}
|
||||||
a.infoView.setText(description);
|
a.infoView.setText(description);
|
||||||
a.infoView.requestFocus();
|
a.infoView.requestFocus();
|
||||||
a.prepareBackup();
|
|
||||||
a.buttonBackup.setEnabled(true);
|
a.buttonBackup.setEnabled(true);
|
||||||
|
if (Algorithms.isEmpty(description)) {
|
||||||
|
a.prepareBackup();
|
||||||
|
} else {
|
||||||
|
a.backupInfo = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -233,8 +239,12 @@ public class TestBackupActivity extends OsmandActionBarActivity {
|
||||||
}
|
}
|
||||||
a.infoView.setText(description);
|
a.infoView.setText(description);
|
||||||
a.infoView.requestFocus();
|
a.infoView.requestFocus();
|
||||||
a.prepareBackup();
|
|
||||||
a.buttonRestore.setEnabled(true);
|
a.buttonRestore.setEnabled(true);
|
||||||
|
if (Algorithms.isEmpty(description)) {
|
||||||
|
a.prepareBackup();
|
||||||
|
} else {
|
||||||
|
a.backupInfo = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -249,21 +259,21 @@ public class TestBackupActivity extends OsmandActionBarActivity {
|
||||||
private String getBackupErrorsDescription(@Nullable Map<File, String> uploadErrors, @Nullable Map<File, String> downloadErrors, @Nullable Map<UserFile, String> deleteErrors, @Nullable String error) {
|
private String getBackupErrorsDescription(@Nullable Map<File, String> uploadErrors, @Nullable Map<File, String> downloadErrors, @Nullable Map<UserFile, String> deleteErrors, @Nullable String error) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
if (!Algorithms.isEmpty(uploadErrors)) {
|
if (!Algorithms.isEmpty(uploadErrors)) {
|
||||||
sb.append("--- Upload errors ---").append("\n");
|
sb.append("--- Upload errors ---").append("\n\n");
|
||||||
for (Entry<File, String> uploadEntry : uploadErrors.entrySet()) {
|
for (Entry<File, String> uploadEntry : uploadErrors.entrySet()) {
|
||||||
sb.append(uploadEntry.getKey().getName()).append(": ").append(uploadEntry.getValue()).append("\n");
|
sb.append(uploadEntry.getKey().getName()).append(": ").append(uploadEntry.getValue()).append("\n\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!Algorithms.isEmpty(downloadErrors)) {
|
if (!Algorithms.isEmpty(downloadErrors)) {
|
||||||
sb.append("--- Download errors ---").append("\n");
|
sb.append("--- Download errors ---").append("\n\n");
|
||||||
for (Entry<File, String> downloadEntry : downloadErrors.entrySet()) {
|
for (Entry<File, String> downloadEntry : downloadErrors.entrySet()) {
|
||||||
sb.append(downloadEntry.getKey().getName()).append(": ").append(downloadEntry.getValue()).append("\n");
|
sb.append(downloadEntry.getKey().getName()).append(": ").append(downloadEntry.getValue()).append("\n\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!Algorithms.isEmpty(deleteErrors)) {
|
if (!Algorithms.isEmpty(deleteErrors)) {
|
||||||
sb.append("--- Delete errors ---").append("\n");
|
sb.append("--- Delete errors ---").append("\n\n");
|
||||||
for (Entry<UserFile, String> deleteEntry : deleteErrors.entrySet()) {
|
for (Entry<UserFile, String> deleteEntry : deleteErrors.entrySet()) {
|
||||||
sb.append(deleteEntry.getKey().getName()).append(": ").append(deleteEntry.getValue()).append("\n");
|
sb.append(deleteEntry.getKey().getName()).append(": ").append(deleteEntry.getValue()).append("\n\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sb.length() == 0 ? "OK" : sb.toString();
|
return sb.length() == 0 ? "OK" : sb.toString();
|
||||||
|
@ -272,32 +282,32 @@ public class TestBackupActivity extends OsmandActionBarActivity {
|
||||||
private String getBackupDescription(@NonNull BackupInfo backupInfo) {
|
private String getBackupDescription(@NonNull BackupInfo backupInfo) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
if (!Algorithms.isEmpty(backupInfo.filesToUpload)) {
|
if (!Algorithms.isEmpty(backupInfo.filesToUpload)) {
|
||||||
sb.append("\n").append("--- Upload ---").append("\n");
|
sb.append("\n").append("--- Upload ---").append("\n\n");
|
||||||
for (GpxFileInfo info : backupInfo.filesToUpload) {
|
for (GpxFileInfo info : backupInfo.filesToUpload) {
|
||||||
sb.append(info.getFileName(true))
|
sb.append(info.getFileName(true))
|
||||||
.append(" L: ").append(DF.format(new Date(info.getFileDate())))
|
.append(" L: ").append(DF.format(new Date(info.getFileDate())))
|
||||||
.append(" U: ").append(DF.format(new Date(info.uploadTime)))
|
.append(" U: ").append(DF.format(new Date(info.uploadTime)))
|
||||||
.append("\n");
|
.append("\n\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!Algorithms.isEmpty(backupInfo.filesToDownload)) {
|
if (!Algorithms.isEmpty(backupInfo.filesToDownload)) {
|
||||||
sb.append("\n").append("--- Download ---").append("\n");
|
sb.append("\n").append("--- Download ---").append("\n\n");
|
||||||
for (UserFile userFile : backupInfo.filesToDownload) {
|
for (UserFile userFile : backupInfo.filesToDownload) {
|
||||||
sb.append(userFile.getName())
|
sb.append(userFile.getName())
|
||||||
.append(" R: ").append(DF.format(new Date(userFile.getClienttimems())))
|
.append(" R: ").append(DF.format(new Date(userFile.getClienttimems())))
|
||||||
.append("\n");
|
.append("\n\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!Algorithms.isEmpty(backupInfo.filesToDelete)) {
|
if (!Algorithms.isEmpty(backupInfo.filesToDelete)) {
|
||||||
sb.append("\n").append("--- Delete ---").append("\n");
|
sb.append("\n").append("--- Delete ---").append("\n\n");
|
||||||
for (UserFile userFile : backupInfo.filesToDelete) {
|
for (UserFile userFile : backupInfo.filesToDelete) {
|
||||||
sb.append(userFile.getName())
|
sb.append(userFile.getName())
|
||||||
.append(" R: ").append(DF.format(new Date(userFile.getClienttimems())))
|
.append(" R: ").append(DF.format(new Date(userFile.getClienttimems())))
|
||||||
.append("\n");
|
.append("\n\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!Algorithms.isEmpty(backupInfo.filesToMerge)) {
|
if (!Algorithms.isEmpty(backupInfo.filesToMerge)) {
|
||||||
sb.append("\n").append("--- Conflicts ---").append("\n");
|
sb.append("\n").append("--- Conflicts ---").append("\n\n");
|
||||||
for (Pair<GpxFileInfo, UserFile> localRemote : backupInfo.filesToMerge) {
|
for (Pair<GpxFileInfo, UserFile> localRemote : backupInfo.filesToMerge) {
|
||||||
GpxFileInfo local = localRemote.first;
|
GpxFileInfo local = localRemote.first;
|
||||||
UserFile remote = localRemote.second;
|
UserFile remote = localRemote.second;
|
||||||
|
@ -305,7 +315,7 @@ public class TestBackupActivity extends OsmandActionBarActivity {
|
||||||
.append(" L: ").append(DF.format(new Date(local.getFileDate())))
|
.append(" L: ").append(DF.format(new Date(local.getFileDate())))
|
||||||
.append(" U: ").append(DF.format(new Date(local.uploadTime)))
|
.append(" U: ").append(DF.format(new Date(local.uploadTime)))
|
||||||
.append(" R: ").append(DF.format(new Date(remote.getClienttimems())))
|
.append(" R: ").append(DF.format(new Date(remote.getClienttimems())))
|
||||||
.append("\n");
|
.append("\n\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
|
|
|
@ -8,6 +8,9 @@ import android.os.AsyncTask;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import net.osmand.AndroidNetworkUtils;
|
import net.osmand.AndroidNetworkUtils;
|
||||||
import net.osmand.AndroidNetworkUtils.OnRequestResultListener;
|
import net.osmand.AndroidNetworkUtils.OnRequestResultListener;
|
||||||
import net.osmand.AndroidNetworkUtils.OnSendRequestsListener;
|
import net.osmand.AndroidNetworkUtils.OnSendRequestsListener;
|
||||||
|
@ -41,9 +44,6 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
public abstract class InAppPurchaseHelper {
|
public abstract class InAppPurchaseHelper {
|
||||||
// Debug tag, for logging
|
// Debug tag, for logging
|
||||||
protected static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(InAppPurchaseHelper.class);
|
protected static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(InAppPurchaseHelper.class);
|
||||||
|
@ -466,7 +466,7 @@ public abstract class InAppPurchaseHelper {
|
||||||
protected void onSkuDetailsResponseDone(List<PurchaseInfo> purchaseInfoList) {
|
protected void onSkuDetailsResponseDone(List<PurchaseInfo> purchaseInfoList) {
|
||||||
final AndroidNetworkUtils.OnRequestResultListener listener = new AndroidNetworkUtils.OnRequestResultListener() {
|
final AndroidNetworkUtils.OnRequestResultListener listener = new AndroidNetworkUtils.OnRequestResultListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onResult(String result) {
|
public void onResult(@Nullable String result, @Nullable String error) {
|
||||||
notifyDismissProgress(InAppPurchaseTaskType.REQUEST_INVENTORY);
|
notifyDismissProgress(InAppPurchaseTaskType.REQUEST_INVENTORY);
|
||||||
notifyGetItems();
|
notifyGetItems();
|
||||||
stop(true);
|
stop(true);
|
||||||
|
@ -477,7 +477,7 @@ public abstract class InAppPurchaseHelper {
|
||||||
if (purchaseInfoList.size() > 0) {
|
if (purchaseInfoList.size() > 0) {
|
||||||
sendTokens(purchaseInfoList, listener);
|
sendTokens(purchaseInfoList, listener);
|
||||||
} else {
|
} else {
|
||||||
listener.onResult("OK");
|
listener.onResult("OK", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -503,7 +503,7 @@ public abstract class InAppPurchaseHelper {
|
||||||
liveUpdatesPurchase.setState(ctx, SubscriptionState.UNDEFINED);
|
liveUpdatesPurchase.setState(ctx, SubscriptionState.UNDEFINED);
|
||||||
sendTokens(Collections.singletonList(info), new OnRequestResultListener() {
|
sendTokens(Collections.singletonList(info), new OnRequestResultListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onResult(String result) {
|
public void onResult(@Nullable String result, @Nullable String error) {
|
||||||
boolean active = ctx.getSettings().LIVE_UPDATES_PURCHASED.get();
|
boolean active = ctx.getSettings().LIVE_UPDATES_PURCHASED.get();
|
||||||
ctx.getSettings().LIVE_UPDATES_PURCHASED.set(true);
|
ctx.getSettings().LIVE_UPDATES_PURCHASED.set(true);
|
||||||
ctx.getSettings().getCustomRenderBooleanProperty("depthContours").set(true);
|
ctx.getSettings().getCustomRenderBooleanProperty("depthContours").set(true);
|
||||||
|
@ -642,7 +642,7 @@ public abstract class InAppPurchaseHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
listener.onResult("OK");
|
listener.onResult("OK", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -695,7 +695,7 @@ public abstract class InAppPurchaseHelper {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logError("SendToken Error", e);
|
logError("SendToken Error", e);
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
listener.onResult("Error");
|
listener.onResult("Error", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import android.content.Context;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import net.osmand.AndroidNetworkUtils;
|
import net.osmand.AndroidNetworkUtils;
|
||||||
import net.osmand.AndroidNetworkUtils.OnRequestResultListener;
|
import net.osmand.AndroidNetworkUtils.OnRequestResultListener;
|
||||||
|
@ -194,7 +195,7 @@ public class PerformLiveUpdateAsyncTask
|
||||||
AndroidNetworkUtils.sendRequestAsync(
|
AndroidNetworkUtils.sendRequestAsync(
|
||||||
app, LiveUpdatesFragment.URL, null, "Requesting map updates info...", false, false, new OnRequestResultListener() {
|
app, LiveUpdatesFragment.URL, null, "Requesting map updates info...", false, false, new OnRequestResultListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onResult(String result) {
|
public void onResult(@Nullable String result, @Nullable String error) {
|
||||||
if (!Algorithms.isEmpty(result)) {
|
if (!Algorithms.isEmpty(result)) {
|
||||||
SimpleDateFormat source = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US);
|
SimpleDateFormat source = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US);
|
||||||
source.setTimeZone(TimeZone.getTimeZone("UTC"));
|
source.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||||
|
|
|
@ -208,7 +208,7 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
|
||||||
"https://osmand.net/subscription/update",
|
"https://osmand.net/subscription/update",
|
||||||
parameters, "Sending data...", true, true, new AndroidNetworkUtils.OnRequestResultListener() {
|
parameters, "Sending data...", true, true, new AndroidNetworkUtils.OnRequestResultListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onResult(String result) {
|
public void onResult(@Nullable String result, @Nullable String error) {
|
||||||
dismissProgress(null);
|
dismissProgress(null);
|
||||||
OsmandApplication app = getMyApplication();
|
OsmandApplication app = getMyApplication();
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
|
|
|
@ -6,6 +6,8 @@ import android.view.View;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import net.osmand.AndroidNetworkUtils;
|
import net.osmand.AndroidNetworkUtils;
|
||||||
import net.osmand.plus.OsmandApplication;
|
import net.osmand.plus.OsmandApplication;
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
|
@ -71,7 +73,7 @@ public class SendSearchQueryBottomSheet extends MenuBottomSheetDialogFragment {
|
||||||
AndroidNetworkUtils.sendRequestAsync(app, "https://osmand.net/api/missing_search", params,
|
AndroidNetworkUtils.sendRequestAsync(app, "https://osmand.net/api/missing_search", params,
|
||||||
null, true, true, new AndroidNetworkUtils.OnRequestResultListener() {
|
null, true, true, new AndroidNetworkUtils.OnRequestResultListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onResult(String result) {
|
public void onResult(@Nullable String result, @Nullable String error) {
|
||||||
if (result != null && isAdded()) {
|
if (result != null && isAdded()) {
|
||||||
try {
|
try {
|
||||||
JSONObject obj = new JSONObject(result);
|
JSONObject obj = new JSONObject(result);
|
||||||
|
|
Loading…
Reference in a new issue