mirror of
https://github.com/pierre42100/ComunicAndroid
synced 2024-11-23 22:09:30 +00:00
Can post files without having to base64 them.
This commit is contained in:
parent
4c79e5de9f
commit
d68755f4fe
@ -5,6 +5,9 @@ import android.net.ConnectivityManager;
|
|||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
|
|
||||||
import org.communiquons.android.comunic.client.BuildConfig;
|
import org.communiquons.android.comunic.client.BuildConfig;
|
||||||
|
import org.communiquons.android.comunic.client.data.models.APIFileRequest;
|
||||||
|
import org.communiquons.android.comunic.client.data.models.APIPostData;
|
||||||
|
import org.communiquons.android.comunic.client.data.models.APIPostFile;
|
||||||
import org.communiquons.android.comunic.client.data.models.APIRequest;
|
import org.communiquons.android.comunic.client.data.models.APIRequest;
|
||||||
import org.communiquons.android.comunic.client.data.models.APIResponse;
|
import org.communiquons.android.comunic.client.data.models.APIResponse;
|
||||||
|
|
||||||
@ -16,8 +19,11 @@ import java.io.InputStream;
|
|||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.PrintWriter;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -115,6 +121,126 @@ public class APIRequestHelper {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute an API request over the server
|
||||||
|
*
|
||||||
|
* Note : this methods is based on a StackOverflow answer:
|
||||||
|
* https://stackoverflow.com/a/33149413/3781411
|
||||||
|
*
|
||||||
|
* @param req Information about the request
|
||||||
|
* @return The response of the server
|
||||||
|
* @throws Exception In case of failure during the connection with the API
|
||||||
|
*/
|
||||||
|
public APIResponse execPostFile(APIFileRequest req) throws Exception {
|
||||||
|
|
||||||
|
//Add API and login tokens to the request
|
||||||
|
addAPItokens(req);
|
||||||
|
addLoginTokens(req);
|
||||||
|
|
||||||
|
//Prepare response
|
||||||
|
APIResponse response = new APIResponse();
|
||||||
|
HttpURLConnection conn = null;
|
||||||
|
OutputStream out;
|
||||||
|
PrintWriter writer;
|
||||||
|
|
||||||
|
//Create unique boundary
|
||||||
|
String boundary = "===" + System.currentTimeMillis() + "===";
|
||||||
|
String LINE_FEED = "\r\n";
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
//Initialize connection
|
||||||
|
URL url = new URL(BuildConfig.api_url + req.getRequest_uri());
|
||||||
|
conn = (HttpURLConnection) url.openConnection();
|
||||||
|
conn.setUseCaches(false);
|
||||||
|
conn.setDoInput(true);
|
||||||
|
conn.setDoOutput(true);
|
||||||
|
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
|
||||||
|
|
||||||
|
//Get output stream
|
||||||
|
out = conn.getOutputStream();
|
||||||
|
writer = new PrintWriter(new OutputStreamWriter(out, "UTF-8"));
|
||||||
|
|
||||||
|
//Append values
|
||||||
|
for(APIPostData value : req.getParameters()){
|
||||||
|
|
||||||
|
writer.append("--" + boundary).append(LINE_FEED);
|
||||||
|
writer.append("Content-Disposition: form-data; name=\"" + value.getEncodedKeyName() + "\"")
|
||||||
|
.append(LINE_FEED);
|
||||||
|
writer.append("Content-Type: form-data; charset=UTF-8").append(
|
||||||
|
LINE_FEED);
|
||||||
|
writer.append(LINE_FEED);
|
||||||
|
writer.append(value.getKey_value()).append(LINE_FEED);
|
||||||
|
writer.flush();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//Append files
|
||||||
|
for(APIPostFile file : req.getFiles()){
|
||||||
|
|
||||||
|
String fileName = file.getFileName();
|
||||||
|
writer.append("--" + boundary).append(LINE_FEED);
|
||||||
|
writer.append(
|
||||||
|
"Content-Disposition: form-data; name=\"" + file.getFieldName()
|
||||||
|
+ "\"; filename=\"" + fileName + "\"")
|
||||||
|
.append(LINE_FEED);
|
||||||
|
writer.append(
|
||||||
|
"Content-Type: "
|
||||||
|
+ URLConnection.guessContentTypeFromName(fileName))
|
||||||
|
.append(LINE_FEED);
|
||||||
|
writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
|
||||||
|
writer.append(LINE_FEED);
|
||||||
|
writer.flush();
|
||||||
|
|
||||||
|
out.write(file.getByteArray());
|
||||||
|
out.flush();
|
||||||
|
|
||||||
|
writer.append(LINE_FEED);
|
||||||
|
writer.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Finish request and get response
|
||||||
|
writer.append(LINE_FEED).flush();
|
||||||
|
writer.append("--" + boundary + "--").append(LINE_FEED);
|
||||||
|
writer.close();
|
||||||
|
|
||||||
|
StringBuilder responseBuffer = new StringBuilder();
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(
|
||||||
|
conn.getInputStream()));
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
responseBuffer.append(line);
|
||||||
|
}
|
||||||
|
reader.close();
|
||||||
|
conn.disconnect();
|
||||||
|
|
||||||
|
//Return the response
|
||||||
|
response.setResponse_code(conn.getResponseCode());
|
||||||
|
response.setResponse(responseBuffer.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
//Malformed URL Exceptions must be fixed by dev
|
||||||
|
catch (MalformedURLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException("MalformedURLException should never occur...");
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
response.setResponse_code(0);
|
||||||
|
|
||||||
|
if(req.isTryContinueOnError() && conn != null){
|
||||||
|
response.setResponse_code(conn.getResponseCode());
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Throw an exception
|
||||||
|
throw new Exception("Could not connect to the server");
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
// Reads an InputStream and converts it to a String.
|
// Reads an InputStream and converts it to a String.
|
||||||
private String readIt(InputStream stream) throws IOException {
|
private String readIt(InputStream stream) throws IOException {
|
||||||
|
|
||||||
@ -133,7 +259,7 @@ public class APIRequestHelper {
|
|||||||
/**
|
/**
|
||||||
* Add the API client tokens to API request object
|
* Add the API client tokens to API request object
|
||||||
*
|
*
|
||||||
* @param params The request parametres to update
|
* @param params The request parameters to update
|
||||||
*/
|
*/
|
||||||
private void addAPItokens(APIRequest params){
|
private void addAPItokens(APIRequest params){
|
||||||
params.addString("serviceName", BuildConfig.api_service_name);
|
params.addString("serviceName", BuildConfig.api_service_name);
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
package org.communiquons.android.comunic.client.data.helpers;
|
package org.communiquons.android.comunic.client.data.helpers;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.communiquons.android.comunic.client.data.models.APIFileRequest;
|
||||||
|
import org.communiquons.android.comunic.client.data.models.APIPostFile;
|
||||||
import org.communiquons.android.comunic.client.data.models.APIRequest;
|
import org.communiquons.android.comunic.client.data.models.APIRequest;
|
||||||
import org.communiquons.android.comunic.client.data.models.APIResponse;
|
import org.communiquons.android.comunic.client.data.models.APIResponse;
|
||||||
import org.communiquons.android.comunic.client.data.models.ConversationMessage;
|
import org.communiquons.android.comunic.client.data.models.ConversationMessage;
|
||||||
@ -82,23 +86,36 @@ public class ConversationMessagesHelper {
|
|||||||
*
|
*
|
||||||
* @param convID Target conversation ID
|
* @param convID Target conversation ID
|
||||||
* @param message The message to send
|
* @param message The message to send
|
||||||
* @param image Base64 encoded image to include with the message (can be null)
|
* @param image Image to include with the request, as bitmap (can be null)
|
||||||
* @return true in case of success / false else
|
* @return true in case of success / false else
|
||||||
*/
|
*/
|
||||||
public boolean sendMessage(int convID, String message, @Nullable String image){
|
public boolean sendMessage(int convID, String message, @Nullable Bitmap image){
|
||||||
|
|
||||||
//Make an API request
|
//Make an API request
|
||||||
APIRequest params = new APIRequest(mContext,
|
APIFileRequest params = new APIFileRequest(mContext,
|
||||||
"conversations/sendMessage");
|
"conversations/sendMessage");
|
||||||
params.addString("conversationID", ""+convID);
|
params.addString("conversationID", ""+convID);
|
||||||
params.addString("message", message);
|
params.addString("message", message);
|
||||||
|
|
||||||
//Include image (if any)
|
//Include image (if any)
|
||||||
if(image != null)
|
if(image != null) {
|
||||||
params.addString("image", "data:image/png;base64," + image);
|
APIPostFile file = new APIPostFile();
|
||||||
|
file.setFieldName("image");
|
||||||
|
file.setFileName("conversationImage.png");
|
||||||
|
file.setBitmap(image);
|
||||||
|
params.addFile(file);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new APIRequestHelper().exec(params);
|
|
||||||
|
if(image != null){
|
||||||
|
//Perform a POST request
|
||||||
|
new APIRequestHelper().execPostFile(params);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
//Perform normal request
|
||||||
|
new APIRequestHelper().exec(params);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e){
|
} catch (Exception e){
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -0,0 +1,51 @@
|
|||||||
|
package org.communiquons.android.comunic.client.data.models;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class handles information about the request that includes files to the server
|
||||||
|
*
|
||||||
|
* @author Pierre HUBERT
|
||||||
|
* Created by pierre on 4/21/18.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class APIFileRequest extends APIRequest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The list of post files
|
||||||
|
*/
|
||||||
|
private ArrayList<APIPostFile> files;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class constructor
|
||||||
|
*
|
||||||
|
* @param context The context of the request
|
||||||
|
* @param uri The request URI on the server
|
||||||
|
*/
|
||||||
|
public APIFileRequest(Context context, String uri) {
|
||||||
|
super(context, uri);
|
||||||
|
|
||||||
|
//Create files list
|
||||||
|
files = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a file to the request
|
||||||
|
*
|
||||||
|
* @param file The file to add
|
||||||
|
*/
|
||||||
|
public void addFile(APIPostFile file){
|
||||||
|
files.add(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of files
|
||||||
|
*
|
||||||
|
* @return The list of the files to include into the request
|
||||||
|
*/
|
||||||
|
public ArrayList<APIPostFile> getFiles() {
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,7 @@ import java.net.URLEncoder;
|
|||||||
* Created by pierre on 10/31/17.
|
* Created by pierre on 10/31/17.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class APIPostData {
|
public class APIPostData {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the key
|
* The name of the key
|
||||||
@ -32,6 +32,52 @@ class APIPostData {
|
|||||||
key_value = value;
|
key_value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name of the key
|
||||||
|
*
|
||||||
|
* @return The name of key
|
||||||
|
*/
|
||||||
|
public String getKey_name() {
|
||||||
|
return key_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value associated with the ky
|
||||||
|
*
|
||||||
|
* @return The value of the key
|
||||||
|
*/
|
||||||
|
public String getKey_value() {
|
||||||
|
return key_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the key name, as an encoded string
|
||||||
|
*
|
||||||
|
* @return The encoded key name
|
||||||
|
*/
|
||||||
|
public String getEncodedKeyName(){
|
||||||
|
try {
|
||||||
|
return URLEncoder.encode(getKey_name(), "UTF-8");
|
||||||
|
} catch (java.io.UnsupportedEncodingException e){
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException("Unsupported encoding : UTF-8 !", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the key value, as an encoded string
|
||||||
|
*
|
||||||
|
* @return The encoded key value
|
||||||
|
*/
|
||||||
|
public String getEncodedKeyValue(){
|
||||||
|
try {
|
||||||
|
return URLEncoder.encode(getKey_value(), "UTF-8");
|
||||||
|
} catch (java.io.UnsupportedEncodingException e){
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException("Unsupported encoding : UTF-8 !", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the the name and the value of the key in an encoded form
|
* Get the the name and the value of the key in an encoded form
|
||||||
*
|
*
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
package org.communiquons.android.comunic.client.data.models;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Single file information included in a request to the API
|
||||||
|
*
|
||||||
|
* @author Pierre HUBERT
|
||||||
|
* Created by pierre on 4/21/18.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class APIPostFile {
|
||||||
|
|
||||||
|
//Private fields
|
||||||
|
private String fieldName;
|
||||||
|
private String fileName;
|
||||||
|
private byte[] byteArray;
|
||||||
|
|
||||||
|
|
||||||
|
//Set and get field name
|
||||||
|
public void setFieldName(String fieldName) {
|
||||||
|
this.fieldName = fieldName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFieldName() {
|
||||||
|
return fieldName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Set and get file name
|
||||||
|
public void setFileName(String fileName) {
|
||||||
|
this.fileName = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set and get byte array
|
||||||
|
public void setByteArray(byte[] byteArray) {
|
||||||
|
this.byteArray = byteArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getByteArray() {
|
||||||
|
return byteArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a bitmap as the file
|
||||||
|
*
|
||||||
|
* @param bmp Bitmap to set
|
||||||
|
*/
|
||||||
|
public void setBitmap(@NonNull Bitmap bmp){
|
||||||
|
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||||
|
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
|
||||||
|
setByteArray(stream.toByteArray());
|
||||||
|
}
|
||||||
|
}
|
@ -112,6 +112,15 @@ public class APIRequest {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of parameters
|
||||||
|
*
|
||||||
|
* @return The list of parameters
|
||||||
|
*/
|
||||||
|
public ArrayList<APIPostData> getParameters() {
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the context of the request
|
* Get the context of the request
|
||||||
*
|
*
|
||||||
|
@ -535,14 +535,8 @@ public class ConversationFragment extends Fragment
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Boolean doInBackground(Void... params) {
|
protected Boolean doInBackground(Void... params) {
|
||||||
String message_image = null;
|
return convMessHelper.sendMessage(conversation_id,
|
||||||
|
message_content, new_message_bitmap);
|
||||||
//Reduce Bitmap and convert it to a base64-encoded string
|
|
||||||
if(new_message_bitmap != null)
|
|
||||||
message_image = BitmapUtils.bitmapToBase64(
|
|
||||||
BitmapUtils.reduceBitmap(new_message_bitmap, 1199, 1199));
|
|
||||||
|
|
||||||
return convMessHelper.sendMessage(conversation_id, message_content, message_image);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user