@capgo/capacitor-updater 6.3.18 → 6.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -197,32 +197,32 @@ Capacitor Updater works by unzipping a compiled app bundle to the native device
197
197
 
198
198
  CapacitorUpdater can be configured with these options:
199
199
 
200
- | Prop | Type | Description | Default | Since |
201
- | ------------------------ | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | ------- |
202
- | **`appReadyTimeout`** | <code>number</code> | Configure the number of milliseconds the native plugin should wait before considering an update 'failed'. Only available for Android and iOS. | <code>10000 // (10 seconds)</code> | |
203
- | **`responseTimeout`** | <code>number</code> | Configure the number of milliseconds the native plugin should wait before considering API timeout. Only available for Android and iOS. | <code>20 // (20 second)</code> | |
204
- | **`autoDeleteFailed`** | <code>boolean</code> | Configure whether the plugin should use automatically delete failed bundles. Only available for Android and iOS. | <code>true</code> | |
205
- | **`autoDeletePrevious`** | <code>boolean</code> | Configure whether the plugin should use automatically delete previous bundles after a successful update. Only available for Android and iOS. | <code>true</code> | |
206
- | **`autoUpdate`** | <code>boolean</code> | Configure whether the plugin should use Auto Update via an update server. Only available for Android and iOS. | <code>true</code> | |
207
- | **`resetWhenUpdate`** | <code>boolean</code> | Automatically delete previous downloaded bundles when a newer native app bundle is installed to the device. Only available for Android and iOS. | <code>true</code> | |
208
- | **`updateUrl`** | <code>string</code> | Configure the URL / endpoint to which update checks are sent. Only available for Android and iOS. | <code>https://api.capgo.app/updates</code> | |
209
- | **`channelUrl`** | <code>string</code> | Configure the URL / endpoint for channel operations. Only available for Android and iOS. | <code>https://api.capgo.app/channel_self</code> | |
210
- | **`statsUrl`** | <code>string</code> | Configure the URL / endpoint to which update statistics are sent. Only available for Android and iOS. Set to "" to disable stats reporting. | <code>https://api.capgo.app/stats</code> | |
211
- | **`privateKey`** | <code>string</code> | Configure the private key for end to end live update encryption. Only available for Android and iOS. | <code>undefined</code> | |
212
- | **`publicKey`** | <code>string</code> | Configure the public key for end to end live update encryption Version 2 Only available for Android and iOS. | <code>undefined</code> | 6.2.0 |
213
- | **`version`** | <code>string</code> | Configure the current version of the app. This will be used for the first update request. If not set, the plugin will get the version from the native code. Only available for Android and iOS. | <code>undefined</code> | 4.17.48 |
214
- | **`directUpdate`** | <code>boolean</code> | Make the plugin direct install the update when the app what just updated/installed. Only for autoUpdate mode. Only available for Android and iOS. | <code>undefined</code> | 5.1.0 |
215
- | **`periodCheckDelay`** | <code>number</code> | Configure the delay period for period update check. the unit is in seconds. Only available for Android and iOS. Cannot be less than 600 seconds (10 minutes). | <code>600 // (10 minutes)</code> | |
216
- | **`localS3`** | <code>boolean</code> | Configure the CLI to use a local server for testing or self-hosted update server. | <code>undefined</code> | 4.17.48 |
217
- | **`localHost`** | <code>string</code> | Configure the CLI to use a local server for testing or self-hosted update server. | <code>undefined</code> | 4.17.48 |
218
- | **`localWebHost`** | <code>string</code> | Configure the CLI to use a local server for testing or self-hosted update server. | <code>undefined</code> | 4.17.48 |
219
- | **`localSupa`** | <code>string</code> | Configure the CLI to use a local server for testing or self-hosted update server. | <code>undefined</code> | 4.17.48 |
220
- | **`localSupaAnon`** | <code>string</code> | Configure the CLI to use a local server for testing. | <code>undefined</code> | 4.17.48 |
221
- | **`localApi`** | <code>string</code> | Configure the CLI to use a local api for testing. | <code>undefined</code> | 6.3.3 |
222
- | **`localApiFiles`** | <code>string</code> | Configure the CLI to use a local file api for testing. | <code>undefined</code> | 6.3.3 |
223
- | **`allowModifyUrl`** | <code>boolean</code> | Allow the plugin to modify the updateUrl, statsUrl and channelUrl dynamically from the JavaScript side. | <code>false</code> | 5.4.0 |
224
- | **`defaultChannel`** | <code>string</code> | Set the default channel for the app in the config. | <code>undefined</code> | 5.5.0 |
225
- | **`appId`** | <code>string</code> | Configure the app id for the app in the config. | <code>undefined</code> | 6.0.0 |
200
+ | Prop | Type | Description | Default | Since |
201
+ | ------------------------ | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | ------- |
202
+ | **`appReadyTimeout`** | <code>number</code> | Configure the number of milliseconds the native plugin should wait before considering an update 'failed'. Only available for Android and iOS. | <code>10000 // (10 seconds)</code> | |
203
+ | **`responseTimeout`** | <code>number</code> | Configure the number of milliseconds the native plugin should wait before considering API timeout. Only available for Android and iOS. | <code>20 // (20 second)</code> | |
204
+ | **`autoDeleteFailed`** | <code>boolean</code> | Configure whether the plugin should use automatically delete failed bundles. Only available for Android and iOS. | <code>true</code> | |
205
+ | **`autoDeletePrevious`** | <code>boolean</code> | Configure whether the plugin should use automatically delete previous bundles after a successful update. Only available for Android and iOS. | <code>true</code> | |
206
+ | **`autoUpdate`** | <code>boolean</code> | Configure whether the plugin should use Auto Update via an update server. Only available for Android and iOS. | <code>true</code> | |
207
+ | **`resetWhenUpdate`** | <code>boolean</code> | Automatically delete previous downloaded bundles when a newer native app bundle is installed to the device. Only available for Android and iOS. | <code>true</code> | |
208
+ | **`updateUrl`** | <code>string</code> | Configure the URL / endpoint to which update checks are sent. Only available for Android and iOS. | <code>https://plugin.capgo.app/updates</code> | |
209
+ | **`channelUrl`** | <code>string</code> | Configure the URL / endpoint for channel operations. Only available for Android and iOS. | <code>https://plugin.capgo.app/channel_self</code> | |
210
+ | **`statsUrl`** | <code>string</code> | Configure the URL / endpoint to which update statistics are sent. Only available for Android and iOS. Set to "" to disable stats reporting. | <code>https://plugin.capgo.app/stats</code> | |
211
+ | **`privateKey`** | <code>string</code> | Configure the private key for end to end live update encryption. Only available for Android and iOS. Deprecated in version 6.2.0. will be removed in version 7.0.0. | <code>undefined</code> | |
212
+ | **`publicKey`** | <code>string</code> | Configure the public key for end to end live update encryption Version 2 Only available for Android and iOS. | <code>undefined</code> | 6.2.0 |
213
+ | **`version`** | <code>string</code> | Configure the current version of the app. This will be used for the first update request. If not set, the plugin will get the version from the native code. Only available for Android and iOS. | <code>undefined</code> | 4.17.48 |
214
+ | **`directUpdate`** | <code>boolean</code> | Make the plugin direct install the update when the app what just updated/installed. Only for autoUpdate mode. Only available for Android and iOS. | <code>undefined</code> | 5.1.0 |
215
+ | **`periodCheckDelay`** | <code>number</code> | Configure the delay period for period update check. the unit is in seconds. Only available for Android and iOS. Cannot be less than 600 seconds (10 minutes). | <code>600 // (10 minutes)</code> | |
216
+ | **`localS3`** | <code>boolean</code> | Configure the CLI to use a local server for testing or self-hosted update server. | <code>undefined</code> | 4.17.48 |
217
+ | **`localHost`** | <code>string</code> | Configure the CLI to use a local server for testing or self-hosted update server. | <code>undefined</code> | 4.17.48 |
218
+ | **`localWebHost`** | <code>string</code> | Configure the CLI to use a local server for testing or self-hosted update server. | <code>undefined</code> | 4.17.48 |
219
+ | **`localSupa`** | <code>string</code> | Configure the CLI to use a local server for testing or self-hosted update server. | <code>undefined</code> | 4.17.48 |
220
+ | **`localSupaAnon`** | <code>string</code> | Configure the CLI to use a local server for testing. | <code>undefined</code> | 4.17.48 |
221
+ | **`localApi`** | <code>string</code> | Configure the CLI to use a local api for testing. | <code>undefined</code> | 6.3.3 |
222
+ | **`localApiFiles`** | <code>string</code> | Configure the CLI to use a local file api for testing. | <code>undefined</code> | 6.3.3 |
223
+ | **`allowModifyUrl`** | <code>boolean</code> | Allow the plugin to modify the updateUrl, statsUrl and channelUrl dynamically from the JavaScript side. | <code>false</code> | 5.4.0 |
224
+ | **`defaultChannel`** | <code>string</code> | Set the default channel for the app in the config. | <code>undefined</code> | 5.5.0 |
225
+ | **`appId`** | <code>string</code> | Configure the app id for the app in the config. | <code>undefined</code> | 6.0.0 |
226
226
 
