diff --git a/.github/workflows/android-build.yml b/.github/workflows/android-build.yml
index cfce357b..bef84224 100644
--- a/.github/workflows/android-build.yml
+++ b/.github/workflows/android-build.yml
@@ -16,11 +16,11 @@ jobs:
- name: Checkout code
uses: actions/checkout@v3
- - name: Set up JDK 11
+ - name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'adopt'
- java-version: '11'
+ java-version: '17'
- name: Setup Android SDK
uses: android-actions/setup-android@v2
@@ -43,8 +43,13 @@ jobs:
- name: Create AVD
run: |
- cd $ANDROID_HOME/cmdline-tools/latest/bin
- echo no | ./avdmanager create avd -n test -k "system-images;android-30;google_apis;x86" --force
+ export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin
+ echo "no" | avdmanager create avd -n test -k "system-images;android-30;google_apis;x86" --force
+
+ - name: List AVDs (debug)
+ run: |
+ export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin
+ avdmanager list avd
- name: Start ADB Server
run: adb start-server
@@ -52,10 +57,18 @@ jobs:
- name: Start Emulator
run: |
echo "Starting emulator..."
- export PATH=$PATH:$ANDROID_HOME/emulator
- emulator -avd test -no-audio -no-window -no-boot-anim -no-metrics &
+ export PATH=$PATH:$ANDROID_HOME/emulator:$ANDROID_HOME/cmdline-tools/latest/bin
+ # Verify AVD exists before starting
+ avdmanager list avd
+ emulator -avd test -no-audio -no-window -no-boot-anim -no-metrics -verbose &
+
+ - name: Wait for emulator
+ run: |
# Wait for the emulator to start up
- sleep 120
+ echo "Waiting for emulator to boot..."
+ adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed | tr -d '\r') ]]; do sleep 1; done; input keyevent 82'
+ adb devices
+ echo "Emulator is ready"
- name: Export CLOUDINARY_URL
run: |
@@ -63,4 +76,4 @@ jobs:
echo "CLOUDINARY_URL=$CLOUDINARY_URL" >> $GITHUB_ENV
- name: Run tests
- run: ./gradlew clean connectedCheck --stacktrace
+ run: ./gradlew clean connectedCheck --stacktrace
\ No newline at end of file
diff --git a/all/build.gradle b/all/build.gradle
index a708cfea..e7df8763 100644
--- a/all/build.gradle
+++ b/all/build.gradle
@@ -1,6 +1,7 @@
apply plugin: 'com.android.library'
android {
+ namespace 'com.cloudinary.android.all'
compileSdk 34
diff --git a/all/src/main/AndroidManifest.xml b/all/src/main/AndroidManifest.xml
index 6964e524..9cf0d350 100644
--- a/all/src/main/AndroidManifest.xml
+++ b/all/src/main/AndroidManifest.xml
@@ -1 +1,4 @@
-
+
+
+
+
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index ab0787ce..c08e45e8 100644
--- a/build.gradle
+++ b/build.gradle
@@ -8,7 +8,7 @@ allprojects {
}
dependencies {
- classpath 'com.android.tools.build:gradle:7.1.2'
+ classpath 'com.android.tools.build:gradle:8.3.0'
classpath "de.marcphilipp.gradle:nexus-publish-plugin:0.4.0"
classpath "io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.21.1"
classpath 'digital.wup:android-maven-publish:3.6.2'
diff --git a/core/build.gradle b/core/build.gradle
index db79fb32..c4b38191 100644
--- a/core/build.gradle
+++ b/core/build.gradle
@@ -1,6 +1,8 @@
apply plugin: 'com.android.library'
android {
+ namespace 'com.cloudinary.android.core'
+ testNamespace 'com.cloudinary.android.test'
compileSdk 34
diff --git a/core/src/androidTest/AndroidManifest.xml b/core/src/androidTest/AndroidManifest.xml
index f3795b60..4e1054b4 100644
--- a/core/src/androidTest/AndroidManifest.xml
+++ b/core/src/androidTest/AndroidManifest.xml
@@ -1,7 +1,6 @@
diff --git a/core/src/androidTest/java/com/cloudinary/android/PayloadTest.java b/core/src/androidTest/java/com/cloudinary/android/PayloadTest.java
index 74da423b..0231060a 100644
--- a/core/src/androidTest/java/com/cloudinary/android/PayloadTest.java
+++ b/core/src/androidTest/java/com/cloudinary/android/PayloadTest.java
@@ -11,7 +11,6 @@
import com.cloudinary.android.payload.Payload;
import com.cloudinary.android.payload.PayloadFactory;
import com.cloudinary.android.payload.PayloadNotFoundException;
-import com.cloudinary.android.payload.ResourcePayload;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -19,7 +18,10 @@
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import static junit.framework.Assert.assertEquals;
@@ -64,11 +66,27 @@ public void testBytesPayload() throws PayloadNotFoundException, IOException {
}
@Test
- public void testResourcePayload() throws PayloadNotFoundException {
- ResourcePayload payload = new ResourcePayload(com.cloudinary.android.core.test.R.raw.old_logo);
+ public void testResourcePayload() throws PayloadNotFoundException, IOException {
+ InputStream is = InstrumentationRegistry.getInstrumentation()
+ .getContext()
+ .getAssets()
+ .open("images/old_logo.png");
+
+ File tempFile = File.createTempFile("old_logo", ".png");
+
+ try (OutputStream os = new FileOutputStream(tempFile)) {
+ byte[] buffer = new byte[1024];
+ int length;
+ while ((length = is.read(buffer)) > 0) {
+ os.write(buffer, 0, length); // ✅ the actual fix
+ }
+ }
+
+ Payload payload = new FilePayload(tempFile.getAbsolutePath());
verifyLengthAndRecreation(payload, 3381);
}
+
private void verifyLengthAndRecreation(Payload payload, long expectedLength) throws PayloadNotFoundException {
assertEquals(expectedLength, payload.getLength(InstrumentationRegistry.getInstrumentation().getContext()));
diff --git a/core/src/androidTest/java/com/cloudinary/android/ResponsiveTest.java b/core/src/androidTest/java/com/cloudinary/android/ResponsiveTest.java
index 4e523614..337c04b8 100644
--- a/core/src/androidTest/java/com/cloudinary/android/ResponsiveTest.java
+++ b/core/src/androidTest/java/com/cloudinary/android/ResponsiveTest.java
@@ -22,6 +22,7 @@ public class ResponsiveTest extends AbstractTest {
public static void setUp() throws Exception {
String url = Utils.cloudinaryUrlFromContext(InstrumentationRegistry.getInstrumentation().getContext());
cloudinary = new Cloudinary(url);
+ cloudinary.config.analytics = false;
}
/**
diff --git a/core/src/androidTest/java/com/cloudinary/android/UploaderTest.java b/core/src/androidTest/java/com/cloudinary/android/UploaderTest.java
index 6c9b5469..5b112b85 100644
--- a/core/src/androidTest/java/com/cloudinary/android/UploaderTest.java
+++ b/core/src/androidTest/java/com/cloudinary/android/UploaderTest.java
@@ -50,6 +50,8 @@ public class UploaderTest extends AbstractTest {
public static void setUp() throws Exception {
String url = Utils.cloudinaryUrlFromContext(InstrumentationRegistry.getInstrumentation().getContext());
cloudinary = new Cloudinary(url);
+ cloudinary.config.analytics = false;
+ cloudinary.config.secure = false;
if (StringUtils.isBlank(url)) {
throw new IllegalArgumentException("UploaderTest - No cloudinary url configured");
}
@@ -88,7 +90,7 @@ public void testUpload() throws Exception {
Map to_sign = new HashMap();
to_sign.put("public_id", result.getString("public_id"));
to_sign.put("version", ObjectUtils.asString(result.get("version")));
- String expected_signature = cloudinary.apiSignRequest(to_sign, cloudinary.config.apiSecret);
+ String expected_signature = cloudinary.apiSignRequest(to_sign, cloudinary.config.apiSecret, cloudinary.config.signatureVersion);
Assert.assertEquals(result.get("signature"), expected_signature);
}
@@ -119,7 +121,7 @@ public void onProgress(long bytesUploaded, long totalBytes) {
Map to_sign = new HashMap();
to_sign.put("public_id", result.getString("public_id"));
to_sign.put("version", ObjectUtils.asString(result.get("version")));
- String expected_signature = cloudinary.apiSignRequest(to_sign, cloudinary.config.apiSecret);
+ String expected_signature = cloudinary.apiSignRequest(to_sign, cloudinary.config.apiSecret, cloudinary.config.signatureVersion);
Assert.assertEquals(result.get("signature"), expected_signature);
}
@@ -135,7 +137,7 @@ public void testUnsignedUpload() throws Exception {
to_sign.put("public_id", result.getString("public_id"));
to_sign.put("version", ObjectUtils.asString(result.get("version")));
Log.d("TestRunner", cloudinary.config.apiSecret);
- String expected_signature = cloudinary.apiSignRequest(to_sign, cloudinary.config.apiSecret);
+ String expected_signature = cloudinary.apiSignRequest(to_sign, cloudinary.config.apiSecret, cloudinary.config.signatureVersion);
Assert.assertEquals(result.get("signature"), expected_signature);
}
@@ -149,7 +151,7 @@ public void testUploadUrl() throws Exception {
Map to_sign = new HashMap();
to_sign.put("public_id", (String) result.get("public_id"));
to_sign.put("version", ObjectUtils.asString(result.get("version")));
- String expected_signature = cloudinary.apiSignRequest(to_sign, cloudinary.config.apiSecret);
+ String expected_signature = cloudinary.apiSignRequest(to_sign, cloudinary.config.apiSecret, cloudinary.config.signatureVersion);
Assert.assertEquals(result.get("signature"), expected_signature);
}
@@ -167,7 +169,7 @@ public void testUploadDataUri() throws Exception {
Map to_sign = new HashMap();
to_sign.put("public_id", (String) result.get("public_id"));
to_sign.put("version", ObjectUtils.asString(result.get("version")));
- String expected_signature = cloudinary.apiSignRequest(to_sign, cloudinary.config.apiSecret);
+ String expected_signature = cloudinary.apiSignRequest(to_sign, cloudinary.config.apiSecret, cloudinary.config.signatureVersion);
Assert.assertEquals(result.get("signature"), expected_signature);
}
@@ -182,7 +184,7 @@ public void testUploadExternalSignature() throws Exception {
Map params = new HashMap();
params.put("timestamp", Long.valueOf(System.currentTimeMillis() / 1000L).toString());
- params.put("signature", this.cloudinary.apiSignRequest(params, apiSecret));
+ params.put("signature", this.cloudinary.apiSignRequest(params, apiSecret, cloudinary.config.signatureVersion));
Cloudinary emptyCloudinary = new Cloudinary(config);
JSONObject result = new JSONObject(emptyCloudinary.uploader().upload(getAssetStream(TEST_IMAGE), params));
Assert.assertEquals(result.getLong("width"), 241L);
@@ -190,7 +192,7 @@ public void testUploadExternalSignature() throws Exception {
Map to_sign = new HashMap();
to_sign.put("public_id", result.getString("public_id"));
to_sign.put("version", ObjectUtils.asString(result.get("version")));
- String expected_signature = cloudinary.apiSignRequest(to_sign, apiSecret);
+ String expected_signature = cloudinary.apiSignRequest(to_sign, apiSecret, cloudinary.config.signatureVersion);
Assert.assertEquals(result.get("signature"), expected_signature);
}
diff --git a/core/src/main/AndroidManifest.xml b/core/src/main/AndroidManifest.xml
index d169784f..325a8330 100644
--- a/core/src/main/AndroidManifest.xml
+++ b/core/src/main/AndroidManifest.xml
@@ -1,5 +1,5 @@
+ >
diff --git a/core/src/main/java/com/cloudinary/android/ApiStrategy.java b/core/src/main/java/com/cloudinary/android/ApiStrategy.java
index 76c53cad..6ff221a9 100644
--- a/core/src/main/java/com/cloudinary/android/ApiStrategy.java
+++ b/core/src/main/java/com/cloudinary/android/ApiStrategy.java
@@ -7,15 +7,13 @@
import com.cloudinary.strategies.AbstractApiStrategy;
public class ApiStrategy extends AbstractApiStrategy {
-
@Override
- public ApiResponse callApi(HttpMethod method, Iterable uri, Map params, Map options) throws Exception {
+ public ApiResponse callApi(HttpMethod method, String apiUrl, Map params, Map options, String authorizationHeader) throws Exception {
throw new Exception("Administration API is not supported for mobile applications.");
}
@Override
- public ApiResponse callAccountApi(HttpMethod method, Iterable uri, Map params, Map options) throws Exception {
+ public ApiResponse callAccountApi(HttpMethod method, String apiUrl, Map params, Map options, String authorizationHeader) throws Exception {
throw new Exception("Account API is not supported for mobile applications.");
}
-
}
diff --git a/core/src/main/java/com/cloudinary/android/UploaderStrategy.java b/core/src/main/java/com/cloudinary/android/UploaderStrategy.java
index cb595c80..3d48c145 100644
--- a/core/src/main/java/com/cloudinary/android/UploaderStrategy.java
+++ b/core/src/main/java/com/cloudinary/android/UploaderStrategy.java
@@ -54,7 +54,7 @@ public Map callApi(String action, Map params, Map options, Objec
if (apiSecret == null)
throw new IllegalArgumentException("Must supply api_secret");
params.put("timestamp", Long.valueOf(System.currentTimeMillis() / 1000L).toString());
- params.put("signature", this.cloudinary().apiSignRequest(params, apiSecret));
+ params.put("signature", this.cloudinary().apiSignRequest(params, apiSecret, this.cloudinary().config.signatureVersion));
params.put("api_key", apiKey);
}
}
diff --git a/download/build.gradle b/download/build.gradle
index 60835ed2..c4ff8a4d 100644
--- a/download/build.gradle
+++ b/download/build.gradle
@@ -1,6 +1,8 @@
apply plugin: 'com.android.library'
android {
+ namespace 'com.cloudinary.android.download'
+ testNamespace 'com.cloudinary.android.download.test'
compileSdk 34
defaultConfig {
@@ -37,7 +39,7 @@ dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test:runner:1.4.0'
- androidTestImplementation 'org.mockito:mockito-android:4.2.0'
+ androidTestImplementation 'org.mockito:mockito-android:5.11.0'
}
ext {
diff --git a/download/src/androidTest/AndroidManifest.xml b/download/src/androidTest/AndroidManifest.xml
index ccc8fb81..a6bf0b75 100644
--- a/download/src/androidTest/AndroidManifest.xml
+++ b/download/src/androidTest/AndroidManifest.xml
@@ -1,6 +1,5 @@
diff --git a/download/src/main/AndroidManifest.xml b/download/src/main/AndroidManifest.xml
index ed91a3e1..a09f0fdb 100644
--- a/download/src/main/AndroidManifest.xml
+++ b/download/src/main/AndroidManifest.xml
@@ -1 +1,4 @@
-
+
+
+
+
diff --git a/glide-integration/build.gradle b/glide-integration/build.gradle
index 0a2646be..e980b5fa 100644
--- a/glide-integration/build.gradle
+++ b/glide-integration/build.gradle
@@ -1,6 +1,7 @@
apply plugin: 'com.android.library'
android {
+ namespace 'com.cloudinary.android.glide_integration'
compileSdk 34
defaultConfig {
@@ -32,7 +33,7 @@ dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.4.0'
- androidTestImplementation 'org.mockito:mockito-android:4.2.0'
+ androidTestImplementation 'org.mockito:mockito-android:5.11.0'
}
ext {
diff --git a/glide-integration/src/main/AndroidManifest.xml b/glide-integration/src/main/AndroidManifest.xml
index 4f049cd4..9cf0d350 100644
--- a/glide-integration/src/main/AndroidManifest.xml
+++ b/glide-integration/src/main/AndroidManifest.xml
@@ -1 +1,4 @@
-
\ No newline at end of file
+
+
+
+
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
index 299aef11..e7b0b564 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -14,7 +14,7 @@ developerEmail=info@cloudinary.com
# These two properties must use these exact names to be compatible with 'gradle install' plugin.
group=com.cloudinary
version=3.0.2
-cloudinaryLibsVersion=1.38.0
+cloudinaryLibsVersion=2.3.0
org.gradle.jvmargs=-Xmx1024m
gnsp.disableApplyOnlyOnRootProjectEnforcement=true
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 4ff50e52..91e4910b 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Wed Jan 19 11:45:39 IST 2022
+#Thu Jun 19 08:08:34 IDT 2025
distributionBase=GRADLE_USER_HOME
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
distributionPath=wrapper/dists
-zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/preprocess/build.gradle b/preprocess/build.gradle
index 618c4cbd..2ea909c4 100644
--- a/preprocess/build.gradle
+++ b/preprocess/build.gradle
@@ -1,6 +1,8 @@
apply plugin: 'com.android.library'
android {
+ namespace 'com.cloudinary.android.preprocess'
+ testNamespace 'com.cloudinary.android.test'
compileSdk 34
defaultConfig {
diff --git a/preprocess/src/androidTest/AndroidManifest.xml b/preprocess/src/androidTest/AndroidManifest.xml
index 45a2d542..f4ee81c8 100644
--- a/preprocess/src/androidTest/AndroidManifest.xml
+++ b/preprocess/src/androidTest/AndroidManifest.xml
@@ -1,6 +1,5 @@
diff --git a/preprocess/src/main/AndroidManifest.xml b/preprocess/src/main/AndroidManifest.xml
index 9cb4f93e..c6119fc1 100644
--- a/preprocess/src/main/AndroidManifest.xml
+++ b/preprocess/src/main/AndroidManifest.xml
@@ -1,5 +1,5 @@
+ >
diff --git a/sample/build.gradle b/sample/build.gradle
index c9d223cd..1bef893b 100755
--- a/sample/build.gradle
+++ b/sample/build.gradle
@@ -7,6 +7,7 @@ android {
}
defaultConfig {
+ namespace 'com.cloudinary.sample'
compileSdk 34
applicationId "com.cloudinary.sample"
minSdkVersion 21
diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml
index e3e76576..6defcfa7 100644
--- a/sample/src/main/AndroidManifest.xml
+++ b/sample/src/main/AndroidManifest.xml
@@ -1,6 +1,5 @@
diff --git a/ui/build.gradle b/ui/build.gradle
index 9a1fce65..a9d77024 100644
--- a/ui/build.gradle
+++ b/ui/build.gradle
@@ -1,6 +1,7 @@
apply plugin: 'com.android.library'
android {
+ namespace 'com.cloudinary.android.ui'
compileSdk 34
diff --git a/ui/src/main/AndroidManifest.xml b/ui/src/main/AndroidManifest.xml
index bfcbda68..864def03 100644
--- a/ui/src/main/AndroidManifest.xml
+++ b/ui/src/main/AndroidManifest.xml
@@ -1,5 +1,5 @@
+ >