Browse Source

allow uploading any type of image

Tested all formats (except MNG) from https://www.w3.org/People/mimasa/test/imgformat/
legacy
Ammar Githam 4 years ago
parent
commit
4a73aa1179
  1. 50
      app/src/main/java/awais/instagrabber/asyncs/ImageUploader.java
  2. 19
      app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java
  3. 42
      app/src/main/java/awais/instagrabber/models/ImageUploadOptions.java

50
app/src/main/java/awais/instagrabber/asyncs/ImageUploader.java

@ -1,11 +1,17 @@
package awais.instagrabber.asyncs; package awais.instagrabber.asyncs;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.util.Log; import android.util.Log;
import org.json.JSONObject; import org.json.JSONObject;
import java.io.BufferedOutputStream;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
@ -35,13 +41,24 @@ public class ImageUploader extends AsyncTask<ImageUploadOptions, Void, ImageUplo
OutputStream out = null; OutputStream out = null;
InputStream inputStream = null; InputStream inputStream = null;
BufferedReader r = null; BufferedReader r = null;
ByteArrayOutputStream baos = null;
try { try {
final ImageUploadOptions options = imageUploadOptions[0]; final ImageUploadOptions options = imageUploadOptions[0];
final File file = options.getFile();
inputStream = new FileInputStream(file);
final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
baos = new ByteArrayOutputStream();
final boolean compressResult = bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
if (!compressResult) {
Log.e(TAG, "Compress result was false!");
return null;
}
final byte[] bytes = baos.toByteArray();
final String contentLength = String.valueOf(bytes.length);
final Map<String, String> headers = new HashMap<>(); final Map<String, String> headers = new HashMap<>();
final String uploadId = String.valueOf(new Date().getTime()); final String uploadId = String.valueOf(new Date().getTime());
final long random = LOWER + new Random().nextLong() * (UPPER - LOWER + 1); final long random = LOWER + new Random().nextLong() * (UPPER - LOWER + 1);
final String name = String.format("%s_0_%s", uploadId, random); final String name = String.format("%s_0_%s", uploadId, random);
final String contentLength = String.valueOf(options.getContentLength());
final String waterfallId = options.getWaterfallId() != null ? options.getWaterfallId() : UUID.randomUUID().toString(); final String waterfallId = options.getWaterfallId() != null ? options.getWaterfallId() : UUID.randomUUID().toString();
headers.put("X-Entity-Type", "image/jpeg"); headers.put("X-Entity-Type", "image/jpeg");
headers.put("Offset", "0"); headers.put("Offset", "0");
@ -58,20 +75,15 @@ public class ImageUploader extends AsyncTask<ImageUploadOptions, Void, ImageUplo
connection.setUseCaches(false); connection.setUseCaches(false);
connection.setDoOutput(true); connection.setDoOutput(true);
Utils.setConnectionHeaders(connection, headers); Utils.setConnectionHeaders(connection, headers);
out = connection.getOutputStream();
byte[] buffer = new byte[1024];
int n;
inputStream = options.getInputStream();
while (-1 != (n = inputStream.read(buffer))) {
out.write(buffer, 0, n);
}
out = new BufferedOutputStream(connection.getOutputStream());
out.write(bytes);
out.flush(); out.flush();
final int responseCode = connection.getResponseCode(); final int responseCode = connection.getResponseCode();
Log.d(TAG, "response: " + responseCode); Log.d(TAG, "response: " + responseCode);
if (responseCode != HttpURLConnection.HTTP_OK) {
return new ImageUploadResponse(responseCode, null);
}
r = new BufferedReader(new InputStreamReader(connection.getInputStream()));
final String responseCodeString = String.valueOf(responseCode);
final InputStream responseInputStream = responseCodeString.startsWith("4") || responseCodeString.startsWith("5")
? connection.getErrorStream() : connection.getInputStream();
r = new BufferedReader(new InputStreamReader(responseInputStream));
final StringBuilder builder = new StringBuilder(); final StringBuilder builder = new StringBuilder();
for (String line = r.readLine(); line != null; line = r.readLine()) { for (String line = r.readLine(); line != null; line = r.readLine()) {
if (builder.length() != 0) { if (builder.length() != 0) {
@ -86,24 +98,26 @@ public class ImageUploader extends AsyncTask<ImageUploadOptions, Void, ImageUplo
if (r != null) { if (r != null) {
try { try {
r.close(); r.close();
} catch (IOException ignored) {
}
} catch (IOException ignored) {}
} }
if (inputStream != null) { if (inputStream != null) {
try { try {
inputStream.close(); inputStream.close();
} catch (IOException ignored) {
}
} catch (IOException ignored) {}
} }
if (out != null) { if (out != null) {
try { try {
out.close(); out.close();
} catch (IOException ignored) {
}
} catch (IOException ignored) {}
} }
if (connection != null) { if (connection != null) {
connection.disconnect(); connection.disconnect();
} }
if (baos != null) {
try {
baos.close();
} catch (IOException ignored) {}
}
} }
return null; return null;
} }

19
app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java

@ -6,7 +6,6 @@ import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.ParcelFileDescriptor;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@ -27,8 +26,7 @@ import androidx.recyclerview.widget.RecyclerView;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.File;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.util.ArrayList; import java.util.ArrayList;
@ -282,14 +280,12 @@ public class DirectMessageThreadFragment extends Fragment {
} }
private void sendImage(final Uri imageUri) { private void sendImage(final Uri imageUri) {
try {
final ParcelFileDescriptor fileDescriptor = requireContext().getContentResolver().openFileDescriptor(imageUri, "r");
if (fileDescriptor == null) {
Log.e(TAG, "fileDescriptor is null!");
final String path = imageUri.getPath();
if (path == null) {
Log.e(TAG, "uri path is null!");
return; return;
} }
final long contentLength = fileDescriptor.getStatSize();
final InputStream inputStream = requireContext().getContentResolver().openInputStream(imageUri);
final File file = new File(path);
// Upload Image // Upload Image
final ImageUploader imageUploader = new ImageUploader(); final ImageUploader imageUploader = new ImageUploader();
imageUploader.setOnTaskCompleteListener(response -> { imageUploader.setOnTaskCompleteListener(response -> {
@ -311,11 +307,8 @@ public class DirectMessageThreadFragment extends Fragment {
Log.e(TAG, "Error parsing json response", e); Log.e(TAG, "Error parsing json response", e);
} }
}); });
final ImageUploadOptions options = ImageUploadOptions.builder(inputStream, contentLength).build();
final ImageUploadOptions options = ImageUploadOptions.builder(file).build();
imageUploader.execute(options); imageUploader.execute(options);
} catch (FileNotFoundException e) {
Log.e(TAG, "Error opening InputStream", e);
}
} }
private void broadcast(final DirectThreadBroadcaster.BroadcastOptions broadcastOptions, final DirectThreadBroadcaster.OnBroadcastCompleteListener listener) { private void broadcast(final DirectThreadBroadcaster.BroadcastOptions broadcastOptions, final DirectThreadBroadcaster.OnBroadcastCompleteListener listener) {

42
app/src/main/java/awais/instagrabber/models/ImageUploadOptions.java

@ -1,31 +1,23 @@
package awais.instagrabber.models; package awais.instagrabber.models;
import java.io.InputStream;
import java.io.File;
public class ImageUploadOptions { public class ImageUploadOptions {
private InputStream inputStream;
private long contentLength;
private final File file;
private boolean isSidecar; private boolean isSidecar;
private String waterfallId; private String waterfallId;
public static class Builder { public static class Builder {
private InputStream inputStream;
private long contentLength;
private File file;
private boolean isSidecar; private boolean isSidecar;
private String waterfallId; private String waterfallId;
public Builder(final InputStream inputStream, final long contentLength) {
this.inputStream = inputStream;
this.contentLength = contentLength;
public Builder(final File file) {
this.file = file;
} }
public Builder setInputStream(final InputStream inputStream) {
this.inputStream = inputStream;
return this;
}
public Builder setContentLength(final long contentLength) {
this.contentLength = contentLength;
public Builder setFile(final File file) {
this.file = file;
return this; return this;
} }
@ -40,30 +32,24 @@ public class ImageUploadOptions {
} }
public ImageUploadOptions build() { public ImageUploadOptions build() {
return new ImageUploadOptions(inputStream, contentLength, isSidecar, waterfallId);
return new ImageUploadOptions(file, isSidecar, waterfallId);
} }
} }
public static Builder builder(final InputStream inputStream, final long contentLength) {
return new Builder(inputStream, contentLength);
public static Builder builder(final File file) {
return new Builder(file);
} }
private ImageUploadOptions(final InputStream inputStream,
final long contentLength,
private ImageUploadOptions(final File file,
final boolean isSidecar, final boolean isSidecar,
final String waterfallId) { final String waterfallId) {
this.inputStream = inputStream;
this.contentLength = contentLength;
this.file = file;
this.isSidecar = isSidecar; this.isSidecar = isSidecar;
this.waterfallId = waterfallId; this.waterfallId = waterfallId;
} }
public InputStream getInputStream() {
return inputStream;
}
public long getContentLength() {
return contentLength;
public File getFile() {
return file;
} }
public boolean isSidecar() { public boolean isSidecar() {

Loading…
Cancel
Save