227
227
  ### Examples
228
228
 
@@ -591,6 +591,7 @@ setChannel(options: SetChannelOptions) => Promise<ChannelRes>
591
591
  Sets the channel for this device. The channel has to allow for self assignment for this to work.
592
592
  Do not use this method to set the channel at boot when `autoUpdate` is enabled in the {@link PluginsConfig}.
593
593
  This method is to set the channel after the app is ready.
594
+ This methods send to Capgo backend a request to link the device ID to the channel. Capgo can accept or refuse depending of the setting of your channel.
594
595
 
595
596
  | Param | Type | Description |
596
597
  | ------------- | --------------------------------------------------------------- | -------------------------------------------------------------------------------- |
@@ -52,11 +52,12 @@ dependencies {
52
52
  implementation fileTree(dir: 'libs', include: ['*.jar'])
53
53
  implementation project(':capacitor-android')
54
54
  implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
55
- implementation 'com.android.volley:volley:1.2.1'
55
+ // implementation 'com.android.volley:volley:1.2.1'
56
56
  implementation 'io.github.g00fy2:versioncompare:1.5.0'
57
57
  implementation 'com.google.code.gson:gson:2.11.0'
58
58
  testImplementation "junit:junit:$junitVersion"
59
59
  androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
60
60
  androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
61
61
  implementation 'org.brotli:dec:0.1.2'
62
+ implementation 'com.squareup.okhttp3:okhttp:4.12.0'
62
63
  }
