diff --git a/README.md b/README.md
index 0ddcfe29..318291db 100644
--- a/README.md
+++ b/README.md
@@ -358,6 +358,34 @@ try {
}
```
+### Image Client 样例
+
+> 以下片断来自项目代码里面的文件:example / cn.jpush.api.examples.ImageExample
+* 支持通过URL或者文件来上传图片
+```Java
+ public static void testUploadImageByUrl() throws APIConnectionException, APIRequestException {
+ ImageClient client = new ImageClient(MASTER_SECRET, APP_KEY);
+ ImageUrlPayload payload = ImageUrlPayload.newBuilder()
+ .setImageType(ImageType.LARGE_ICON)
+ .setImageUrl("http://xxx.com/image/a.jpg")
+ .build();
+ ImageUploadResult imageUploadResult = client.uploadImage(payload);
+ String mediaId = imageUploadResult.getMediaId();
+ }
+
+ public static void testUploadImageByFile() {
+ ImageClient client = new ImageClient(MASTER_SECRET, APP_KEY);
+ ImageFilePayload payload = ImageFilePayload.newBuilder()
+ .setImageType(ImageType.BIG_PICTURE)
+ // 本地文件路径
+ .setOppoFileName("/MyDir/a.jpg")
+ .setXiaomiFileName("/MyDir/a.jpg")
+ .build();
+ ImageUploadResult imageUploadResult = client.uploadImage(payload);
+ String mediaId = imageUploadResult.getMediaId();
+ }
+```
+
### Weblogic 使用Java SDK
Weblogic在使用jpush-api-java-client时需要注意的一些事项。
diff --git a/example/main/java/cn/jpush/api/examples/ImageExample.java b/example/main/java/cn/jpush/api/examples/ImageExample.java
new file mode 100644
index 00000000..a29ad866
--- /dev/null
+++ b/example/main/java/cn/jpush/api/examples/ImageExample.java
@@ -0,0 +1,56 @@
+package cn.jpush.api.image;
+
+import cn.jiguang.common.resp.APIConnectionException;
+import cn.jiguang.common.resp.APIRequestException;
+import cn.jpush.api.image.model.ImageFilePayload;
+import cn.jpush.api.image.model.ImageType;
+import cn.jpush.api.image.model.ImageUploadResult;
+import cn.jpush.api.image.model.ImageUrlPayload;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ImageExample {
+ protected static final Logger LOG = LoggerFactory.getLogger(ImageExample.class);
+
+ // demo App defined in resources/jpush-api.conf
+ protected static final String APP_KEY = "e4ceeaf7a53ad745dd4728f2";
+ protected static final String MASTER_SECRET = "1582b986adeaf48ceec1e354";
+ protected static final String GROUP_PUSH_KEY = "2c88a01e073a0fe4fc7b167c";
+ protected static final String GROUP_MASTER_SECRET = "b11314807507e2bcfdeebe2e";
+
+ public static final String TITLE = "Test from API example";
+ public static final String ALERT = "Test from API Example - alert";
+ public static final String MSG_CONTENT = "Test from API Example - msgContent";
+ public static final String REGISTRATION_ID = "0900e8d85ef";
+ public static final String TAG = "tag_api";
+ public static long sendCount = 0;
+ private static long sendTotalTime = 0;
+
+ public static void main(String[] args) throws APIConnectionException, APIRequestException {
+ testUploadImageByFile();
+ testUploadImageByUrl();
+ }
+
+ public static void testUploadImageByUrl() throws APIConnectionException, APIRequestException {
+ ImageClient client = new ImageClient(MASTER_SECRET, APP_KEY);
+ ImageUrlPayload payload = ImageUrlPayload.newBuilder()
+ .setImageType(ImageType.LARGE_ICON)
+ .setImageUrl("http://xxx.com/image/a.jpg")
+ .build();
+ ImageUploadResult imageUploadResult = client.uploadImage(payload);
+ String mediaId = imageUploadResult.getMediaId();
+ }
+
+ public static void testUploadImageByFile() {
+ ImageClient client = new ImageClient(MASTER_SECRET, APP_KEY);
+ ImageFilePayload payload = ImageFilePayload.newBuilder()
+ .setImageType(ImageType.BIG_PICTURE)
+ // 本地文件路径
+ .setOppoFileName("/MyDir/a.jpg")
+ .setXiaomiFileName("/MyDir/a.jpg")
+ .build();
+ ImageUploadResult imageUploadResult = client.uploadImage(payload);
+ String mediaId = imageUploadResult.getMediaId();
+ }
+}
+
diff --git a/pom.xml b/pom.xml
index fdc07020..f8f5a173 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
cn.jpush.api
jpush-client
- 3.4.7
+ 3.4.8
jar
https://github.com/jpush/jpush-api-java-client
JPush API Java Client
@@ -51,7 +51,7 @@
cn.jpush.api
jiguang-common
- 1.1.9
+ 1.1.10
org.apache.httpcomponents
@@ -117,6 +117,18 @@
2.0.0
test
+
+ org.mockito
+ mockito-core
+ 1.10.19
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+ 2.2
+ test
+
@@ -294,7 +306,6 @@
-
ossrh
diff --git a/src/main/java/cn/jpush/api/file/FileClient.java b/src/main/java/cn/jpush/api/file/FileClient.java
index 601805cb..b7e11a2e 100644
--- a/src/main/java/cn/jpush/api/file/FileClient.java
+++ b/src/main/java/cn/jpush/api/file/FileClient.java
@@ -56,7 +56,7 @@ public FileUploadResult uploadFile(FileType type, String filename)
String url = _baseUrl + _filesPath + "/" + typeStr;
Map fileMap = new HashMap<>();
fileMap.put("filename", filename);
- String response = client.formUpload(url, null, fileMap, null);
+ String response = client.formUploadByPost(url, null, fileMap, null);
LOG.info("uploadFile:{}", response);
return _gson.fromJson(response,
new TypeToken() {
diff --git a/src/main/java/cn/jpush/api/image/ImageClient.java b/src/main/java/cn/jpush/api/image/ImageClient.java
new file mode 100644
index 00000000..87a2acd4
--- /dev/null
+++ b/src/main/java/cn/jpush/api/image/ImageClient.java
@@ -0,0 +1,162 @@
+package cn.jpush.api.image;
+
+import cn.jiguang.common.ClientConfig;
+import cn.jiguang.common.ServiceHelper;
+import cn.jiguang.common.connection.HttpProxy;
+import cn.jiguang.common.connection.IHttpClient;
+import cn.jiguang.common.connection.NativeHttpClient;
+import cn.jiguang.common.resp.APIConnectionException;
+import cn.jiguang.common.resp.APIRequestException;
+import cn.jiguang.common.resp.ResponseWrapper;
+import cn.jiguang.common.utils.Preconditions;
+import cn.jiguang.common.utils.StringUtils;
+import cn.jpush.api.image.model.ImageFilePayload;
+import cn.jpush.api.image.model.ImageSource;
+import cn.jpush.api.image.model.ImageUploadResult;
+import cn.jpush.api.image.model.ImageUrlPayload;
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonSyntaxException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Provide the ability to upload images to the Jiguang server. Only images in JPG, JPEG and PNG format are supported.
+ *
+ * @author fuyx
+ * @version 2020-12-14
+ */
+public class ImageClient {
+
+ protected static final Logger LOG = LoggerFactory.getLogger(ImageClient.class);
+
+ private IHttpClient _httpClient;
+ private String _baseUrl;
+ private String _imagesPath;
+ private Gson _gson = new Gson();
+
+ public ImageClient(String masterSecret, String appKey) {
+ this(masterSecret, appKey, null, ClientConfig.getInstance());
+ }
+
+ public ImageClient(String masterSecret, String appKey, HttpProxy proxy, ClientConfig conf) {
+ _baseUrl = (String) conf.get(ClientConfig.PUSH_HOST_NAME);
+ _imagesPath = (String) conf.get(ClientConfig.V3_IMAGES_PATH);
+ String authCode = ServiceHelper.getBasicAuthorization(appKey, masterSecret);
+ this._httpClient = new NativeHttpClient(authCode, proxy, conf);
+ }
+
+ /**
+ * Upload image by url. Require at least one non-null url.
+ */
+ public ImageUploadResult uploadImage(ImageUrlPayload imageUrlPayload)
+ throws APIConnectionException, APIRequestException {
+ Preconditions.checkArgument(imageUrlPayload.getImageType() != null, "Image type should not be null");
+ checkImageUrlPayload(imageUrlPayload);
+ NativeHttpClient client = (NativeHttpClient) _httpClient;
+ String url = _baseUrl + _imagesPath + "/" + ImageSource.URL.value();
+ JsonElement jsonElement = imageUrlPayload.toJSON();
+ String content = _gson.toJson(jsonElement);
+ ResponseWrapper responseWrapper = client.sendPost(url, content);
+ if (responseWrapper.responseCode != 200) {
+ LOG.error("upload image failed: {}", responseWrapper);
+ }
+ ImageUploadResult imageUploadResult = _gson.fromJson(responseWrapper.responseContent, ImageUploadResult.class);
+
+ LOG.info("upload image result:{}", imageUploadResult);
+ return imageUploadResult;
+ }
+
+ /**
+ * Upload image by file. Require at least 1 non-null fileName. Currently only support Xiaomi and OPPO
+ */
+ public ImageUploadResult uploadImage(ImageFilePayload imageFilePayload) {
+ Preconditions.checkArgument(imageFilePayload.getImageType() != null, "Image type should not be null");
+ checkImageFilePayload(imageFilePayload);
+ NativeHttpClient client = (NativeHttpClient) _httpClient;
+ String url = _baseUrl + _imagesPath + "/" + ImageSource.FILE.value();
+
+ Map textMap = new HashMap<>();
+ textMap.put("image_type", String.valueOf(imageFilePayload.getImageType().value()));
+
+ Map fileMap = imageFilePayload.toFileMap();
+ LOG.debug("upload fileMap: {}", fileMap);
+ String response = client.formUploadByPost(url, textMap, fileMap, null);
+ LOG.debug("upload image result: {}", response);
+ ImageUploadResult imageUploadResult;
+ try {
+ imageUploadResult = _gson.fromJson(response, ImageUploadResult.class);
+ } catch (JsonSyntaxException e) {
+ LOG.error("could not parse response: {}", response);
+ throw new IllegalStateException("could not parse response", e);
+ }
+ LOG.info("upload image result:{}", imageUploadResult);
+ return imageUploadResult;
+ }
+
+ /**
+ * Modify image by url. Require at least one non-null url.
+ */
+ public ImageUploadResult modifyImage(String mediaId, ImageUrlPayload imageUrlPayload)
+ throws APIConnectionException, APIRequestException {
+ Preconditions.checkArgument(StringUtils.isNotEmpty(mediaId), "mediaId should not be empty");
+ checkImageUrlPayload(imageUrlPayload);
+ NativeHttpClient client = (NativeHttpClient) _httpClient;
+ String url = _baseUrl + _imagesPath + "/" + ImageSource.URL.value() + "/" + mediaId;
+ JsonElement jsonElement = imageUrlPayload.toJSON();
+ String content = _gson.toJson(jsonElement);
+ ResponseWrapper responseWrapper = client.sendPut(url, content);
+ if (responseWrapper.responseCode != 200) {
+ LOG.error("upload image failed: {}", responseWrapper);
+ }
+ ImageUploadResult imageUploadResult = _gson.fromJson(responseWrapper.responseContent, ImageUploadResult.class);
+
+ LOG.info("upload image result:{}", imageUploadResult);
+ return imageUploadResult;
+ }
+
+ /**
+ * Modify image by file. Require at least 1 non-null fileName. Currently only support Xiaomi and OPPO
+ */
+ public ImageUploadResult modifyImage(String mediaId, ImageFilePayload imageFilePayload) {
+ Preconditions.checkArgument(StringUtils.isNotEmpty(mediaId), "mediaId should not be empty");
+ checkImageFilePayload(imageFilePayload);
+ NativeHttpClient client = (NativeHttpClient) _httpClient;
+ String url = _baseUrl + _imagesPath + "/" + ImageSource.FILE.value() + "/" + mediaId;
+
+ Map fileMap = imageFilePayload.toFileMap();
+ LOG.debug("upload image fileMap: {}", fileMap);
+ String response = client.formUploadByPut(url, null, fileMap, null);
+ LOG.debug("upload image result: {}", response);
+ ImageUploadResult imageUploadResult;
+ try {
+ imageUploadResult = _gson.fromJson(response, ImageUploadResult.class);
+ } catch (JsonSyntaxException e) {
+ LOG.error("could not parse response: {}", response);
+ throw new IllegalStateException("could not parse response", e);
+ }
+ LOG.info("upload image result:{}", imageUploadResult);
+ return imageUploadResult;
+ }
+
+ private void checkImageUrlPayload(ImageUrlPayload imageUrlPayload) {
+ boolean anyUrlNotEmpty = StringUtils.isNotEmpty(imageUrlPayload.getImageUrl())
+ || StringUtils.isNotEmpty(imageUrlPayload.getFcmImageUrl())
+ || StringUtils.isNotEmpty(imageUrlPayload.getHuaweiImageUrl())
+ || StringUtils.isNotEmpty(imageUrlPayload.getOppoImageUrl())
+ || StringUtils.isNotEmpty(imageUrlPayload.getXiaomiImageUrl())
+ || StringUtils.isNotEmpty(imageUrlPayload.getJiguangImageUrl()) ;
+ Preconditions.checkArgument(anyUrlNotEmpty, "Require at least 1 non-empty url");
+ }
+
+ private void checkImageFilePayload(ImageFilePayload imageFilePayload) {
+ boolean anyFileNotEmpty = StringUtils.isNotEmpty(imageFilePayload.getOppoFileName() )
+ || StringUtils.isNotEmpty(imageFilePayload.getXiaomiFileName() );
+ Preconditions.checkArgument(anyFileNotEmpty, "Require at least 1 non-empty fileName. Currently only support Xiaomi and OPPO");
+ }
+
+
+}
diff --git a/src/main/java/cn/jpush/api/image/model/ImageFilePayload.java b/src/main/java/cn/jpush/api/image/model/ImageFilePayload.java
new file mode 100644
index 00000000..7a4be086
--- /dev/null
+++ b/src/main/java/cn/jpush/api/image/model/ImageFilePayload.java
@@ -0,0 +1,105 @@
+package cn.jpush.api.image.model;
+
+import lombok.Data;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Data
+public class ImageFilePayload {
+ private static final String IMAGE_TYPE = "image_type";
+ private static final String OPPO_IMAGE_FILE = "oppo_file";
+ private static final String XIAOMI_IMAGE_FILE = "xiaomi_file";
+ private static final String HUAWEI_IMAGE_FILE = "huawei_file";
+ private static final String FCM_IMAGE_FILE = "fcm_file";
+ private static final String JIGUANG_IMAGE_FILE = "jiguang_file";
+
+ private ImageType imageType;
+ private String oppoFileName;
+ private String xiaomiFileName;
+ private String huaweiFileName;
+ private String fcmFileName;
+ private String jiguangFileName;
+
+ public Map toFileMap() {
+ HashMap fileMap = new HashMap<>();
+ if (null != oppoFileName) {
+ fileMap.put(OPPO_IMAGE_FILE, oppoFileName);
+ }
+ if (null != xiaomiFileName) {
+ fileMap.put(XIAOMI_IMAGE_FILE, xiaomiFileName);
+ }
+ if (null != huaweiFileName) {
+ fileMap.put(HUAWEI_IMAGE_FILE, huaweiFileName);
+ }
+ if (null != fcmFileName) {
+ fileMap.put(FCM_IMAGE_FILE, fcmFileName);
+ }
+ if (null != jiguangFileName) {
+ fileMap.put(JIGUANG_IMAGE_FILE, jiguangFileName);
+ }
+ return fileMap;
+ }
+
+ public static Builder newBuilder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private ImageType imageType;
+ private String oppoFileName;
+ private String xiaomiFileName;
+ private String huaweiFileName;
+ private String fcmFileName;
+ private String jiguangFileName;
+
+ private Builder() {
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public Builder setImageType(ImageType imageType) {
+ this.imageType = imageType;
+ return this;
+ }
+
+ public Builder setOppoFileName(String oppoFileName) {
+ this.oppoFileName = oppoFileName;
+ return this;
+ }
+
+ public Builder setXiaomiFileName(String xiaomiFileName) {
+ this.xiaomiFileName = xiaomiFileName;
+ return this;
+ }
+
+ public Builder setHuaweiFileName(String huaweiFileName) {
+ this.huaweiFileName = huaweiFileName;
+ return this;
+ }
+
+ public Builder setFcmFileName(String fcmFileName) {
+ this.fcmFileName = fcmFileName;
+ return this;
+ }
+
+ public Builder setJiguangFileName(String jiguangFileName) {
+ this.jiguangFileName = jiguangFileName;
+ return this;
+ }
+
+ public ImageFilePayload build() {
+ ImageFilePayload imageFilePayload = new ImageFilePayload();
+ imageFilePayload.setImageType(imageType);
+ imageFilePayload.setOppoFileName(oppoFileName);
+ imageFilePayload.setXiaomiFileName(xiaomiFileName);
+ imageFilePayload.setHuaweiFileName(huaweiFileName);
+ imageFilePayload.setFcmFileName(fcmFileName);
+ imageFilePayload.setJiguangFileName(jiguangFileName);
+ return imageFilePayload;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/cn/jpush/api/image/model/ImageSource.java b/src/main/java/cn/jpush/api/image/model/ImageSource.java
new file mode 100644
index 00000000..5bd847c1
--- /dev/null
+++ b/src/main/java/cn/jpush/api/image/model/ImageSource.java
@@ -0,0 +1,27 @@
+package cn.jpush.api.image.model;
+
+/**
+ * @author fuyx
+ * @version 2020-12-14
+ */
+public enum ImageSource {
+
+ /**
+ * Network Resource
+ */
+ URL("byurls"),
+ /**
+ * File Resource
+ */
+ FILE("byfiles");
+
+ private final String value;
+
+ ImageSource(final String value) {
+ this.value = value;
+ }
+
+ public String value() {
+ return this.value;
+ }
+}
diff --git a/src/main/java/cn/jpush/api/image/model/ImageType.java b/src/main/java/cn/jpush/api/image/model/ImageType.java
new file mode 100644
index 00000000..24b37425
--- /dev/null
+++ b/src/main/java/cn/jpush/api/image/model/ImageType.java
@@ -0,0 +1,27 @@
+package cn.jpush.api.image.model;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * @author fuyx
+ * @version 2020-12-14
+ */
+public enum ImageType {
+
+ @SerializedName("1")
+ BIG_PICTURE(1),
+ @SerializedName("2")
+ LARGE_ICON(2),
+ @SerializedName("3")
+ SMALL_ICON(3);
+
+ private final int value;
+
+ ImageType(final int value) {
+ this.value = value;
+ }
+
+ public int value() {
+ return this.value;
+ }
+}
diff --git a/src/main/java/cn/jpush/api/image/model/ImageUploadResult.java b/src/main/java/cn/jpush/api/image/model/ImageUploadResult.java
new file mode 100644
index 00000000..2435eb22
--- /dev/null
+++ b/src/main/java/cn/jpush/api/image/model/ImageUploadResult.java
@@ -0,0 +1,31 @@
+package cn.jpush.api.image.model;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+@Data
+public class ImageUploadResult {
+
+ @SerializedName("media_id")
+ private String mediaId;
+ @SerializedName("oppo_image_url")
+ private String oppoImageUrl;
+ @SerializedName("xiaomi_image_url")
+ private String xiaomiImageUrl;
+ @SerializedName("huawei_image_url")
+ private String huaweiImageUrl;
+ @SerializedName("fcm_image_url")
+ private String fcmImageUrl;
+ @SerializedName("jiguang_image_url")
+ private String jiguangImageUrl;
+ @SerializedName("error")
+ private Error error;
+
+ @Data
+ public static class Error {
+ @SerializedName("message")
+ private String message;
+ @SerializedName("code")
+ private int code;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/cn/jpush/api/image/model/ImageUrlPayload.java b/src/main/java/cn/jpush/api/image/model/ImageUrlPayload.java
new file mode 100644
index 00000000..62cd0626
--- /dev/null
+++ b/src/main/java/cn/jpush/api/image/model/ImageUrlPayload.java
@@ -0,0 +1,119 @@
+package cn.jpush.api.image.model;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import lombok.Data;
+
+@Data
+public class ImageUrlPayload {
+ private static final String IMAGE_TYPE = "image_type";
+ private static final String IMAGE_URL = "image_url";
+ private static final String OPPO_IMAGE_URL = "oppo_image_url";
+ private static final String XIAOMI_IMAGE_URL = "xiaomi_image_url";
+ private static final String HUAWEI_IMAGE_URL = "huawei_image_url";
+ private static final String FCM_IMAGE_URL = "fcm_image_url";
+ private static final String JIGUANG_IMAGE_URL = "jiguang_image_url";
+
+ private ImageType imageType;
+ private String imageUrl;
+ private String oppoImageUrl;
+ private String xiaomiImageUrl;
+ private String huaweiImageUrl;
+ private String fcmImageUrl;
+ private String jiguangImageUrl;
+
+ public JsonElement toJSON() {
+ JsonObject json = new JsonObject();
+ if (null != imageType) {
+ json.addProperty(IMAGE_TYPE, imageType.value());
+ }
+ if (null != imageUrl) {
+ json.addProperty(IMAGE_URL, imageUrl);
+ }
+ if (null != oppoImageUrl) {
+ json.addProperty(OPPO_IMAGE_URL, oppoImageUrl);
+ }
+ if (null != xiaomiImageUrl) {
+ json.addProperty(XIAOMI_IMAGE_URL, xiaomiImageUrl);
+ }
+ if (null != huaweiImageUrl) {
+ json.addProperty(HUAWEI_IMAGE_URL, huaweiImageUrl);
+ }
+ if (null != fcmImageUrl) {
+ json.addProperty(FCM_IMAGE_URL, fcmImageUrl);
+ }
+ if (null != jiguangImageUrl) {
+ json.addProperty(JIGUANG_IMAGE_URL, jiguangImageUrl);
+ }
+ return json;
+ }
+
+ public static Builder newBuilder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private ImageType imageType;
+ private String imageUrl;
+ private String oppoImageUrl;
+ private String xiaomiImageUrl;
+ private String huaweiImageUrl;
+ private String fcmImageUrl;
+ private String jiguangImageUrl;
+
+ private Builder() {
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public Builder setImageType(ImageType imageType) {
+ this.imageType = imageType;
+ return this;
+ }
+
+ public Builder setImageUrl(String imageUrl) {
+ this.imageUrl = imageUrl;
+ return this;
+ }
+
+ public Builder setOppoImageUrl(String oppoImageUrl) {
+ this.oppoImageUrl = oppoImageUrl;
+ return this;
+ }
+
+ public Builder setXiaomiImageUrl(String xiaomiImageUrl) {
+ this.xiaomiImageUrl = xiaomiImageUrl;
+ return this;
+ }
+
+ public Builder setHuaweiImageUrl(String huaweiImageUrl) {
+ this.huaweiImageUrl = huaweiImageUrl;
+ return this;
+ }
+
+ public Builder setFcmImageUrl(String fcmImageUrl) {
+ this.fcmImageUrl = fcmImageUrl;
+ return this;
+ }
+
+ public Builder setJiguangImageUrl(String jiguangImageUrl) {
+ this.jiguangImageUrl = jiguangImageUrl;
+ return this;
+ }
+
+ public ImageUrlPayload build() {
+ ImageUrlPayload imageUrlPayload = new ImageUrlPayload();
+ imageUrlPayload.setImageType(imageType);
+ imageUrlPayload.setImageUrl(imageUrl);
+ imageUrlPayload.setOppoImageUrl(oppoImageUrl);
+ imageUrlPayload.setXiaomiImageUrl(xiaomiImageUrl);
+ imageUrlPayload.setHuaweiImageUrl(huaweiImageUrl);
+ imageUrlPayload.setFcmImageUrl(fcmImageUrl);
+ imageUrlPayload.setJiguangImageUrl(jiguangImageUrl);
+ return imageUrlPayload;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/cn/jpush/api/push/model/notification/AndroidNotification.java b/src/main/java/cn/jpush/api/push/model/notification/AndroidNotification.java
index dcc0d197..ab2407cd 100644
--- a/src/main/java/cn/jpush/api/push/model/notification/AndroidNotification.java
+++ b/src/main/java/cn/jpush/api/push/model/notification/AndroidNotification.java
@@ -3,10 +3,7 @@
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
-import lombok.*;
-import lombok.experimental.Accessors;
-import java.util.LinkedHashMap;
import java.util.Map;
public class AndroidNotification extends PlatformNotification {
@@ -23,6 +20,7 @@ public class AndroidNotification extends PlatformNotification {
private static final String PRIORITY = "priority";
private static final String CATEGORY = "category";
private static final String LARGE_ICON = "large_icon";
+ private static final String SMALL_ICON_URI = "small_icon_uri";
private static final String INTENT = "intent";
private final String title;
@@ -38,6 +36,7 @@ public class AndroidNotification extends PlatformNotification {
private int priority;
private String category;
private String large_icon;
+ private String small_icon_uri;
private JsonObject intent;
private AndroidNotification(Object alert,
@@ -51,6 +50,7 @@ private AndroidNotification(Object alert,
int priority,
String category,
String large_icon,
+ String small_icon_uri,
JsonObject intent,
String channelId,
Map extras,
@@ -70,6 +70,7 @@ private AndroidNotification(Object alert,
this.priority = priority;
this.category = category;
this.large_icon = large_icon;
+ this.small_icon_uri = small_icon_uri;
this.intent = intent;
this.channelId = channelId;
}
@@ -142,6 +143,10 @@ public JsonElement toJSON() {
json.add(LARGE_ICON, new JsonPrimitive(large_icon));
}
+ if (null != small_icon_uri) {
+ json.add(SMALL_ICON_URI, new JsonPrimitive(small_icon_uri));
+ }
+
if (null != intent) {
json.add(INTENT, intent);
}
@@ -164,6 +169,7 @@ public static class Builder extends PlatformNotification.Builder textMap = new HashMap<>();
+ textMap.put("image_type", "2");
+ HashMap fileMap = new HashMap<>();
+ fileMap.put("oppo_file", "oppoXX.jpg");
+ fileMap.put("xiaomi_file", "dir/xiaomiXX.jpg");
+ verify(mockIHttpClient).formUploadByPost("https://api.jpush.cn/v3/images/byfiles", textMap, fileMap, null);
+
+ assertThat(imageUploadResult.getMediaId(), equalTo("jgmedia-2-14b23451-0001-41ce-89d9-987b465122da"));
+ assertThat(imageUploadResult.getOppoImageUrl(), equalTo("3653918_5f92b5739ae676f5745bcbf4"));
+ assertThat(imageUploadResult.getXiaomiImageUrl(), equalTo("http://f6.market.xiaomi.com/download/MiPass/01fff50f50ba193f94074ec/d1671936d468383f.png"));
+ assertThat(imageUploadResult.getHuaweiImageUrl(), nullValue());
+ }
+
+ @Test
+ public void testModifyImageByUrl() throws NoSuchFieldException, APIConnectionException, APIRequestException {
+ ResponseWrapper mockResponseWrapper = new ResponseWrapper();
+ mockResponseWrapper.responseCode = 200;
+ mockResponseWrapper.responseContent = "{\n" +
+ " \"media_id\": \"jgmedia-2-14b23451-0001-41ce-89d9-987b465122da\", \n" +
+ " \"oppo_image_url\": \"3653918_5f92b5739ae676f5745bcbf4\", \n" +
+ " \"xiaomi_image_url\": \"http://f6.market.xiaomi.com/download/MiPass/01fff50f50ba193f94074ec/d1671936d468383f.png\" \n" +
+ "}";
+ String mediaId = "jgmedia-2-14b23451-0001-41ce-89d9-987b465122da";
+ NativeHttpClient mockIHttpClient = mock(NativeHttpClient.class);
+ when(mockIHttpClient.sendPut(anyString(), anyString())).thenReturn(mockResponseWrapper);
+
+ ImageClient client = new ImageClient(MASTER_SECRET, APP_KEY);
+ new FieldSetter(client, client.getClass().getDeclaredField("_httpClient")).set(mockIHttpClient);
+ ImageClient spyClient = Mockito.spy(client);
+ ImageUrlPayload payload = ImageUrlPayload.newBuilder()
+ .setImageUrl("xxx.jpg")
+ .setFcmImageUrl("xxx.png")
+ .setHuaweiImageUrl("xxx.jpeg")
+ .build();
+ ImageUploadResult imageUploadResult = spyClient.modifyImage(mediaId, payload);
+ verify(mockIHttpClient).sendPut("https://api.jpush.cn/v3/images/byurls/" + mediaId, "{\"image_url\":\"xxx.jpg\",\"huawei_image_url\":\"xxx.jpeg\",\"fcm_image_url\":\"xxx.png\"}");
+
+ assertThat(imageUploadResult.getMediaId(), equalTo("jgmedia-2-14b23451-0001-41ce-89d9-987b465122da"));
+ assertThat(imageUploadResult.getOppoImageUrl(), equalTo("3653918_5f92b5739ae676f5745bcbf4"));
+ assertThat(imageUploadResult.getXiaomiImageUrl(), equalTo("http://f6.market.xiaomi.com/download/MiPass/01fff50f50ba193f94074ec/d1671936d468383f.png"));
+ assertThat(imageUploadResult.getHuaweiImageUrl(), nullValue());
+ }
+
+ @Test
+ public void testModifyImageByFile() throws NoSuchFieldException {
+ String content = "{\n" +
+ " \"media_id\": \"jgmedia-2-14b23451-0001-41ce-89d9-987b465122da\", \n" +
+ " \"oppo_image_url\": \"3653918_5f92b5739ae676f5745bcbf4\", \n" +
+ " \"xiaomi_image_url\": \"http://f6.market.xiaomi.com/download/MiPass/01fff50f50ba193f94074ec/d1671936d468383f.png\" \n" +
+ "}";
+ String mediaId = "jgmedia-2-14b23451-0001-41ce-89d9-987b465122da";
+
+ NativeHttpClient mockIHttpClient = mock(NativeHttpClient.class);
+ when(mockIHttpClient.formUploadByPut(anyString(), anyMap(), anyMap(), anyString())).thenReturn(content);
+
+ ImageClient client = new ImageClient(MASTER_SECRET, APP_KEY);
+ new FieldSetter(client, client.getClass().getDeclaredField("_httpClient")).set(mockIHttpClient);
+ ImageClient spyClient = Mockito.spy(client);
+ ImageFilePayload payload = ImageFilePayload.newBuilder()
+ .setOppoFileName("oppoXX.jpg")
+ .setXiaomiFileName("dir/xiaomiXX.jpg")
+ .build();
+ ImageUploadResult imageUploadResult = spyClient.modifyImage(mediaId, payload);
+ HashMap fileMap = new HashMap<>();
+ fileMap.put("oppo_file", "oppoXX.jpg");
+ fileMap.put("xiaomi_file", "dir/xiaomiXX.jpg");
+ verify(mockIHttpClient).formUploadByPut("https://api.jpush.cn/v3/images/byfiles/" + mediaId, null, fileMap, null);
+
+ assertThat(imageUploadResult.getMediaId(), equalTo("jgmedia-2-14b23451-0001-41ce-89d9-987b465122da"));
+ assertThat(imageUploadResult.getOppoImageUrl(), equalTo("3653918_5f92b5739ae676f5745bcbf4"));
+ assertThat(imageUploadResult.getXiaomiImageUrl(), equalTo("http://f6.market.xiaomi.com/download/MiPass/01fff50f50ba193f94074ec/d1671936d468383f.png"));
+ assertThat(imageUploadResult.getHuaweiImageUrl(), nullValue());
+ }
+
+ @Test
+ public void testUploadImageByUrl2() throws APIConnectionException, APIRequestException {
+
+ ImageClient client = new ImageClient(MASTER_SECRET, APP_KEY);
+ ImageUrlPayload payload = ImageUrlPayload.newBuilder()
+ .setImageType(ImageType.LARGE_ICON)
+ .setImageUrl("http://img.aiimg.com/uploads/allimg/151009/280082-151009232P5.jpg")
+ .setOppoImageUrl("http://img.aiimg.com/uploads/allimg/151009/280082-151009232P5.jpg")
+ .setHuaweiImageUrl("http://img.aiimg.com/uploads/allimg/151009/280082-151009232P5.jpg")
+ .build();
+ ImageUploadResult imageUploadResult = client.uploadImage(payload);
+ assertThat(imageUploadResult, notNullValue());
+ String mediaId = imageUploadResult.getMediaId();
+ assertThat(mediaId, notNullValue());
+ ImageUrlPayload payload2 = ImageUrlPayload.newBuilder()
+ .setImageUrl("http://img.aiimg.com/uploads/allimg/151009/280082-151009225435.jpg")
+ .setFcmImageUrl("http://img.aiimg.com/uploads/allimg/151009/280082-151009225435.jpg")
+ .setHuaweiImageUrl("http://img.aiimg.com/uploads/allimg/151009/280082-151009225435.jpg")
+ .build();
+ ImageUploadResult imageUploadResult2 = client.modifyImage(mediaId, payload2);
+ assertThat(imageUploadResult2, notNullValue());
+ assertThat(imageUploadResult2.getHuaweiImageUrl(), notNullValue());
+ }
+
+ @Test
+ public void testUploadImageByFile2() {
+ ImageClient client = new ImageClient(MASTER_SECRET, APP_KEY);
+ ImageFilePayload payload = ImageFilePayload.newBuilder()
+ .setImageType(ImageType.BIG_PICTURE)
+ .setOppoFileName("/Users/yongxing/Downloads/Xnip2020-12-11_14-24-28.jpg")
+ .setXiaomiFileName("/Users/yongxing/Downloads/Xnip2020-12-11_14-24-28.jpg")
+ .build();
+ ImageUploadResult imageUploadResult = client.uploadImage(payload);
+ assertThat(imageUploadResult, notNullValue());
+ assertThat(imageUploadResult.getError(), nullValue());
+ String mediaId = imageUploadResult.getMediaId();
+ assertThat(mediaId, notNullValue());
+ ImageFilePayload payload2 = ImageFilePayload.newBuilder()
+ .setOppoFileName("/Users/yongxing/Downloads/IMG_2778.jpeg")
+ .setXiaomiFileName("/Users/yongxing/Downloads/IMG_2778.jpeg")
+ .build();
+ imageUploadResult = client.modifyImage(mediaId, payload2);
+ assertThat(imageUploadResult, notNullValue());
+ assertThat(imageUploadResult.getOppoImageUrl(), notNullValue());
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/cn/jpush/api/push/remote/NotificationTest.java b/src/test/java/cn/jpush/api/push/remote/NotificationTest.java
index d296b74a..6b73954c 100644
--- a/src/test/java/cn/jpush/api/push/remote/NotificationTest.java
+++ b/src/test/java/cn/jpush/api/push/remote/NotificationTest.java
@@ -2,6 +2,10 @@
import cn.jiguang.common.resp.APIRequestException;
import cn.jpush.api.SlowTests;
+import cn.jpush.api.image.ImageClient;
+import cn.jpush.api.image.model.ImageType;
+import cn.jpush.api.image.model.ImageUploadResult;
+import cn.jpush.api.image.model.ImageUrlPayload;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
@@ -18,16 +22,16 @@
@Category(SlowTests.class)
public class NotificationTest extends BaseRemotePushTest {
-
+
@Test
public void sendNotification_alert_json() throws Exception {
JsonObject json = new JsonObject();
json.addProperty("key1", "value1");
json.addProperty("key2", true);
-
+
String alert = json.toString();
System.out.println(alert);
-
+
PushPayload payload = PushPayload.newBuilder()
.setAudience(Audience.all())
.setPlatform(Platform.all())
@@ -39,9 +43,9 @@ public void sendNotification_alert_json() throws Exception {
PushResult result = _client.sendPush(payload);
assertTrue(result.isResultOK());
}
-
+
// --------------- Android
-
+
@Test
public void sendNotification_android_title() throws Exception {
PushPayload payload = PushPayload.newBuilder()
@@ -55,7 +59,7 @@ public void sendNotification_android_title() throws Exception {
PushResult result = _client.sendPush(payload);
assertTrue(result.isResultOK());
}
-
+
@Test
public void sendNotification_android_buildId() throws Exception {
PushPayload payload = PushPayload.newBuilder()
@@ -70,7 +74,7 @@ public void sendNotification_android_buildId() throws Exception {
PushResult result = _client.sendPush(payload);
assertTrue(result.isResultOK());
}
-
+
@Test
public void sendNotification_android_extras() throws Exception {
PushPayload payload = PushPayload.newBuilder()
@@ -86,10 +90,43 @@ public void sendNotification_android_extras() throws Exception {
PushResult result = _client.sendPush(payload);
assertTrue(result.isResultOK());
}
-
-
+
+ @Test
+ public void sendNotification_android_media_id() throws Exception {
+ ImageClient imageClient = new ImageClient(MASTER_SECRET, APP_KEY);
+ ImageUploadResult imageUploadResult = imageClient.uploadImage(ImageUrlPayload.newBuilder()
+ .setImageType(ImageType.SMALL_ICON)
+ .setImageUrl("http://img.aiimg.com/uploads/allimg/151009/280082-151009225435.jpg")
+ .setXiaomiImageUrl("http://img.aiimg.com/uploads/allimg/151009/280082-151009225435.jpg")
+ .build());
+ String mediaId = imageUploadResult.getMediaId();
+ JsonObject json = new JsonObject();
+ json.addProperty("key1", "value1");
+ json.addProperty("key2", true);
+
+ String alert = json.toString();
+ System.out.println(alert);
+
+ PushPayload payload = PushPayload.newBuilder()
+ .setAudience(Audience.all())
+ .setPlatform(Platform.all())
+ .setNotification(Notification.newBuilder()
+ .addPlatformNotification(AndroidNotification.newBuilder()
+ .setAlert(alert)
+ .setSmallIconUri(mediaId)
+ .setLargeIcon(mediaId)
+ .setBigPicPath(mediaId)
+ .setInbox(mediaId)
+ .setBigText(mediaId)
+ .setTitle("title")
+ .build()).build())
+ .build();
+ PushResult result = _client.sendPush(payload);
+ assertTrue(result.isResultOK());
+ }
+
// ------------------ ios
-
+
@Test
public void sendNotification_ios_badge() throws Exception {
PushPayload payload = PushPayload.newBuilder()