@@ -8,6 +8,7 @@ package ee.forgr.capacitor_updater;
8
8
 
9
9
  import static android.content.Context.RECEIVER_NOT_EXPORTED;
10
10
 
11
+ import android.annotation.SuppressLint;
11
12
  import android.app.Activity;
12
13
  import android.content.BroadcastReceiver;
13
14
  import android.content.Context;
@@ -18,14 +19,6 @@ import android.os.Build;
18
19
  import android.os.Bundle;
19
20
  import android.util.Base64;
20
21
  import android.util.Log;
21
- import com.android.volley.BuildConfig;
22
- import com.android.volley.DefaultRetryPolicy;
23
- import com.android.volley.NetworkResponse;
24
- import com.android.volley.Request;
25
- import com.android.volley.RequestQueue;
26
- import com.android.volley.VolleyError;
27
- import com.android.volley.toolbox.HttpHeaderParser;
28
- import com.android.volley.toolbox.JsonObjectRequest;
29
22
  import com.getcapacitor.JSObject;
30
23
  import com.getcapacitor.plugin.WebView;
31
24
  import java.io.BufferedInputStream;
@@ -37,7 +30,6 @@ import java.io.FileOutputStream;
37
30
  import java.io.FilenameFilter;
38
31
  import java.io.IOException;
39
32
  import java.io.InputStream;
40
- import java.io.UnsupportedEncodingException;
41
33
  import java.net.URL;
42
34
  import java.net.URLConnection;
43
35
  import java.security.GeneralSecurityException;
@@ -54,6 +46,7 @@ import java.util.zip.CRC32;
54
46
  import java.util.zip.ZipEntry;
55
47
  import java.util.zip.ZipInputStream;
56
48
  import javax.crypto.SecretKey;
49
+ import okhttp3.*;
57
50
  import org.json.JSONArray;
58
51
  import org.json.JSONException;
59
52
  import org.json.JSONObject;
@@ -74,7 +67,7 @@ public class CapacitorUpdater {
74
67
  public SharedPreferences.Editor editor;
75
68
  public SharedPreferences prefs;
76
69
 
77
- public RequestQueue requestQueue;
70
+ public OkHttpClient client;
78
71
 
79
72
  public File documentsDir;
80
73
  public Boolean directUpdate = false;
@@ -105,7 +98,13 @@ public class CapacitorUpdater {
105
98
  };
106
99
 
107
100
  private boolean isProd() {
108
- return !BuildConfig.DEBUG;
101
+ try {
102
+ return !Objects.requireNonNull(getClass().getPackage())
103
+ .getName()
104
+ .contains(".debug");
105
+ } catch (Exception e) {
106
+ return true; // Default to production if we can't determine
107
+ }
109
108
  }
110
109
 
111
110
  private boolean isEmulator() {
@@ -252,6 +251,7 @@ public class CapacitorUpdater {
252
251
  sourceFile.delete();
253
252
  }
254
253
 
254
+ @SuppressLint("UnspecifiedRegisterReceiverFlag")
255
255
  public void onResume() {
256
256
  IntentFilter filter = new IntentFilter();
257
257
  filter.addAction(DownloadService.NOTIFICATION);
@@ -478,9 +478,15 @@ public class CapacitorUpdater {
478
478
  intent.putExtra(DownloadService.SESSIONKEY, sessionKey);
479
479
  intent.putExtra(DownloadService.CHECKSUM, checksum);
480
480
  if (manifest != null) {
481
- intent.putExtra(DownloadService.MANIFEST, manifest.toString());
481
+ DataManager.getInstance().setManifest(manifest);
482
+ intent.putExtra(DownloadService.IS_MANIFEST, true);
483
+ }
484
+
485
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
486
+ this.activity.startForegroundService(intent);
487
+ } else {
488
+ this.activity.startService(intent);
482
489
  }
483
- this.activity.startService(intent);
484
490
  }
485
491
 
486
492
  private void downloadFile(
@@ -954,36 +960,65 @@ public class CapacitorUpdater {
954
960
  return json;
955
961
  }
956
962
 
957
- private JsonObjectRequest setRetryPolicy(JsonObjectRequest request) {
958
- request.setRetryPolicy(
959
- new DefaultRetryPolicy(
960
- this.timeout,
961
- DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
962
- DefaultRetryPolicy.DEFAULT_BACKOFF_MULT
963
- )
964
- );
965
- return request;
966
- }
963
+ private void makeJsonRequest(
964
+ String url,
965
+ JSONObject jsonBody,
966
+ Callback callback
967
+ ) {
968
+ MediaType JSON = MediaType.get("application/json; charset=utf-8");
969
+ RequestBody body = RequestBody.create(jsonBody.toString(), JSON);
970
+
971
+ Request request = new Request.Builder().url(url).post(body).build();
972
+
973
+ client
974
+ .newCall(request)
975
+ .enqueue(
976
+ new okhttp3.Callback() {
977
+ @Override
978
+ public void onFailure(Call call, IOException e) {
979
+ JSObject retError = new JSObject();
980
+ retError.put("message", "Request failed: " + e.getMessage());
981
+ retError.put("error", "network_error");
982
+ callback.callback(retError);
983
+ }
967
984
 
968
- private JSObject createError(String message, VolleyError error) {
969
- NetworkResponse response = error.networkResponse;
970
- final JSObject retError = new JSObject();
971
- retError.put("error", "response_error");
972
- if (response != null) {
973
- try {
974
- String json = new String(
975
- response.data,
976
- HttpHeaderParser.parseCharset(response.headers)
977
- );
978
- retError.put("message", message + ": " + json);
979
- } catch (UnsupportedEncodingException e) {
980
- retError.put("message", message + ": " + e);
981
- }
982
- } else {
983
- retError.put("message", message + ": " + error);
984
- }
985
- Log.e(TAG, message + ": " + retError);
986
- return retError;
985
+ @Override
986
+ public void onResponse(Call call, Response response)
987
+ throws IOException {
988
+ try (ResponseBody responseBody = response.body()) {
989
+ if (!response.isSuccessful()) {
990
+ JSObject retError = new JSObject();
991
+ retError.put("message", "Server error: " + response.code());
992
+ retError.put("error", "response_error");
993
+ callback.callback(retError);
994
+ return;
995
+ }
996
+
997
+ String responseData = responseBody.string();
998
+ JSONObject jsonResponse = new JSONObject(responseData);
999
+ JSObject ret = new JSObject();
1000
+
1001
+ Iterator<String> keys = jsonResponse.keys();
1002
+ while (keys.hasNext()) {
1003
+ String key = keys.next();
1004
+ if (jsonResponse.has(key)) {
1005
+ if ("session_key".equals(key)) {
1006
+ ret.put("sessionKey", jsonResponse.get(key));
1007
+ } else {
1008
+ ret.put(key, jsonResponse.get(key));
1009
+ }
1010
+ }
1011
+ }
1012
+ callback.callback(ret);
1013
+ } catch (JSONException e) {
1014
+ JSObject retError = new JSObject();
1015
+ retError.put("message", "JSON parse error: " + e.getMessage());
1016
+ retError.put("error", "parse_error");
1017
+ callback.callback(retError);
1018
+ }
1019
+ }
1020
+ }
1021
+ );
987
1022
  }
988
1023
 
989
1024
  public void getLatest(final String updateUrl, final Callback callback) {
@@ -992,7 +1027,6 @@ public class CapacitorUpdater {
992
1027
  json = this.createInfoObject();
993
1028
  } catch (JSONException e) {
994
1029
  Log.e(TAG, "Error getLatest JSONException", e);
995
- e.printStackTrace();
996
1030
  final JSObject retError = new JSObject();
997
1031
  retError.put("message", "Cannot get info: " + e);
998
1032
  retError.put("error", "json_error");
@@ -1001,40 +1035,8 @@ public class CapacitorUpdater {
1001
1035
  }
1002
1036
 
1003
1037
  Log.i(CapacitorUpdater.TAG, "Auto-update parameters: " + json);
1004
- // Building a request
1005
- JsonObjectRequest request = new JsonObjectRequest(
1006
- Request.Method.POST,
1007
- updateUrl,
1008
- json,
1009
- res -> {
1010
- final JSObject ret = new JSObject();
1011
- Iterator<String> keys = res.keys();
1012
- while (keys.hasNext()) {
1013
- String key = keys.next();
1014
- if (res.has(key)) {
1015
- try {
1016
- if ("session_key".equals(key)) {
1017
- ret.put("sessionKey", res.get(key));
1018
- } else {
1019
- ret.put(key, res.get(key));
1020
- }
1021
- } catch (JSONException e) {
1022
- e.printStackTrace();
1023
- final JSObject retError = new JSObject();
1024
- retError.put("message", "Cannot set info: " + e);
1025
- retError.put("error", "response_error");
1026
- callback.callback(retError);
1027
- }
1028
- }
1029
- }
1030
- callback.callback(ret);
1031
- },
1032
- error ->
1033
- callback.callback(
1034
- CapacitorUpdater.this.createError("Error get latest", error)
1035
- )
1036
- );
1037
- this.requestQueue.add(setRetryPolicy(request));
1038
+
1039
+ makeJsonRequest(updateUrl, json, callback);
1038
1040
  }
1039
1041
 
1040
1042
  public void unsetChannel(final Callback callback) {
@@ -1052,44 +1054,66 @@ public class CapacitorUpdater {
1052
1054
  json = this.createInfoObject();
1053
1055
  } catch (JSONException e) {
1054
1056
  Log.e(TAG, "Error unsetChannel JSONException", e);
1055
- e.printStackTrace();
1056
1057
  final JSObject retError = new JSObject();
1057
1058
  retError.put("message", "Cannot get info: " + e);
1058
1059
  retError.put("error", "json_error");
1059
1060
  callback.callback(retError);
1060
1061
  return;
1061
1062
  }
1062
- // Building a request
1063
- JsonObjectRequest request = new JsonObjectRequest(
1064
- Request.Method.DELETE,
1065
- channelUrl,
1066
- json,
1067
- res -> {
1068
- final JSObject ret = new JSObject();
1069
- Iterator<String> keys = res.keys();
1070
- while (keys.hasNext()) {
1071
- String key = keys.next();
1072
- if (res.has(key)) {
1073
- try {
1074
- ret.put(key, res.get(key));
1075
- } catch (JSONException e) {
1076
- e.printStackTrace();
1077
- final JSObject retError = new JSObject();
1078
- retError.put("message", "Cannot unset channel: " + e);
1079
- retError.put("error", "response_error");
1063
+
1064
+ Request request = new Request.Builder()
1065
+ .url(channelUrl)
1066
+ .delete(
1067
+ RequestBody.create(json.toString(), MediaType.get("application/json"))
1068
+ )
1069
+ .build();
1070
+
1071
+ client
1072
+ .newCall(request)
1073
+ .enqueue(
1074
+ new okhttp3.Callback() {
1075
+ @Override
1076
+ public void onFailure(Call call, IOException e) {
1077
+ JSObject retError = new JSObject();
1078
+ retError.put("message", "Request failed: " + e.getMessage());
1079
+ retError.put("error", "network_error");
1080
+ callback.callback(retError);
1081
+ }
1082
+
1083
+ @Override
1084
+ public void onResponse(Call call, Response response)
1085
+ throws IOException {
1086
+ try (ResponseBody responseBody = response.body()) {
1087
+ if (!response.isSuccessful()) {
1088
+ JSObject retError = new JSObject();
1089
+ retError.put("message", "Server error: " + response.code());
1090
+ retError.put("error", "response_error");
1091
+ callback.callback(retError);
1092
+ return;
1093
+ }
1094
+
1095
+ String responseData = responseBody.string();
1096
+ JSONObject jsonResponse = new JSONObject(responseData);
1097
+ JSObject ret = new JSObject();
1098
+
1099
+ Iterator<String> keys = jsonResponse.keys();
1100
+ while (keys.hasNext()) {
1101
+ String key = keys.next();
1102
+ if (jsonResponse.has(key)) {
1103
+ ret.put(key, jsonResponse.get(key));
1104
+ }
1105
+ }
1106
+ Log.i(TAG, "Channel unset");
1080
1107
  callback.callback(ret);
1108
+ } catch (JSONException e) {
1109
+ JSObject retError = new JSObject();
1110
+ retError.put("message", "JSON parse error: " + e.getMessage());
1111
+ retError.put("error", "parse_error");
1112
+ callback.callback(retError);
1081
1113
  }
1082
1114
  }
1083
1115
  }
1084
- Log.i(TAG, "Channel unset");
1085
- callback.callback(ret);
1086
- },
1087
- error ->
1088
- callback.callback(
1089
- CapacitorUpdater.this.createError("Error unset channel", error)
1090
- )
1091
- );
1092
- this.requestQueue.add(setRetryPolicy(request));
1116
+ );
1093
1117
  }
1094
1118
 
1095
1119
  public void setChannel(final String channel, final Callback callback) {
@@ -1108,44 +1132,14 @@ public class CapacitorUpdater {
1108
1132
  json.put("channel", channel);
1109
1133
  } catch (JSONException e) {
1110
1134
  Log.e(TAG, "Error setChannel JSONException", e);
1111
- e.printStackTrace();
1112
1135
  final JSObject retError = new JSObject();
1113
1136
  retError.put("message", "Cannot get info: " + e);
1114
1137
  retError.put("error", "json_error");
1115
1138
  callback.callback(retError);
1116
1139
  return;
1117
1140
  }
1118
- // Building a request
1119
- JsonObjectRequest request = new JsonObjectRequest(
1120
- Request.Method.POST,
1121
- channelUrl,
1122
- json,
1123
- res -> {
1124
- final JSObject ret = new JSObject();
1125
- Iterator<String> keys = res.keys();
1126
- while (keys.hasNext()) {
1127
- String key = keys.next();
1128
- if (res.has(key)) {
1129
- try {
1130
- ret.put(key, res.get(key));
1131
- } catch (JSONException e) {
1132
- e.printStackTrace();
1133
- final JSObject retError = new JSObject();
1134
- retError.put("message", "Cannot set channel: " + e);
1135
- retError.put("error", "response_error");
1136
- callback.callback(ret);
1137
- }
1138
- }
1139
- }
1140
- Log.i(TAG, "Channel set to \"" + channel);
1141
- callback.callback(ret);
1142
- },
1143
- error ->
1144
- callback.callback(
1145
- CapacitorUpdater.this.createError("Error set channel", error)
1146
- )
1147
- );
1148
- this.requestQueue.add(setRetryPolicy(request));
1141
+
1142
+ makeJsonRequest(channelUrl, json, callback);
1149
1143
  }
1150
1144
 
1151
1145
  public void getChannel(final Callback callback) {
@@ -1163,40 +1157,81 @@ public class CapacitorUpdater {
1163
1157
  json = this.createInfoObject();
1164
1158
  } catch (JSONException e) {
1165
1159
  Log.e(TAG, "Error getChannel JSONException", e);
1166
- e.printStackTrace();
1167
1160
  final JSObject retError = new JSObject();
1168
1161
  retError.put("message", "Cannot get info: " + e);
1169
1162
  retError.put("error", "json_error");
1170
1163
  callback.callback(retError);
1171
1164
  return;
1172
1165
  }
1173
- // Building a request
1174
- JsonObjectRequest request = new JsonObjectRequest(
1175
- Request.Method.PUT,
1176
- channelUrl,
1177
- json,
1178
- res -> {
1179
- final JSObject ret = new JSObject();
1180
- Iterator<String> keys = res.keys();
1181
- while (keys.hasNext()) {
1182
- String key = keys.next();
1183
- if (res.has(key)) {
1184
- try {
1185
- ret.put(key, res.get(key));
1166
+
1167
+ Request request = new Request.Builder()
1168
+ .url(channelUrl)
1169
+ .put(
1170
+ RequestBody.create(json.toString(), MediaType.get("application/json"))
1171
+ )
1172
+ .build();
1173
+
1174
+ client
1175
+ .newCall(request)
1176
+ .enqueue(
1177
+ new okhttp3.Callback() {
1178
+ @Override
1179
+ public void onFailure(Call call, IOException e) {
1180
+ JSObject retError = new JSObject();
1181
+ retError.put("message", "Request failed: " + e.getMessage());
1182
+ retError.put("error", "network_error");
1183
+ callback.callback(retError);
1184
+ }
1185
+
1186
+ @Override
1187
+ public void onResponse(Call call, Response response)
1188
+ throws IOException {
1189
+ try (ResponseBody responseBody = response.body()) {
1190
+ if (response.code() == 400) {
1191
+ String data = responseBody.string();
1192
+ if (
1193
+ data.contains("channel_not_found") &&
1194
+ !defaultChannel.isEmpty()
1195
+ ) {
1196
+ JSObject ret = new JSObject();
1197
+ ret.put("channel", defaultChannel);
1198
+ ret.put("status", "default");
1199
+ Log.i(TAG, "Channel get to \"" + ret);
1200
+ callback.callback(ret);
1201
+ return;
1202
+ }
1203
+ }
1204
+
1205
+ if (!response.isSuccessful()) {
1206
+ JSObject retError = new JSObject();
1207
+ retError.put("message", "Server error: " + response.code());
1208
+ retError.put("error", "response_error");
1209
+ callback.callback(retError);
1210
+ return;
1211
+ }
1212
+
1213
+ String responseData = responseBody.string();
1214
+ JSONObject jsonResponse = new JSONObject(responseData);
1215
+ JSObject ret = new JSObject();
1216
+
1217
+ Iterator<String> keys = jsonResponse.keys();
1218
+ while (keys.hasNext()) {
1219
+ String key = keys.next();
1220
+ if (jsonResponse.has(key)) {
1221
+ ret.put(key, jsonResponse.get(key));
1222
+ }
1223
+ }
1224
+ Log.i(TAG, "Channel get to \"" + ret);
1225
+ callback.callback(ret);
1186
1226
  } catch (JSONException e) {
1187
- e.printStackTrace();
1227
+ JSObject retError = new JSObject();
1228
+ retError.put("message", "JSON parse error: " + e.getMessage());
1229
+ retError.put("error", "parse_error");
1230
+ callback.callback(retError);
1188
1231
  }
1189
1232
  }
1190
1233
  }
1191
- Log.i(TAG, "Channel get to \"" + ret);
1192
- callback.callback(ret);
1193
- },
1194
- error ->
1195
- callback.callback(
1196
- CapacitorUpdater.this.createError("Error get channel", error)
1197
- )
1198
- );
1199
- this.requestQueue.add(setRetryPolicy(request));
1234
+ );
1200
1235
  }
1201
1236
 
1202
1237
  public void sendStats(final String action) {
@@ -1224,19 +1259,39 @@ public class CapacitorUpdater {
1224
1259
  json.put("action", action);
1225
1260
  } catch (JSONException e) {
1226
1261
  Log.e(TAG, "Error sendStats JSONException", e);
1227
- e.printStackTrace();
1228
1262
  return;
1229
1263
  }
1230
- // Building a request
1231
- JsonObjectRequest request = new JsonObjectRequest(
1232
- Request.Method.POST,
1233
- statsUrl,
1234
- json,
1235
- response ->
1236
- Log.i(TAG, "Stats send for \"" + action + "\", version " + versionName),
1237
- error -> CapacitorUpdater.this.createError("Error send stats", error)
1238
- );
1239
- this.requestQueue.add(setRetryPolicy(request));
1264
+
1265
+ Request request = new Request.Builder()
1266
+ .url(statsUrl)
1267
+ .post(
1268
+ RequestBody.create(json.toString(), MediaType.get("application/json"))
1269
+ )
1270
+ .build();
1271
+
1272
+ client
1273
+ .newCall(request)
1274
+ .enqueue(
1275
+ new okhttp3.Callback() {
1276
+ @Override
1277
+ public void onFailure(Call call, IOException e) {
1278
+ Log.e(TAG, "Failed to send stats: " + e.getMessage());
1279
+ }
1280
+
1281
+ @Override
1282
+ public void onResponse(Call call, Response response)
1283
+ throws IOException {
1284
+ if (response.isSuccessful()) {
1285
+ Log.i(
1286
+ TAG,
1287
+ "Stats send for \"" + action + "\", version " + versionName
1288
+ );
1289
+ } else {
1290
+ Log.e(TAG, "Error sending stats: " + response.code());
1291
+ }
1292
+ }
1293
+ }
1294
+ );
1240
1295
  }
1241
1296
 
1242
1297
  public BundleInfo getBundleInfo(final String id) {